2

I need to apply an iptables rules using --string option. I need to match on --hex or ascii 2 strings that are never localized on the same area.

Each samples I tried DROP only one of my two strings, so I have false positive. I need to DROP the 2 STRINGS, but when I have only 1 string or the other, I don't want to DROP.

So, the rule that I am looking for is a AND rule around iptables.

So, I tried:

iptables -I INPUT -j DROP -m string --string "TEST1" --algo bm -m string --string "TEST2" --algo bm

Not working, it is look like I have 2 different rules, so it is blocking on TEST1 or TEST2, but not TEST1 AND TEST2 : so False Positive

iptables -N my_chain
iptables -A my_chain -j DROP
iptables -A my_chain -j QUEUE ! -f -m string --string "TEST2" --algo bm
iptables -A INPUT -j my_chain ! -f -m string --string "TEST1" --algo bm

Not working, it is look like I have 2 different rules, so it is blocking on TEST1 or TEST2, but not TEST1 AND TEST2 : so False Positive

Any advice on how to accomplish this?

slm
  • 7,615
  • 16
  • 56
  • 76
doc
  • 21
  • 1
  • 3
  • The second code block contains a logical error: As soon as you are jumping to your newly created chain, you unconditionally drop the packet so the second check is never reached. You should flip the two statements working on `my_chain` around. Besides: Are you intending to use `QUEUE` (which isn't a valid target to begin with), or did you rather want to say `ACCEPT` here? – Robidu Jun 16 '19 at 15:30

2 Answers2

1

Have you considered jumping to another used-defined table?

e.g.

iptables -A INPUT -p udp -m string --string "TEST1" --algo bm -j secondarystring

iptables -N secondarystring
iptables -A secondarystring -m string --string "TEST2" --algo bm -j DROP

In this situation only packets that match the first condition should jump into the "secondarystring" table. Then packets that match the second condition (AND) should be dropped.

PP.
  • 3,316
  • 6
  • 27
  • 31
  • Thanks for help PP. it is not working I tried : iptables -A INPUT -p udp -m string --string "TEST1" --algo bm -j secondarystring iptables -N secondarystring iptables -A secondarystring -m string --string "TEST2" --algo bm -j DROP and this one: iptables -N secondarystring iptables -A INPUT -p udp -m string --string "TEST1" --algo bm -j secondarystring iptables -A secondarystring -m string --string "TEST2" --algo bm -j DROP No one is dropped. – doc May 03 '13 at 15:22
  • @doc try typing `iptables -L -v -n` - this will output a list of your rules along with a packet count of matches - it may help you diagnose which of your rules are matching. It could be that your rules aren't matching at all - either the rules are wrong - or they are in the wrong table. Consider the diagram at http://www.csie.ntu.edu.tw/~b93070/CNL/v4.0/CNLv4.0.files/Page697.htm to decide in which table your rule should be applied (i.e. are your packets being FORWARDed or INPUTed or OUTPUTed?). – PP. May 23 '13 at 09:21
  • this rule not working – acgbox Sep 23 '19 at 19:14
0

This may be an old question, but using packet marking actually can help here. You need to consider how to set up your iptables rules (the first rule gets hit when the condition is fulfilled, and any subsequent rules are triggered when the condition you are checking for is NOT fulfilled). This neatly implements the logical AND.

iptables -t mangle -A INPUT -m string --string "pattern1" --algo bm -j MARK --or-mark 0x1
iptables -t mangle -A INPUT -m string ! --string "pattern2" --algo bm -j MARK --and-mark 0xFFFFFFFE
[...]

Please note the ! in the second and any subsequent rules which inverts the condition as well as the --and-mark and the inverted bitmask that clears out the desired bit on a match.

Then, for filtering you check whether or not the mark is there:

iptables -A INPUT -m mark --mark 0x1/0x1 -j DROP

The key lies in the order in which the chains in the different tables are processed. What you are doing here is check a given packet for several strings as it traverses the mangle table (selected by issuing -t mangle to iptables) which is processed before the filter table (no -t filter needed, because that is the default table) is processed.

After your conditions have been checked you know for certain that you have found all n conditions within the given packet (the mark is still there in this case) so the rule in the filter table gets hit and drops the packet.

Let's assume you want to check for the following three strings: foobar roflbtc cafeface

You'd have to set up the rules like this:

iptables -t mangle -A INPUT -m string --string "foobar" --algo bm -j MARK --or-mark 0x1
iptables -t mangle -A INPUT -m string ! --string "roflbtc" --algo bm -j MARK --and-mark 0xFFFFFFFE
iptables -t mangle -A INPUT -m string ! --string "cafeface" --algo bm -j MARK --and-mark 0xFFFFFFFE

Now, if you have a packet containing all these strings, you are going to get this:

  1. -m string --string "foobar" is a hit ---> Set mark 0x1 on the packet
  2. -m string ! --string "roflbtc" is a miss ---> The mark remains unchanged
  3. -m string ! --string "cafeface" is a miss ---> The mark remains unchanged

Now the packet finally reaches the rule

iptables -A INPUT -m mark --mark 0x1/0x1 -j DROP

Since the mark is present, the rule is a match and the packet gets dropped.

However, what happens if e. g. the second string is missing?

  1. -m string --string "foobar" is a hit ---> Set mark 0x1 on the packet
  2. -m string ! --string "roflbtc" is a hit (the string is NOT there!) ---> Remove mark 0x1 from the packet
  3. -m string ! --string "cafeface" is a miss ---> The mark remains unchanged

Like above the packet is going to reach the aforementioned drop rule, however, -m mark --mark 0x1/0x1 is a miss, because the mark isn't there. As a consequence, the packet can pass the filter.

Let's also examine what happens if the first string is missing:

  1. -m string --string "foobar" is a miss ---> The mark is NOT set
  2. -m string ! --string "roflbtc" is a miss ---> The mark remains unchanged
  3. -m string ! --string "cafeface" is a miss ---> The mark remains unchanged

Again, because one of the conditions are not met, the mark doesn't get set in the first place so if the drop rule is finally reached, it is a miss and again the packet may pass.

This is an easy way to link condition checks, and depending on how you set or clear the marks, you can implement virtually any logical operation - plus since the mark value is 32 bits wide, that makes up to 32 conditions that you can check for this way.

Robidu
  • 135
  • 8