BCC: bpf_probe_read read function arguments


Adrián López Tejedor <adrianlzt@...>
 

Hi,

I'm learning how to use bcc tools and to have a goal I was trying to read HTTP data before it gets encrypted, so, locally, I can read https traffic (actually, anything using openssl).

I have modified some examples found on the web and done this: https://gist.github.com/adrianlzt/260253376bbcd75265cf47332eda496e

It works well for outgoing data, showing the request, but incoming data just shows the first line:


% sudo python sniff_openssl.py
        TIME(s)    COMM             PID   
WRITE: 0.000000000        curl             27088  4
GET / HTTP/1.1
Host: google.es
User-Agent: curl/7.50.1
Accept: */*


READ: 0.041576303        curl             27088  4
C=US; O=Google Inc; CN=Google Internet Authority G2


I was trying to uderstant that happens behind bpf_probe_read function, but it goes deep in the kernel.
Any idea?

Thanks!
Adrian

P.S.: my real goal is try to decipher http2 requests, but I think is easy to begin with http1.1/SSL first.


Mark Drayton <mbd@...>
 

My guess here is that the probe runs before SSL_read does anything, meaning the buffer you're trying to read hasn't actually been written to yet. This isn't the case for SSL_write as the buffer contains the data you want before the probe runs. I'm not sure why the read buffer would contain a line of output prior to calling SSL_read, though. 

Maybe try converting the read probe to a uretprobe so you can access the buffer after libssl has written to it?


_____________________________
From: Adrián López Tejedor via iovisor-dev <iovisor-dev@...>
Sent: Friday, August 12, 2016 3:05 pm
Subject: [iovisor-dev] BCC: bpf_probe_read read function arguments
To: <iovisor-dev@...>


Hi,

I'm learning how to use bcc tools and to have a goal I was trying to read HTTP data before it gets encrypted, so, locally, I can read https traffic (actually, anything using openssl).

I have modified some examples found on the web and done this: https://gist.github.com/adrianlzt/260253376bbcd75265cf47332eda496e

It works well for outgoing data, showing the request, but incoming data just shows the first line:


% sudo python sniff_openssl.py
        TIME(s)    COMM             PID   
WRITE: 0.000000000        curl             27088  4
GET / HTTP/1.1
User-Agent: curl/7.50.1
Accept: */*


READ: 0.041576303        curl             27088  4
C=US; O=Google Inc; CN=Google Internet Authority G2


I was trying to uderstant that happens behind bpf_probe_read function, but it goes deep in the kernel.
Any idea?

Thanks!
Adrian

P.S.: my real goal is try to decipher http2 requests, but I think is easy to begin with http1.1/SSL first.



Adrián López Tejedor <adrianlzt@...>
 

Thanks, I'll take a look.


El vie., 12 de agosto de 2016 21:06, Mark Drayton <mbd@...> escribió:
My guess here is that the probe runs before SSL_read does anything, meaning the buffer you're trying to read hasn't actually been written to yet. This isn't the case for SSL_write as the buffer contains the data you want before the probe runs. I'm not sure why the read buffer would contain a line of output prior to calling SSL_read, though. 

Maybe try converting the read probe to a uretprobe so you can access the buffer after libssl has written to it?


_____________________________
From: Adrián López Tejedor via iovisor-dev <iovisor-dev@...>
Sent: Friday, August 12, 2016 3:05 pm
Subject: [iovisor-dev] BCC: bpf_probe_read read function arguments
To: <iovisor-dev@...>



Hi,

I'm learning how to use bcc tools and to have a goal I was trying to read HTTP data before it gets encrypted, so, locally, I can read https traffic (actually, anything using openssl).

I have modified some examples found on the web and done this: https://gist.github.com/adrianlzt/260253376bbcd75265cf47332eda496e

It works well for outgoing data, showing the request, but incoming data just shows the first line:


