Large file ex-filtration revisited

So first off a HUGE thank you to Robert Rotsted who posted the original after_hours_exfiltrate.bro. (http://mailman.icsi.berkeley.edu/pipermail/bro/2014-March/007510.html). Here's how I've modified this:

module Exfil;

export {

     redef enum Notice::Type += {
          Large_File_Upload,
      };
}

## Each time a connection is logged execute the following code
event Conn::log_conn(rec: Conn::Info) {

     ## Ensure orig_bytes and resp_bytes exist, if not, return.
     if (! (rec?$orig_bytes || rec?$resp_bytes))
         return;

     ## Is this connection between a local originator and a
     ## remote responder?
     ## Are the sent bytes greater that 10 x the received bytes?
     ## Has the originator sent more than 3 Megabytes?
     if ( rec$id$orig_h in Site::local_nets &&
          rec$id$resp_h !in Site::local_nets &&
          rec$orig_bytes > (20 * rec$resp_bytes) &&
          rec$orig_bytes >= 13145728 )
     {

         NOTICE([$note=Large_File_Upload,
                 $id=rec$id,
                 $identifier=cat(rec$uid),
                 $msg=fmt("Sent Bytes: %s, Received Bytes: %s",
                          rec$orig_bytes, rec$resp_bytes)]);
     }

}

I noticed today an anomaly I guess:

2014-04-03T13:38:45-0600 - x.x.x.x 55023 4.71.33.182 80 - - - tcp Exfil::Large_File_Upload Sent Bytes: 1213381425, Received Bytes: 0 - x.x.x.x 4.71.33.182 80 - bro Notice::ACTION_LOG 3600.000000 F - - - --

2014-04-03T13:38:42-0600 CSZCCe4mZI1T7iJogg x.x.x.x 55023 4.71.33.182 80 tcp - 0.035191 1213381425 0 RSTOS0 T 0 SaR 2 88 1 40 (empty)

I found a RST packet in the capture that matched close to the sent bytes:

Transmission Control Protocol, Src Port: 55023 (55023), Dst Port: http (80), Seq: 1213381426, Len: 0

Did I hose the script by removing the hourly constraint? Thanks for the the assist...this has helped me better understand the scripting (though I'm still just at the copy and paste level :)).

James

This looks like it may be a “half-open” TCP connection, and Bro may report inaccurate {orig,resp}_bytes unless you’re running a development version from the git repo which has a fix for this situation. What version of Bro are you running?

A way to improve your detection with only script changes could be to include {orig,resp}_ip_bytes in the criteria. The difference is that field counts total bytes of IP packets, not just payload data. It’s also more sensitive to packet loss, where {orig,resp}_bytes should still work since it’s monitoring the TCP sequence space.

- Jon

Thanks Jon,

I'm on 2.2 here. I'm going to start fiddling with the script now...thanks again for the help and response.

James

Ok...I've made the below modification:

     if ( rec$id$orig_h in Site::local_nets &&
          rec$id$resp_h in Site::local_nets &&
          rec$orig_bytes > (10 * rec$resp_bytes) &&
          rec$orig_bytes > (10 * rec$resp_ip_bytes) &&
          rec$orig_bytes >= 3145728 )

     {

This works in dev when sending a large file, so going to test this out in production....thank you.

James

James,

Glad to hear that the script was helpful!

–bob

Well shoot..still seeing these:

1396617228.413862 - x.x.x.x 51859 x.x.x.x 80 - - - tcp Exfil::Large_File_Upload Sent Bytes: 1029838798, Received Bytes: 0 - x.x.x.x x.x.x.x 80 - bro Notice::ACTION_LOG 3600.000000 F - - - - -

1396620769.215111 - x.x.x.x 53522 x.x.x.x 80 - - - tcp Exfil::Large_File_Upload Sent Bytes: 569497424, Received Bytes: 0 - x.x.x.x x.x.x.x 80 - bro Notice::ACTION_LOG 3600.000000 F - - - - -

2014-04-04T07:13:45-0600 CGZlLW2nctAkETr18c x.x.x.x 51859 x.x.x.x 80 tcp - 0.064546 1029838798 0 RSTOS0 T 0 SaR 2 92 1 52 (empty)
2014-04-04T08:12:46-0600 C7E5mt24LSdkhFVcI5 x.x.x.x 53522 x.x.x.x 80 tcp - 0.064791 569497424 0 RSTOS0 T 0 SaR 2 92 1 52 (empty)

Should I just take the plunge to the latest git? Side question...how to get the bro id (CGZlLW2nctAkETr18c) in the notice file? I have:

  NOTICE([$note=Large_File_Upload,
                 $id=rec$id,
                 $identifier=cat(rec$uid),
                 $msg=fmt("Sent Bytes: %s, Received Bytes: %s",
                          rec$orig_bytes, rec$resp_bytes)]);

Thank you.

James

rec$orig_bytes > (10 * rec$resp_ip_bytes) is probably still going to be true if the calculation of orig_bytes was botched and incorrectly reported as too large. You probably meant rec$orig_ip_bytes > (10 * rec$resp_bytes) ?

Another idea might be to just check for ‘d’ or ‘D’ in the history field to verify the value is sane — absence of ‘d’ or ‘D’ means no payload data was seen, just control packets, so large values of {orig,resp}_bytes can’t possibly make sense.

- Jon