UDP flow anomaly

Hi all,

We are trying to write the simple script where it will check if the udp reply is 18 bytes and will return the src ip, dst ip as well as its bytes exchanges as illustrate as below

src ip ------> dst ip
src ip <----- dst ip (18 bytes)

It is pretty simple and works well to detect the udp probing, and we are happy with it but when we test it on one of the packet capture which supposingly having 3 udp packets with 18 bytes return, it only detects one of it but didn’t see the rest. And running through tcpdump, we figure this -

2007-09-13 07:32:30.298295 IP 192.168.0.185.63025 > 210.79.186.143.23074: UDP, length 22
2007-09-13 07:32:30.566344 IP 210.79.186.143.23074 > 192.168.0.185.63025: UDP, length 18
2007-09-13 07:32:34.790093 IP 192.168.0.185.63025 > 89.37.157.114.28763: UDP, length 41
2007-09-13 07:32:34.791688 IP 192.168.0.185.63025 > 200.83.176.80.49847: UDP, length 41
2007-09-13 07:32:34.809467 IP 192.168.0.185.63025 > 89.37.157.114.28763 : UDP, length 33
2007-09-13 07:32:34.809531 IP 192.168.0.185.63025 > 200.83.176.80.49847: UDP, length 33
2007-09-13 07:32:35.331256 IP 200.83.176.80.49847 > 192.168.0.185.63025: UDP, length 19
2007-09-13 07:32: 35.350840 IP 200.83.176.80.49847 > 192.168.0.185.63025: UDP, length 18
2007-09-13 07:32:35.403002 IP 89.37.157.114.28763 > 192.168.0.185.63025: UDP, length 19
2007-09-13 07:32:35.407810 IP 89.37.157.114.28763 > 192.168.0.185.63025: UDP, length 18

The script can locate the 210.79.186.143 but not 200.83.176.80 and 89.37.157.114. That lead us to believe that bro understand the flow in semantic level. In fact if we do the matching to 18+19 = 37 bytes, it detects the other 2. And just learn about the trace feature from scott, we immediately tried the trace and we found this -

1189639955.350840 /usr/local/stow/bro-1.3.2/policy/hot.bro:153 function called: check_hot(c = ‘[id=[orig_h=192.168.0.185, orig_p=6302
5/udp, resp_h= 200.83.176.80, resp_p=49847/udp], orig=[size=74, state=1], resp=[size=37, state=1], start_time=1189639954.79169, duration=0.559152126312256, service=, addl=, hot=0, history=Dd]’, state = ‘2’)
…blablabla another one

Here’s our simple and shameful script -

@load udp-common

redef capture_filters += { [“udp”] = “udp” };

redef local_nets: set[subnet] = {
192.168.0.0/24
};

event udp_reply(u: connection)
{
local orig = u$id$orig_h;
local resp = u$id$resp_h;
local origs = u$orig$size;
local resps = u$resp$size;
if ( u$resp$size == 18)
{
print (“Suspected udp probe”);
print fmt("%20s %5s %5s %5s", orig, resp, origs, resps);
}
}

I don’t see we can use udp time out for this as the interval of return packet is too low. Or is there workaround to examine the first corresponding udp reply packet size.

Thanks!

That's right, the size in the endpoint record is cumulative and
reflects the total size of the flow so far.

I see two options for you:

- you could remember the flows' size with every udp_reply and then
calculate the increase when the next udp_reply comes in.

- you could use the new_packet() event which gives you the size for
each packet.

None of the two approaches is very nice and both can also turn out to
be pretty expensive. The main problem here is that Bro isn't really
well-suited for expressing policies at the level of indivdual packets
as it tries to abstract from packets o high-level activity as much as
possible.

Robin

Hi Robin,

Thanks, actually it just need to check if the packet that replying is with 18 bytes length so I guess its good to go.

Back to word, I would like to know if anyone working on skype policy script, in case there’s merge of same interest.

Actually I have a student - Miguel - working on a skype analyzer as
part of his diplom thesis.

Regards,
  Bernhard