[Snort-devel] [PATCH] Add 'mask' parameter to byte_jump and byte_extract

Joshua Kinard kumba at ...2185...
Mon Dec 26 23:03:08 EST 2011


I sent this in some time ago, but I don't think it ever went anywhere?
Anyways, those patches were semi-incomplete.

What this does is adds a 'mask' parameter to byte_jump and byte_extract so
that a bitmask can be applied to the converted bytes.

A sample case can be found here at the Wireshark Sample Captures:
http://wiki.wireshark.org/SampleCaptures#Network_Time_Protocol

Download NTP_sync.pcap, open it in Wireshark, and find the DNS response at
the top (should be the second packet).  In the authority section, the last
nameserver is a.ns.madduck.net.  However. the "net" part of that NS record
was already used, in the first NS record for ns1.mailworx.net.  So instead
of seeing "|03|net", we instead see |c1 36|.

This value is using part of the remaining six bits of the most significant
byte (|c1|), so if we try to use an unmodified byte_jump on those two bytes,
we will attempt to jump the value 0xc136, or 49,462 bytes, from the
beginning of the payload to a point that is beyond the end of the packet.
Only Wile E. Coyote is allowed such antics.

With a byte_jump that supports bitmasking, this does the trick:
    byte_jump:2,0,relative,mask 0x3fff,from_beginning;

Which picks up the two bytes (|c1 36|) relative to the end of the last
content match, masks off the 'c' with 0x3fff to get a final value of 0x0136,
or 310 bytes, which is jumped from the beginning of the payload to land on
top of the |03| in "|03|net", which can then be matched with a final content.

The full example rule to demonstrate this:

alert udp any 53 -> any any (msg:"DNS NS a.ns.madduck.net w/ compression";
content:"|00 02 00 01|"; content:"|01|a|02|ns|07|madduck";
byte_jump:2,0,relative,mask 0x3fff,from_beginning;
content:"|03|net"; sid:42000012; rev:1; gid:1; priority:3;
classtype:misc-activity;)

For each level of compression you have to deal with, you need one byte_jump.


Following compression pointers in DNS can also be accomplished using
byte_extract:

byte_extract:2,0,var_offset,relative,mask 0x3fff; content:"|03|net";
offset:var_offset;

But because we are limited a maximum of two byte_extracts per rule, this
limits the number of pointers that can be followed, so using byte_jump is
the better option in this specific scenario.

I am sure there are other use-cases out there, but this is the best live
example I could find to justify this new parameter.

Changes:
 doc/snort_manual.tex                              |   40 ++++++++-----
 src/detection-plugins/sp_byte_extract.c           |   65 +++++++++++++++++++++-
 src/detection-plugins/sp_byte_extract.h           |    1
 src/detection-plugins/sp_byte_jump.c              |   35 +++++++++++
 src/detection-plugins/sp_byte_jump.h              |    1
 src/dynamic-preprocessors/dcerpc2/dce2_roptions.c |   43 ++++++++++++--
 6 files changed, 162 insertions(+), 23 deletions(-)


Thanks!

-- 
Joshua Kinard
Gentoo/MIPS
kumba at ...2185...
4096R/D25D95E3 2011-03-28

"The past tempts us, the present confuses us, the future frightens us.  And
our lives slip away, moment by moment, lost in that vast, terrible in-between."

--Emperor Turhan, Centauri Republic
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: snort-2.9.2-bytejumpextract-bitmasking.patch
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20111226/9fa970c1/attachment.ksh>


More information about the Snort-devel mailing list