Return to Castle Wolfenstein (RTCW) “infostring” Problem
OK so I’ve been helping out for a while with a few wolf (RTCW) servers and the odd Enemy Territory (ET) one.
As these servers are monitored and statistics etc. produced regularly I started receiving alert emails that there were problems, not with just one but all of them.
Log investigation kept coming up with:
Info string length exceeded
It seems we’d a script kiddie playing with q3infoboom or similar, there’s only one way to deal with these kids and that’s to swat them like flies.
Google wasn’t much help as this is quite an old bug on an old game. ET was fine and had previously been patched, however RTCW was different, I found 2 possible solutions to the problem.
- Try to patch the binary using a generic quake3 patch download link
- Use iptables to block the attack, yes these are linux servers, as detailed here.
The simplest method seemed to be to use the patch, no problems downloading or compiling, but as it’s a generic type patch it didn’t work.
Try iptables solution instead, failure, the installed version of iptables didn’t have the string module as required, a few updates later and we were away. However a new problem arose, I now need to add “–algo” to the command, a bit of research and I’m off.
The rule wasn’t quite matching using “\xff\xff\xff\xffgetstatus” so I used my trusty echo command and got the ascii string I needed to copy and paste.
echo -e "\\xff\\xff\\xff\\xffgetstatus"
gives
ÿÿÿÿgetstatus
I did the same with getinfo too and copied them both into a text editor.
putting them into an iptables rule like:
iptables -A INPUT -p udp -m udp --dport 27960 -m string \
--string "ÿÿÿÿgetstatus" --algo bm --to 65535 \
-m length --length 64:65535 -j LOG
allowed me to get a more sensible command for later on using iptables-save:
iptables -A INPUT -p udp -m udp --dport 27960 -m string \
--hex-string "|ffffffff676574737461747573|" --algo bm \
--to 65535 -m length --length 64:65535 -j LOG
as you can see iptables has converted the whole string to hex.
So now I’ve got the command I’ll break it down into the important parts:
iptables | The Command |
-A | Append to the chain |
INPUT | The chain to modify |
-p udp -m udp | Match UDP Packets |
–dport 27960 | Match Destination port 27960 |
-m string | Use a string to match on |
–hex-string “|ffffffff676574737461747573|” | Hex version of the string to match |
–algo bm | The matching algorithm to use |
-–to 65535 | how far to look in the packet (this could possibly be reduced) |
-m length | only check packets of a certain length |
-–length 64:65535 | check packets >64 in length |
-j LOG | LOG the event |
As you can see this just logs that we’ve seen the packet, I do this for both the getinfo and getstatus, then have the exact same rule but replace LOG for DROP to ensure the game server doesn’t receive the packet.
So far all has been well, and if someone decided to play silly churlish games again I will have the IP address logged and can fire off an abuse report to their ISP in the hope that someone actually cares what their users get up to.
In conclusion I now have the following iptables rules first in the input chain, if required this can be tweaked even further to restrict to destination IP or even the network interface.
-A INPUT -p udp -m udp --dport 27960 -m string --hex-string "|ffffffff676574696e666f|" \
--algo bm --to 65535 -m length --length 64:65535 -j LOG
-A INPUT -p udp -m udp --dport 27960 -m string --hex-string "|ffffffff676574737461747573|" \
--algo bm --to 65535 -m length --length 64:65535 -j LOG
-A INPUT -p udp -m udp --dport 27960 -m string --hex-string "|ffffffff676574696e666f|" \
--algo bm --to 65535 -m length --length 64:65535 -j DROP
-A INPUT -p udp -m udp --dport 27960 -m string --hex-string "|ffffffff676574737461747573|" \
--algo bm --to 65535 -m length --length 64:65535 -j DROP
NB These are read in by iptables-restore and should be prefixed with your iptables command if you’re testing on the command line.