% sudo python sniff_openssl.py
        TIME(s)    COMM             PID   
WRITE: 0.000000000        curl             27088  4
GET / HTTP/1.1
User-Agent: curl/7.50.1
Accept: */*


READ: 0.041576303        curl             27088  4
C=US; O=Google Inc; CN=Google Internet Authority G2


I was trying to uderstant that happens behind bpf_probe_read function, but it goes deep in the kernel.
Any idea?

Thanks!
Adrian

P.S.: my real goal is try to decipher http2 requests, but I think is easy to begin with http1.1/SSL first.



Mark Drayton <mbd@...>
 

Here’s a version that works:

 

https://gist.github.com/markdrayton/d077459b7ed23ce25bb3eff2d5e220ba

 

It looks like SSL_read’s arguments aren’t available in a return probe so you need to stash the buffer address in a map on the function entry and read it on its exit.

 

As you’ll see in my example, the amount of data captured is limited by the size of probe_SSL_data_t.v0, which in turn is limited by the (relatively small) size of the BPF stack. I’m not sure how best to handle this.

 

Unrelatedly: I suspect that GitHub is a better place to send questions like this than the –dev mailing list. I’m not sure whether others have a preference (Brenden/Brendan/Alexei, please shout if there is an established order here) but for me GitHub is preferable because it probably has a wider audience, is more discoverable, and has fancier formatting options. The mailing list seems primarily to be for higher level organizational issues.

 

From: Adrián López Tejedor <adrianlzt@...>
Date: Friday, August 12, 2016 at 8:38 PM
To: k a <mbd@...>, "iovisor-dev@..." <iovisor-dev@...>
Subject: Re: [iovisor-dev] BCC: bpf_probe_read read function arguments

 

Thanks, I'll take a look.

 

El vie., 12 de agosto de 2016 21:06, Mark Drayton <mbd@...> escribió:

My guess here is that the probe runs before SSL_read does anything, meaning the buffer you're trying to read hasn't actually been written to yet. This isn't the case for SSL_write as the buffer contains the data you want before the probe runs. I'm not sure why the read buffer would contain a line of output prior to calling SSL_read, though. 

 

Maybe try converting the read probe to a uretprobe so you can access the buffer after libssl has written to it?

 

 

_____________________________
From: Adrián López Tejedor via iovisor-dev <iovisor-dev@...>
Sent: Friday, August 12, 2016 3:05 pm
Subject: [iovisor-dev] BCC: bpf_probe_read read function arguments
To: <iovisor-dev@...>



Hi,

 

I'm learning how to use bcc tools and to have a goal I was trying to read HTTP data before it gets encrypted, so, locally, I can read https traffic (actually, anything using openssl).

 

I have modified some examples found on the web and done this: https://gist.github.com/adrianlzt/260253376bbcd75265cf47332eda496e

 

It works well for outgoing data, showing the request, but incoming data just shows the first line:

 

 

% sudo python sniff_openssl.py

        TIME(s)    COMM             PID   

WRITE: 0.000000000        curl             27088  4

GET / HTTP/1.1

Host: google.es

User-Agent: curl/7.50.1

Accept: */*

 

 

READ: 0.041576303        curl             27088  4

C=US; O=Google Inc; CN=Google Internet Authority G2

 

 

I was trying to uderstant that happens behind bpf_probe_read function, but it goes deep in the kernel.

Any idea?

 

Thanks!

Adrian

 

P.S.: my real goal is try to decipher http2 requests, but I think is easy to begin with http1.1/SSL first.

 


Brenden Blanco <bblanco@...>
 



On Fri, Aug 12, 2016 at 4:46 PM, Mark Drayton via iovisor-dev <iovisor-dev@...> wrote:

Here’s a version that works:

 

https://gist.github.com/markdrayton/d077459b7ed23ce25bb3eff2d5e220ba

 

