Is it possible to intercept unencrypted HTTPS request body of local programs?
Asked Answered
C

4

9

Is it possible to write a single general EBPF program that can read the unencrypted HTTPS request and response bodies of all user space programs?

As I understand it, EBPF works with packets for layers 2, 3 and 4 of the network. HTTPS payloads are encrypted inside these packets, so EBPF can read the packet meta data but not the payloads that make up the HTTPS request/response?

Is the only way to do this to add logging to the user space programs?

Co answered 2/1, 2020 at 21:40 Comment(1)
SSL/TLS payloads, such as those used by HTTPS, are encrypted in user space before they hit the network. So yes, you would have to add logging of the unencrypted data inside the programs themselvesBartonbartosch
W
6

As you mention and as others confirmed, the data is encrypted in user space before the packets are passed to the kernel, so you cannot examine the unencrypted data when working on packets with eBPF (or indeed, you would need to do some MitM hacking).

But bear in mind that eBPF can also be used for tracing, be it kernel or user space programs. In particular, the BCC framework has a very interesting sslsniff example where the eBPF program is hooked (through user probes) directly into the SSL/TLS libraries (at runtime, no recompilation needed for the libs) in order to intercept the unencrypted data just before it gets encrypted. You might want to have a look at the sample output that comes with it, maybe this tool could help solve your problem.

Weasner answered 3/1, 2020 at 10:57 Comment(0)
R
6

As @Qeole and @Maxim explained, you will have to resort to man-in-the-middle if the payloads are encrypted in userspace. There's one other case though: the payloads may be encrypted in the kernel with kTLS.

If the userspace process relies on kTLS, then the handshake is still performed in userspace, but subsequent messages will be encrypted in the kernel. In that case, you can attach BPF programs of type BPF_PROG_TYPE_SK_MSG at the TLS ULP layer in the kernel.

You can find an example of such a setup in the kernel tests, namely test_sockmap. In that example, the TLS connection is setup in userspace in sockmap_init_ktls(). The corresponding BPF programs are in test_sockmap_kern.h.

kTLS is relatively new, so it's clearly a corner case at the time I'm writing this answer. It's likely to become more common however, as userspace libraries start to transparently use it. OpenSSL, for example, merged support for kTLS more than a year ago.

Rita answered 5/1, 2020 at 10:21 Comment(0)
S
1

There is a way to make generic solution which reads content of encrypted traffic (SSL / TLS ).

old-school MiTM setup with sslsplit will do all dirty work for you.

You have full control over DUT (device under test) so you can always add fake root CA certificate into your system for sslsplit to generate fake certificates on the fly.

This is indeed generic solution and allows to intercept traffic for DUT of arbitrary platform - Windows, iOS, MacOS, Linux, Android.

I used small VPS in the cloud to make such rougue VPN server with MiTM capabilities ( i.e. with sslsplit running on it).

To intercept (and decrypt) DUT's traffic you just need to activate VPN connection to specific MiTM server.

Of course you can use virtual machine in your office/home instead of cloud based VPS. I picked up cloud VPS due to flexibility - i.e. I can record Android's traffic on the go while I'm outside of the lab's environment.

There are many tutorials about how to configure VPN servers and sslsplit. Most likely there are ready-to-use docker or vagrant images to setup such interception servers. here is an example: https://github.com/praetorian-code/mitm-vm

Here is copy-paste for relevant pieces from my current server:

ufw allow 10443
ufw allow 10080

iptables -t nat -A PREROUTING -i tun0 \
 -p tcp --dport 443 -j REDIRECT --to-port 10443
iptables -t nat -A PREROUTING -i tun0 \
 -p tcp --dport 80 -j REDIRECT --to-port 10080
sslsplit -D \
  -l /root/mitm/logs/connections`date +%Y-%m-%d_%H-%M`.log \
  -S /root/mitm/recorded/ \
  -L /root/mitm/logs/log`date +%Y-%m-%d_%H-%M`.bin \
  -F /root/mitm/recorded/%T_%d.raw \
  -k /root/mitm/ca.key \
  -c /root/mitm/ca.crt \
   https 0.0.0.0 10443 \
    http 0.0.0.0 10080 \
   > /root/mitm/logs/`date +%Y-%m-%d_%H-%M`.log2 2>&1

Happy New Year and Happy Hacking! :-)

Shopwindow answered 3/1, 2020 at 4:6 Comment(0)
H
1

I've done lots of plaintext tracing before using user-space dynamic instrumentation (uprobes on Linux) by picking the functions before encryption. If the encryption is kernel space (as @pchaigno said) then it gets easier as you have kernel space as well to trace (kprobes/etc.)

I want raise an important point: This kind of tracing can have passers by thinking the wrong thing, that there's some eBPF vulnerability or that eBPF is bad for security. This is bad for the eBPF community in general (eBPF is actually good for security because of capabilities it enables), so please use caution when discussing this type of tracing in public. I'd make these two points:

  • eBPF requires root access, so any type of plaintext tracing is coming after the system has already been owned.
  • Plaintext encryption tracing is typically already possible using widely available tools like strace(1) (for SSH) and custom library interposers, so eBPF is not making this type of attack possible in the first place.
Hillis answered 21/8, 2022 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.