Stream Extraction from Scriptland

Hello List,

I'd first like to point out something I never knew existed.
bro/aux/bro-aux/devel-tools/extract-conn-by-uid will build a BPF from
a UID in a conn.log file and extract that stream from a pcap. Nifty.
That got me thinking if it would be possible to call
extract-conn-by-uid from scriptland with the exec framework. I wrote a
few PoC scripts but things became rather complicated when I couldn't
figure out when the conn.log file is available on disk from
scriptland. I'm curious if anyone has done something similar to this
before.

I then started playing around with the set_record_packets bif, but I
could not seem to get that function to do anything with packets that
weren't TCP data packets. The documentation around this function says
nothing specifically about TCP and only references 'connections',
which in Bro parlance includes TCP, UDP, and ICMP. I've included a
sample trace file, bro script, and some notes that resemble a bug
report around the set_record_packets functionality.

I supposed my root question is this: is there a way to use Bro
scripting to identify a connection of interest and have it written to
disk (either with the exec framework or with set_record_packet)
instead of including dumb BPFs with Bro's invocation?
Thanks all,

-AK

notes.txt (490 Bytes)

connection_extractor.bro (807 Bytes)

sample.pcap (22.2 KB)

That's one of the features of the TimeMachine framework that I haven't finished yet. :slight_smile:

You can use the set_record_packets BiF as you found too, but that requires that you are running Bro with the -w flag to write packets to disk. Ultimately I think that something like the TimeMachine approach is the most scaleable because you could even do your bulk packet recording on a separate device and just have Bro communicate to it when you want to extract some packets (even going back in time).

  .Seth

I agree with your point on scalability and look forward to the TimeMachine framework.

It does seem that set_record_packets only works on TCP data packets, though. I’m not sure if thats an issue with the function or with the documentation about the function.

The script I included sets all new connection’s to false with set_record_packets, then sets connections to true from the connection_state_remove event if they contain DNS. The notes.txt file shows the bro command I ran (including the -w option) against the sample.pcap file, included previously, to produce a new trace file with unexpected contents.

Is this a bug in the function or am I reading the doc incorrectly? Thanks all (Seth).

-AK

Actually, I'm surprised that it works with TCP at all. The problem
with set_record_packets() is that at the time when an event handler
calls it, the packet may already be gone at Bro's lower levels
(handlers are executed asynchronously and Bro doesn't buffer any
packets).

Have you tried calling set_record_packets(c$id, T) in new_connection()
for UDP traffic? (Understood that that isn't what you want, just to
see if it works).

Regarding TM integration, the old 1.5 time machine script may actually
still work, it has the functionality.

Robin

Hi Robin,

The same results occur (UDP, ICMP and TCP signalling packets are
present in the interesting.pcap file) when running:
bro -Cr sample.pcap new_test.bro -w interesting.pcap

Where sample.pcap is the previously included sample.pcap trace file
and new_test.bro includes the following code:
event new_connection(c: connection)
{
        if ("DNS" in c$service) # this is surprisingly set before this
event is handled, so we can use it
        {
                set_record_packets(c$id, T);
        } else {
                set_record_packets(c$id, F);
        }
}

To me, it seems the function only works with TCP connections.

-AK