It looks like SSL_read’s arguments aren’t available in a return probe so you need to stash the buffer address in a map on the function entry and read it on its exit.

 

As you’ll see in my example, the amount of data captured is limited by the size of probe_SSL_data_t.v0, which in turn is limited by the (relatively small) size of the BPF stack. I’m not sure how best to handle this.

 

Unrelatedly: I suspect that GitHub is a better place to send questions like this than the –dev mailing list.

+1 

I’m not sure whether others have a preference (Brenden/Brendan/Alexei, please shout if there is an established order here) but for me GitHub is preferable because it probably has a wider audience, is more discoverable, and has fancier formatting options. The mailing list seems primarily to be for higher level organizational issues.

 

From: Adrián López Tejedor <adrianlzt@...>
Date: Friday, August 12, 2016 at 8:38 PM
To: k a <mbd@...>, "iovisor-dev@..." <iovisor-dev@...>
Subject: Re: [iovisor-dev] BCC: bpf_probe_read read function arguments

 

Thanks, I'll take a look.

 

El vie., 12 de agosto de 2016 21:06, Mark Drayton <mbd@...> escribió:

My guess here is that the probe runs before SSL_read does anything, meaning the buffer you're trying to read hasn't actually been written to yet. This isn't the case for SSL_write as the buffer contains the data you want before the probe runs. I'm not sure why the read buffer would contain a line of output prior to calling SSL_read, though. 

 

Maybe try converting the read probe to a uretprobe so you can access the buffer after libssl has written to it?

 

 

_____________________________
From: Adrián López Tejedor via iovisor-dev <iovisor-dev@...>
Sent: Friday, August 12, 2016 3:05 pm
Subject: [iovisor-dev] BCC: bpf_probe_read read function arguments
To: <iovisor-dev@...>



Hi,

 

I'm learning how to use bcc tools and to have a goal I was trying to read HTTP data before it gets encrypted, so, locally, I can read https traffic (actually, anything using openssl).

 

I have modified some examples found on the web and done this: https://gist.github.com/adrianlzt/260253376bbcd75265cf47332eda496e

 

It works well for outgoing data, showing the request, but incoming data just shows the first line:

 

 

% sudo python sniff_openssl.py

        TIME(s)    COMM             PID   

WRITE: 0.000000000        curl             27088  4

GET / HTTP/1.1

Host: google.es

User-Agent: curl/7.50.1

Accept: */*

 

 

READ: 0.041576303        curl             27088  4

C=US; O=Google Inc; CN=Google Internet Authority G2

 

 

I was trying to uderstant that happens behind bpf_probe_read function, but it goes deep in the kernel.

Any idea?

 

Thanks!

Adrian

 

P.S.: my real goal is try to decipher http2 requests, but I think is easy to begin with http1.1/SSL first.

 


_______________________________________________
iovisor-dev mailing list
iovisor-dev@...
https://lists.iovisor.org/mailman/listinfo/iovisor-dev



Alexei Starovoitov
 

On Fri, Aug 12, 2016 at 4:50 PM, Brenden Blanco via iovisor-dev
<iovisor-dev@...> wrote:


On Fri, Aug 12, 2016 at 4:46 PM, Mark Drayton via iovisor-dev
<iovisor-dev@...> wrote:

Here’s a version that works:



https://gist.github.com/markdrayton/d077459b7ed23ce25bb3eff2d5e220ba



It looks like SSL_read’s arguments aren’t available in a return probe so
you need to stash the buffer address in a map on the function entry and read
it on its exit.



As you’ll see in my example, the amount of data captured is limited by the
size of probe_SSL_data_t.v0, which in turn is limited by the (relatively
small) size of the BPF stack. I’m not sure how best to handle this.



Unrelatedly: I suspect that GitHub is a better place to send questions
like this than the –dev mailing list.
+1
+2
I think that sniff_openssl.py you can wrap into PR into examples/
or even tools/.
Looks quite useful as it is.