Skip to content

Instantly share code, notes, and snippets.

@grigorescu
Last active November 6, 2020 02:34
Show Gist options
  • Save grigorescu/ce7fcc61724bac34d544730bfb0620c8 to your computer and use it in GitHub Desktop.
Save grigorescu/ce7fcc61724bac34d544730bfb0620c8 to your computer and use it in GitHub Desktop.
breakpoint_to_pcap

breakpoint_to_pcap

Overview

Given an input PCAP and a location in a Bro script, this script will filter the PCAP into a new file, which contains only the connections that visited that script location. This script can help filter a large PCAP to narrow down problematic connections, such as protocol violations, weirds, etc.

Example

> tshark -r ~/pcaps/dns_multicast_bug.pcap| wc -l
499
> ./breakpoint_to_pcap.sh -r ~/pcaps/dns_multicast_bug.pcap -o test_output.pcap -b /Users/vladg/src/bro/scripts/base/protocols/dns/./main.bro:414 --                                   
Policy file debugging ON.
In bro_init() at /Users/vladg/src/bro/scripts/base/frameworks/sumstats/./main.bro:276
276    		hook register_observe_plugins();
Setting breakpoint on /Users/vladg/src/bro/scripts/base/protocols/dns/./main.bro:414:
Breakpoint 1 set at /Users/vladg/src/bro/scripts/base/protocols/dns/./main.bro:414
Breakpoint set at:
410
411    		for ( i in strs )
412    			{
413    			if ( i > 0 )
414    				txt_strings += " ";
415
416    			txt_strings += fmt("TXT %d %s", |strs[i]|, strs[i]);
417    			}
418
419    		hook DNS::do_reply(c, msg, ans, txt_strings);
Continuing.
(Bro [0]) (Bro [1]) (Bro [2]) (Bro [3]) (Bro [4])
> tshark -r test_output.pcap | wc -l                                                                                                
>  86
function generate_current_packet_filter(): bool
{
local output = open_for_append("tmp.out");
local pkt = get_current_packet_header();
if ( ! pkt?$ip )
{
if ( ! (pkt?$l2 && pkt$l2?$src && pkt$l2?$dst ) )
return F;
# All we have are MACs
print output, fmt("(eth.addr == %s && eth.addr == %s)", pkt$l2$src, pkt$l2$dst);
return F;
}
if ( ! (pkt?$tcp || pkt?$udp || pkt?$icmp) )
{
print output, fmt("(ip.host == %s && ip.host == %s)", cat(pkt$ip$src), cat(pkt$ip$dst));
return F;
}
if ( pkt?$tcp )
{
print output, fmt("(ip.host == %s && ip.host == %s && tcp.port == %d && tcp.port == %d)", cat(pkt$ip$src), cat(pkt$ip$dst), pkt$tcp$sport, pkt$tcp$dport);
return F;
}
if ( pkt?$udp )
{
print output, fmt("(ip.host == %s && ip.host == %s && udp.port == %d && udp.port == %d)", cat(pkt$ip$src), cat(pkt$ip$dst), pkt$udp$sport, pkt$udp$dport);
return F;
}
if ( pkt?$icmp )
{
print output, fmt("(icmp and ip.host == %s && ip.host == %s)", cat(pkt$ip$src), cat(pkt$ip$dst));
return F;
}
return F;
}
#!/bin/bash
if [[ $# -lt 7 ]]
then
echo "Usage: $0 -r input.pcap -o output.pcap -b breakpoint:location -- bro_args"
echo ""
echo "Example: $0 -r input.pcap -o output.pcap -b error1.bro:3 -- site/local.bro -e 'redef Site::local_networks += {10.0.0.0/8};'"
exit 1
fi
while [[ $# -gt 1 ]]
do
key="$1"
case $key in
-r|--readfile)
READFILE="$2"
shift # past argument
;;
-o|--outfile)
OUTFILE="$2"
shift # past argument
;;
-b|--breakpoint)
BREAKPOINT="$2"
shift # past argument
;;
--)
shift
ARGS=$@
shift $#
;;
esac
shift # past argument or value
done
rm tmp.out
cat <<EOF | bro -d -r $READFILE $ARGS breakpoint_to_pcap.bro
break $BREAKPOINT
cond 1 generate_current_packet_filter()
continue
EOF
FILTER=$(sort tmp.out| uniq | awk '{printf "%s or ",$0}' | sed -e 's/ or $//')
tshark -r $READFILE -w $OUTFILE -- $FILTER
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment