How to get the from..to offset from tcpdump output to use with iptables string match module - iptables

I'm trying to get the 'from' and 'to' offset to use in my iptables rule with the string match module. Here is my output packet from the tcpdump tool:
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
05:49:49.631211 IP xxx.xxx.xxx.xxx.57625 > xxx.xxx.xxx.xxx.13333: Flags [S], seq 1036987151, win 29200, options [mss 1460,sackOK,TS val 770422252 ecr 0,nop,wscale 7], length 0
0x0000: 4514 003c 9ee3 4000 3a06 9772 bca5 2e4d E..<..#.:..r...M
0x0010: b009 6f56 e119 2f4f 3dcf 2b0f 0000 0000 ..oV../O=.+.....
0x0020: a002 7210 6e7e 0000 0204 05b4 0402 080a ..r.n~..........
0x0030: 2deb b5ec 0000 0000 0103 0307 -...........
The hex units i'm looking for their start-end position are :
bca5 2e4d b009 6f56
My aim is to get this iptables rule to work properly:
iptables -A INPUT -p tcp --dport 13333 -m string --from xx --to yy --algo bm --hex-string "|bca52e4db0096f56|" -j DROP
By the way my rule is already working fine without using the from-to offset.
Any help will be appreciated.
Best regards.

To answer your original question, you may use :
iptables -A INPUT -p tcp --dport 13333 -m string --from 12 --to 20 --algo bm --hex-string "|bca52e4db0096f56|" -j DROP
But, there is more to get the final answer as you want to improve the efficiency of iptables by adding these two options.
What I found is a little disappointing, it seems that --to option doesn't work.
I paste the original related content of man iptables in CentOS release 6.5 (Final):
--from offset
Set the offset from which it starts looking for any matching. If not passed, default is 0.
--to offset
Set the offset from which it starts looking for any matching. If not passed, default is the packet size.
As you see, the description of option --to is wrong, so is the result of my experiment use --to option. However, --from option works fine as the description.
The final answer is that the part of the bad packet represents src ip and dest ip of ip protocol, so you may use (I don't use the ip in your packet content in your question for your privacy issue, but the ip is already exposed, so maybe you can change your question) :
iptables -A INPUT -p tcp --dport 13333 -s xx.xx.xx.xx -d xx.xx.xx.xx -j DROP
Update, use module u32:
iptables -A INPUT -p tcp --dport 13333 -m u32 --u32 "12=0xbca52e4d && 16=0xb0096f56" -j DROP

Related

How to record the packets after iptables?

I want to record the packets (using tcpdump) after iptables, but it seems that tcpdump will record all the packets. I don't want the packet dropped by iptables.
Is there any way to
record the packets after iptables? or
output the packets (processing by iptables) into pcap/log file?
Thanks.
Tcpdump acts before iptables for inbound traffic, but you can use iptables "NFLOG" extension to reach your goal: http://ipset.netfilter.org/iptables-extensions.man.html#lbDI
Using "NFLOG" destination you can log desired packets to userspace application, and that's where tcpdump belongs (you can also assign traffic to a specific group and then tell tcpdump to listen from it).
Webserver (very basic) example, let's pretend you are accepting http/https traffic and dropping ssh:
#BASIC RULES
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
#NFLOG REDIRECT ONLY HTTP TRAFFIC
iptables -A INPUT -p tcp --dport 80 -j NFLOG
#TCPDUMP ONLY ON MATCHED TRAFFIC (=HTTP)
tcpdump -i nflog

IPTables rule to log then drop packets than contains a hex-string found via TCDUMP

Using TCP Dump i captured this packet which is all the time making my software unavailable.
18:56:58.979504 IP Ubuntu-1404-trusty-64-minimal.13333 > XXX.XXX.XXX.XXX.60323: Flags [.], ack 47, win 227, options [nop,nop,TS val 26672837 ecr 695829589], length 0
0x0000: f4cc 554b 552c 5404 a6a6 8f40 0800 4500 ..UKU,T....#..E.
0x0010: 0034 0ac8 4000 4006 25aa b009 6f56 bca5 .4..#.#.%...oV..
0x0020: 2e4d 2f4f eba3 ffa0 f75a aac5 8dfb 8010 .M/O.....Z......
0x0030: 00e3 72ad 0000 0101 080a 0196 fec5 2979 ..r...........)y
0x0040: 8455
After several inspections, i noticed that this packet has a fixed part which remain unchanged in every captured packet,this part is situated in the offset 0x0010 exactley : b009 6f56 bca5.
First of all i attempt to log this packet when arrived using iptables:
iptables -A INPUT -p tcp --dport 13333 -m string --algo bm --hex-string "|b0096f56bca5|" -j LOG --log-prefix "b009-6f56-bca5:"
Unfortunately this iptables rule don't work.But when i changed it to :
iptables -A INPUT -p tcp --dport 13333 -m string --algo bm --hex-string "|bca5|" -j LOG --log-prefix "b009-6f56-bca5:"
It work without any issues.
What is wrong with the 1st rule? I already tried "|b009 6f56 bca5|" without success.
Any help will be appreciated.
Best regards.
Not working tcpdump command:
tcpdump -XX src port 13333
bad output :
18:56:58.979504 IP Ubuntu-1404-trusty-64-minimal.13333 > XXX.XXX.XXX.XXX.60323: Flags [.], ack 47, win 227, options [nop,nop,TS val 26672837 ecr 695829589], length 0
0x0000: f4cc 554b 552c 5404 a6a6 8f40 0800 4500 ..UKU,T....#..E.
0x0010: 0034 0ac8 4000 4006 25aa b009 6f56 bca5 .4..#.#.%...oV..
0x0020: 2e4d 2f4f eba3 ffa0 f75a aac5 8dfb 8010 .M/O.....Z......
0x0030: 00e3 72ad 0000 0101 080a 0196 fec5 2979 ..r...........)y
0x0040: 8455
Working tcpdump command :
tcpdump -nnSOX "src host XXX.XXX.XXX.XXX" and "dst port 13333"
good output :
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
05:49:49.631211 IP xxx.xxx.xxx.xxx.57625 > xxx.xxx.xxx.xxx.13333: Flags [S], seq 1036987151, win 29200, options [mss 1460,sackOK,TS val 770422252 ecr 0,nop,wscale 7], length 0
0x0000: 4514 003c 9ee3 4000 3a06 9772 bca5 2e4d E..<..#.:..r...M
0x0010: b009 6f56 e119 2f4f 3dcf 2b0f 0000 0000 ..oV../O=.+.....
0x0020: a002 7210 6e7e 0000 0204 05b4 0402 080a ..r.n~..........
0x0030: 2deb b5ec 0000 0000 0103 0307 -...........
The rule that works for me :
iptables -A INPUT -p tcp --dport 13333 -m string --algo bm --hex-string "|bca52e4db0096f56|" -j LOG --log-prefix "Bad Packet:"
iptables -A INPUT -p tcp --dport 13333 -m string --algo bm --hex-string "|bca52e4db0096f56|" -j DROP
Here's a solution for you to try
iptables -I INPUT -j DROP -p tcp --dport 13333 -m string --algo bm --hex-string "|bca52e4db0096f56|"

Is it possible to map 1:1 port range iptable DNAT rules

I want the following rules to forward tcp packets
from 127.0.0.1:32770 to 172.17.0.36:1000
and forward packets from 127.0.0.1:32771 to 172.17.0.36:10001
and forward packets from 127.0.0.1:32772 to 172.17.0.36:10002
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 32770:32771 -j DNAT --to-destination 172.17.0.36:1000-1002
But currently it can forward all packets from 127.0.0.1:32770-32771 to any one of 172.17.0.36:1000-1002
I've struggled a lot to find this and finally found a solution that absolutely works, the command in your case would be:
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 32770:32771 -j DNAT --to-destination 172.17.0.36:1000-1002/32770
Here, 32770 is the base-port, and the mapping will start from there, for example:
32770 -> 172.17.0.36:1000
32771 -> 172.17.0.36:1001
Now, let's say the incoming range and outgoing range are not equal:
iptables -t nat -I PREROUTING -p tcp --dport 30000:30199 -j DNAT --to 10.1.1.1:40000-40099/30000
In the above case, the DNAT mapping will round itself like this:
30000 -> 10.1.1.1:40000
30001 -> 10.1.1.1:40001
...
30099 -> 10.1.1.1:40099
30100 -> 10.1.1.1:40000
30101 -> 10.1.1.1:40001
...
30199 -> 10.1.1.1:40099
The support for base-port based 1:1 port mapping in DNAT was added in 2018.
Please refer below link:
http://git.netfilter.org/iptables/commit/?id=36976c4b54061b0147d56892ac9d402dae3069df
I have seen this working in Linux kernel 4.19 and above.

Block IP address which matches a rule

The following will drop packets which contain the string specified:
iptables -I FORWARD -j DROP -p tcp -s 0.0.0.0/0 -m string --string "therichsheickc#yahoo.com"
The string is one which a botnet spammer uses (from 1000's upon 1000's of ip addresses) to hammer my email servers constantly. This rule is somewhat effective, but doesn't stop the connections. I'd like it to -j DROP the IP as well after a match. Can I do this in iptables without going to userspace?
This particular scanner always greet with EHLO 192.168.2.33. Use these rules to stop them:
iptables -t raw -A PREROUTING -i eth+ -p tcp --dport 25 -m string --string "192.168.2.33" --algo bm -m recent --set --name SBOT
iptables -I INPUT -i eth+ -p tcp --dport 25 -m recent --rcheck --name SBOT -j REJECT --reject-with tcp-reset
or maybe this will help :
iptables -A FORWARD -m string --algo bm --string "therichsheickc#yahoo.com" -j DROP

IPTables block ALL packets to port 2001

so I need to block all packets to port 2001 in order to stop Chargen amplified floods on my server. Chargen amplified floods hit port 2001. This is what I have tried, but when I look in IPTraf, i still see packets coming in on port 2001:
iptables -A INPUT -p tcp --dport 2001 -j DROP
iptables -A INPUT -p udp --dport 2001 -j DROP
Please help!
Iptables can't stop packets coming in over the wire, it will only prevent further processing of them. So it's completely normal to see the unwanted traffic in packet dumps and similar tools.