Hi everyone,
[This mail has been sent to bro@ first, but I think I might have more
luck (and answers) here. Sorry for the inconvenience to those who have
already read it.]
For a network recon framework I am working on (https://ivre.rocks/ --
for those interested), I would like to log each "TCP server banner"
Bro sees.
I call "TCP server banner" the first chunk of data a server sends,
before the client has sent data (if the client sends data before the
server, I don't want to log anything).
Here is what I have done so far (`PassiveRecon` is my module's name):
export {
redef tcp_content_deliver_all_resp = T;
[...]
}
[...]
event tcp_contents(c: connection, is_orig: bool, seq: count, contents: string)
{
if (! is_orig && seq == 1 && c$orig$num_pkts == 2)
{
Log::write(PassiveRecon::LOG, [$ts=c$start_time,
$host=c$id$resp_h,
$srvport=c$id$resp_p,
$recon_type=TCP_SERVER_BANNER,
$value=contents]);
}
}
Basically, I consider we have a "TCP server banner" when `is_orig` is
false, when `seq` equals 1 and when we have seen exactly two packets
from the client (which should be a SYN and the first ACK).
This solution generally works **but** I sometimes log a data chunk
when I should not, particularly if I have missed part of the
traffic.
As an example, the following Scapy script creates a PCAP file that
would trick my script into logging a "TCP server banner" while the
client has actually sent some data (and we have missed an ACK packet,
left as a comment in the script):
wrpcap("test.cap", [
Ether() / IP(dst="1.2.3.4", src="5.6.7.8") /
TCP(dport=80, sport=5678, flags="S", ack=0, seq=555678),
Ether() / IP(src="1.2.3.4", dst="5.6.7.8") /
TCP(sport=80, dport=5678, flags="SA", seq=111234, ack=555679),
# Ether() / IP(dst="1.2.3.4", src="5.6.7.8") /
# TCP(dport=80, sport=5678, flags="A", ack=111235, seq=555679),
Ether() / IP(dst="1.2.3.4", src="5.6.7.8") /
TCP(dport=80, sport=5678, flags="PA", ack=111235, seq=555679) / "DATA",
Ether() / IP(src="1.2.3.4", dst="5.6.7.8") /
TCP(sport=80, dport=5678, flags="PA", seq=111235, ack=555683) / "DATA"
])
Is there a way to know that I have not missed any packet from the
client and/or a way to know that the client has not sent any data on
the connection (like an equivalent of the `seq` parameter, but for the
`ack`)?
Also, when `seq` equals 1, am I certain that I have not missed any
packet from the server?
One more question: is there a better, cleaner, etc. way to do what I'm
trying to do?
Thanks a lot,
Pierre