-1

I'm trying to create a iptables rule that matches the following pattern in this UDP packet:

0x0000:  0000 030a 0000 0000 0000 0000 0000 0800  ................
0x0010:  4500 0027 5d30 0000 6c11 232a 5164 585d  E..']0..l.#*QdX]
0x0020:  c0a8 6402 fe25 1e61 0013 b382 5341 4d50  ..d..%.a....SAMP
0x0030:  c063 ba71 e2ea 63                        .c.q..c

The pattern is |53414d50c063ba71| followed by a random hex, in this case |e2ea|, followed by |63|.

The rule has to assure that there are 4 digits after the |53414d50c063ba71|, and that after those 4 random digits, there is a |63|.

Right now I have this, but I don't know how to modify it accordingly:

iptables -I INPUT -p udp --dport 7777 -m string --algo kmp \
    --hex-string '|53414d50c063ba71????63|' -j DROP

???? -> How??

Please help me.

poige
  • 9,171
  • 2
  • 24
  • 50
  • I have seen it's possible to do this with http://www.stearns.org/doc/iptables-u32.current.html, but I don't know how to use it. Another option is to check the first part, just until before the 4 random digits (I know how to do it), and then match the LAST 2 digits with another rule. How to do that? – Tryhard3r Sep 29 '19 at 16:53
  • @A.B It's always the last position, in my UDP packet example, it's "63", it's always that last position, do you know how to do that with the example packet I've provided? – Tryhard3r Sep 29 '19 at 23:31
  • I made an answer but you never gave any feedback. So, is that what you wanted? – A.B Oct 08 '19 at 17:27

1 Answers1

0

As long as the offset is fixed, it's possible to use the u32 match to do this kind of test. If the payload is at the end of the packet, that means the packet must be of constant size too for u32 to be of any use.

Why? That's because u32 can only add unsigned numbers, so it's not possible to match "last 11 bytes" expressed as "at position (packet size - 11)" with u32 because there's a substraction (or an addition of a negative number).

So for this specific example with a payload size of 0x37 (55), as asked in comment, here's the u32 match expression to use (packet being UDP will already have been validated by the udp match before):

iptables -I INPUT -p udp --dport 7777 -m u32 --u32 "0x0>>0x16&0x3c@0x34=0x53414d50&&0x0>>0x16&0x3c@0x38=0xc063ba71&&0x0>>0x16&0x3c@0x3b&0xff=0x63" -j DROP

Iterative explanations (of course, understanding u32's manpage and examples is needed):

0x0 >> 0x16 & 0x3c : adjusted Internet Header Length (IHL) <=> start of UDP header
0x0 >> 0x16 & 0x3c @ 8 : 4 bytes at start of UDP data
0x0 >> 0x16 & 0x3c @ 0x34 : 4 bytes at position (0x34-8) = 0x2c of UDP data
0x0 >> 0x16 & 0x3c @ 0x34 = 0x53414d50 : 4 bytes at position 0x2c == 0x53414d50
&& : logical and
0x0 >> 0x16 & 0x3c @ 0x38 = 0xc063ba71 : 4 bytes at position 0x30 == 0xc063ba71
0x0 >> 0x16 & 0x3c @ 0x3b : 4 bytes at position (0x3b-8) = 0x33 of UDP data
0x0 >> 0x16 & 0x3c @ 0x3b && 0x000000ff : content of last byte of the 4 bytes starting at position 0x33, meaning single byte at (here last) position 0x36
0x0 >> 0x16 & 0x3c @ 0x3b && 0x000000ff = 0x63 : byte at position 0x36 == 0x63

A.B
  • 9,037
  • 2
  • 19
  • 37