Advertising
Is your server exploited (Part 2)

28.05.2011 - 17:21:01

OK, testing completed. 17714 Bans within 5 days, runned every 15minutes

Download ther file here

 Code von Datei getstatus_ban1_4.sh
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
 
#!/bin/bash

##################################################################################
##################################################################################
#                                                                                #
#  Q3-Engine-GetStatus-Flood-Fixer                                               #
#  Version 1.4                                                                   #
#  by schnoog (schnoog@wolffiles.de)                                             #
#                                                                                #
# Versioncontrol:                                                                #
# 1.4 - changed to function based design                                         #
#       iptables usage minimized                                                 #
#       fixed not matching DNS entries                                           #
#       added syslog functionality (bans and unbans are reported to syslog)      #
# 1.3 - added vars for iptables and tcpdump paths, also fixed no-file-error      #
#       export path for file_* set to script directory                           #
# 1.2 - fixed RegExp                                                             #
# 1.0 + 1.1 internal testing                                                     #
#                                                                                #
#                                                                                #
#                                                                                #
# Thanks to benny from Hirntot for the regexp                                    #
##################################################################################
########################       DESCRIPTION     ###################################
#                                                                                #
# This script try to get rid of the Q3-Engine getstatus-Abuse-Exploit            #
#                                                                                #
# About the exploit                                                              #
#                                                                                #
# This exploit use the getstatus udp query command with a spoofed sender         #
# adress. This 14 byte long command enganges the gameserver engine to            #
# respond the whole status of the gameserver ( > ~600 bytes on empty server)     #
# This amplification is visible if you use a tool like vnstat (vnstat -l)        #
# The outgoint traffic exceeds the incoming traffic with a faktor > 3            #
#                                                                                #
#                                                                                #
# About the script                                                               #
# This script capture the count of tcp packets set in config and search for      #
# answered getstatus queries. For any requesting IP adress the count of          #
# those packets is compared to the defind limit.                                 #
# If the limit is broken by an IP adress, the access for this IP will ne denied  #
# with iptables by adding a drop rule.                                           #
#                                                                                #
# Configuration                                                                  #
#                                                                                #
# By default, the script don`t need any configuration                            #
# The default values                                                             #
# IPTABLESBIN=/usr/sbin/iptables                                                 #
# TCPDUMPBIN=/usr/sbin/tcpdump                                                   #
# LOGGERBIN=/bin/logger                                                          #
# CAPTURETIME=3                                                                  #
# MAXPERSECONDS=2                                                                #
#                                                                                #
#                                                                                #
#                                                                                #
# will enforces drops in the case that:                                          #
#                                                                                #
# Each IP which requests more than 2 getstatus respones per second,              #
# averaged over 3 seconds                                                        #
#                                                                                #
# Requirements                                                                   #
#                                                                                #
# This script use a few open source tools to offence against this attacks        #
# tcpdump - capture incoming packets: http://www.tcpdump.org/                    #
# iptables - the most used linux firewall (packet filter)                        #
# GNU-tools - grep, cat                                                          #
#                                                                                #
# THIS SCRIPT COMES WITH NO WARRANTY! USE IT AT YOUR OWN RISK ONLY!              #
#                                                                                #
##################################################################################
##################################################################################
##################################################################################
#                                                                                #
#                                SETUP                                           #
#                                                                                #
##################################################################################
##################################################################################
#                                                                                #
#      1. Ensure you installed iptables and tcpdump                              #
#                                                                                #
#      2. Place this script on your server, and allow execution for it           #
#           #chmod +x getstatus_*                                                #
#                                                                                #
#      3. Change the configuration below to your system requirements             #
#         Hint: which iptables  and  which tcpdump  and which logger             #
#               will return the values needed to insert below                    #
#                                                                                #
#      4. Run the script once to see any errors occour                           #
#           #./getstatus_ban1_4.sh                                               #
#                                                                                #
#      5. If all went well, configure a cronjob to run the script periodically   #
#                                                                                #
#                                                                                #
######################       CONFIGURATION      ##################################
##################################################################################
CAPTURETIME=20
MAXPERSECONDS=3
IPTABLESBIN=/usr/sbin/iptables
TCPDUMPBIN=/usr/sbin/tcpdump
LOGGERBIN=/bin/logger
##################################################################################
MYDEBUG=0
DEBUGOUT=0
##################################################################################
##################################################################################
##################################################################################
##################################################################################
#######################      initialisation     ##################################
##################################################################################
thisscript=$(readlink -f $0)
mygoto=`dirname $thisscript`
mygoto="$mygoto/"
cd $mygoto
MYIFS=$IFS
IFS="
"
##################################################################################
##################################################################################
###################### set some variables and files ##############################
##################################################################################
# All bans where stored in the file defined on next line
banfile="$mygoto/banlist"
iptablesoutputlist=iptables_content
export iptablesoutputlist
rm $iptablesoutputlist 2>/dev/null
captured_data="$mygoto/tmp_captured"
touch $captured_data
captured_data_num="$mygoto/tmp_captured_num"
touch $captured_data_num
calclimit=$((MAXPERSECONDS*CAPTURETIME))
export calclimit
export MYDEBUG
export DEBUGOUT
export captured_data
export captured_data_num
export IPTABLESBIN
export TCPDUMPBIN
export CAPTURETIME
export MAXPERSECONDS
export LOGGERBIN
##################################################################################
##################################################################################
##################################################################################
################################  functions ######################################
##################################################################################
##################################################################################
#######   catpure data - captures all tcp packets for the defined time   #########
#######                  output is saved to predefined file              #########
##################################################################################
function capture_data {
$TCPDUMPBIN -f -c 100000 -A >$captured_data 2>$captured_data_num &
pid=$!
sleep $CAPTURETIME
kill $pid
}
##################################################################################
#######   ban          - Ban the given IP ($1) - Port ($2) combination,  #########
#######                  and log data together with request frequence    #########
#######                  to "banlist"                                    #########
##################################################################################
function ban {
IP=$1
PORT=$2
RPS=$3    #### Requests per second
$IPTABLESBIN -A INPUT -p udp -s $IP --dport $PORT -j DROP
$LOGGERBIN -t "GetStatusBan" -- "$IP : $PORT banned -- $RPS Requests per second"
if [ $DEBUGOUT == "1" ]
then
echo "$IPTABLESBIN -A INPUT -p udp -s $IP --dport $PORT -j DROP" >> debug.out
fi
ts=`date --utc +%s`
rps=$((IPCNT/CAPTURETIME))
tshr=`date --utc --date "1970-01-01 $ts sec" "+%Y-%m-%d %T"`
out="$ts $IP $PORT $IPCNT = $RPS ReqPerSec banned $tshr"
echo $out >> $banfile
}
##################################################################################
#######   unban        - Unban the given IP ($1) - Port ($2) combination  ########
#######                  (delete drop rule, erease entry from banfile     ########
##################################################################################
function unban {
IP=$1
PORT=$2
IPTBLN=`grep "$IP" $iptablesoutputlist | grep "$PORT" | awk '{print $1}'`
$LOGGERBIN -t "GetStatusBan" -- "$IP : $PORT unbanned"
$IPTABLESBIN -D INPUT $IPTBLN
if [ $DEBUGOUT == "1" ]
then
echo "$IPTABLESBIN -D INPUT $IPTBLN" >> debug.out
fi
grep -v "$IP" $banfile > tmp001
mv tmp001 $banfile
}
##################################################################################
#######  autounban     - walks through banfile and check each entry for   ########
#######                  corresponding captured tcp date. If no match is  ########
#######                  found, unban is called to release drop rule      ########
##################################################################################
function autounban {
if [ -f $banfile ]
then
if [ ! -f $iptablesoutputlist ]
then
$IPTABLESBIN -L -v -n --line-numbers > $iptablesoutputlist
fi
bancont=$(cat $banfile | sort -u)
for banline in $bancont
do
LIP=`echo $banline | awk '{print $2}'`
LPORT=`echo $banline | awk '{print $3}'`
indump=$(grep "$LIP" $captured_data | wc -l)
if [ $indump == "0" ]
then
if [ $DEBUGOUT == "1" ]
then
echo "unban $LIP $LPORT"
fi
unban "$LIP" "$LPORT"
sleep 1
fi
done
fi
}
##################################################################################
#######   autoban      - starts the ban routine: calls capture_data      #########
#######                  greps the IPs to which getStatusRepsonsed where #########
#######                  delivered. If more then defined responses       #########
#######                  sent to a single IP, the ban routine is called  #########
##################################################################################
function autoban {
capture_data
allips=$(grep -B2 Respon $captured_data | grep UDP | awk '{print $5}' | cut -d '.' -f 1,2,3,4 | sort -u)
for newip in $allips
do
cnt=$(grep -B2 Respon $captured_data | grep UDP | grep $newip | wc -l)
ports=$(grep -B2 Respon $captured_data | grep UDP | grep $newip | awk '{print $3}' | perl -e 'while (<STDIN>) {print "$1\n" if ($_ =~ /\.(\d+)$/)}' | sort -u)
rps=$((cnt/CAPTURETIME))
for port in $ports
do
if [ $MYDEBUG == "1" ]
then
calclimit=8
echo "--No ban: $newip $port $cnt $rps"
fi
if [ $cnt -gt $calclimit ]
then
ban "$newip" "$port" "$rps"
fi
done
done
}
##################################################################################
##################################################################################
###################            Script routine startup             ################
##################################################################################
autoban
autounban
##################################################################################
##################################################################################
###################                 Cleanup               ########################
##################################################################################
IFS=$MYIFS
rm $captured_data 2>/dev/null
rm $captured_data_num 2>/dev/null
rm $iptablesoutputlist 2>/dev/null
##################################################################################
##################################################################################
##################################################################################

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


28.05.2011 - 19:53:58

you configured it to the right values???
that:
CAPTIME="5" # Time in seconds the packet capture will run
LIMIT="4" # Block if there are ${LIMIT} packets/s from one ip address

Regards,
Rod

  zer0o0
Private First Class

User Pic

Posts: 37
Registred: 26.01.2011

   

0 approved this posting.


28.05.2011 - 21:09:58

Nice Schnoog, I'll test it now.

Opps, Zer0o0, I forgot the default limit value to 40 hehe,

EDIT: for Debian the values have to be changed:


IPTABLESBIN=/sbin/iptables
TCPDUMPBIN=/usr/sbin/tcpdump
LOGGERBIN=/usr/bin/logger


Question: "logger" is a file? Can i change it to be created in the installation directory?


EDIT: now paths for Debian Lenny are correct


last changed by old-owl am 29.05.2011 - 17:56:28

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


29.05.2011 - 14:22:30

Just to help if someone is running Fedora, using the schnooq script
the directories are different too:

IPTABLESBIN=/sbin/iptables
TCPDUMPBIN=/usr/sbin/tcpdump
LOGGERBIN=/usr/bin/logger

Regards,
Rod

  zer0o0
Private First Class

User Pic

Posts: 37
Registred: 26.01.2011

   

0 approved this posting.


29.05.2011 - 15:04:47

Thanks for your path-fixes.
Next version I`ll try to determine the distribution and / or set the correct paths automatically.

logger is the linux program to write entries into system-log (if yu want I`ll add a new configurable log-output [syslog or local log f.e.]

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


30.05.2011 - 13:42:13

Yesterday with your new script I got the system alerts from the hosting company, The traffic was increased a lot.

Seems that the new script doesn't block all IP's as before. The settings are the same:

CAPTURETIME=15
MAXPERSECONDS=4

I don't know whats changed at all, and I am sure that it does something because iptables -S show the bans of the new script. The syslog show that he ban and unban IP's from time to time.

For now I've set back the old script in crontab.

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


30.05.2011 - 20:41:13

I`m running the script every 10 minutes now, since I noticed some attacks started a few minutes after full hour.

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


31.05.2011 - 13:34:18

Now I run the new script every 10 minutes. All ok. Well done Schnoog :D

Maybe I got the warning because our main server was full of players, plus for some time the server was unprotected against the attackers, since I stopped the old script in order to run the newest one.

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


01.06.2011 - 16:55:15

If i set my server an alias ip like eth0:1 this script will continues blocking those attacks?

  zer0o0
Private First Class

User Pic

Posts: 37
Registred: 26.01.2011

   

0 approved this posting.


01.06.2011 - 17:46:51

The script doesn`t cares about the servers ip.



To explain it:

The script dumps all tcp-packets for the defined time into a file

Banning:
The script looks for query-replies, and count the number of answers each foreign IP sent to.
If the count is higher than capturetime x max/s -> drop incoming packets from the offenders IP.

Unbanning:
The script look for allready banned IPs, and check if an incoming getStatus-request from the banned IP is captured (since tcpdump captures the traffic on the "net" - side of iptables, even iptable-dropped packets where captured)
If no entry is found, the ban will be released.

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


01.06.2011 - 23:48:48

Thx for the answer!! I have tested your script and its running great!! Good work!!! :)

Regards,
Rod.

  zer0o0
Private First Class

User Pic

Posts: 37
Registred: 26.01.2011

   

0 approved this posting.


04.06.2011 - 22:11:33

Sometimes I see some attackers through iftop, and if I launch the script manually I see these errors:


iptables: Bad rule (does a matching rule exist in that chain?)
iptables: Index of deletion too big
iptables: Index of deletion too big
iptables: Index of deletion too big

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


06.06.2011 - 13:35:02

Even your script works a lot and seems to work, I see that iptables is full of new entries: in 24 hours almost 200 banned IP's (consider I run 3 servers).

The problem is that the traffic increased a lot again with this new script version.

It is maybe because the script unban too early some IP's?
Can your script ban all IP he catch then once per day do a cleanup of inactive attackers IP?

Sorry for my questions but I have to avoid this traffic and the lags ASAP.

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


06.06.2011 - 14:44:02

I`ll try to include such a daily clean-up within the next few days.

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


06.06.2011 - 22:34:42

Now I am running the code 1.3 and I hope that you can make something like 1.3 that is fast like 1.4 and efficient like 1.3

I know that this seems like your new version have a problem, maybe it's me, but I don't know how your script work in detail. Could be nice to know the difference between the two versions.

What I dont get is the last errors I saw in the 1.4, and why the traffic changed from 25.000 Gb/day to 45.000 Gb/day when i changed from 1.3 to 1.4, maybe last weekend was "hot" and we had a storm of attacks?

  old-owl
Private

User Pic

Posts: 13
Registred: 06.02.2011

   

0 approved this posting.


01.08.2011 - 23:08:07

1.4 läuft bei mir zufriendenstellend.
die capture time habe ich allerdings runtergesetzt.
gibts nen "schalter" um die automatische entbannung abzuschalten?
oder ist die sinnvoll um das regelwerk klein zu halten?

  Meister Gandalf
Private First Class

User Pic

Posts: 30
Registred: 13.01.2011

   

0 approved this posting.


02.08.2011 - 16:25:54

Die automatische Löschung alter Bans hab ich aus 2 Gründen eingebaut:

1.) Um die Drop-Rules möglichst klein zu halten
2.) Da die IPs ja zu 99,9% gespooft sind, ist es nur zu gut möglich, dass irgendwann mal die IP von SL, Gametracker, TB, HLSW Master Server etc. gespooft werden. Einen solchen Bann über die notwendige Zeit hinaus aufrecht zu halten könnte einem Server beinahe schon den Todesstoss geben.

Wenn Bedarf besteht schreibe ich das Skript aber dahingehen um, dass es die Unbans nur auf einen Spezifischen Befehl hin durchführt.

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


29.08.2011 - 19:27:23

Hi,

vielen Dank für das nette Script Schnoog!
Leider zählt mein Server auch zu den Opfer der unter den Getstatus-Attacken leidet.
Das Script Version 1.4 verursachte bei mir allerdings diverse Probleme und die Unban-Funktion wollte nicht richtig funktionieren. Ich kenne mich mit Shellscripten nicht sonderlich gut aus, versuchte mich aber einzuarbeiten und habe ein stark geändertes Script erstellt.
Schaut es euch mal an, ich hoffe bei dem einen oder anderen funktioniert es auch :-)

Unter Debian 5.0 funktioniert es bei mir problemlos und zuverlässig.
Für andere Distrubtionen nicht vergessen die Pfade anzupassen.
Ich lasse es per Cronjob aller 10 Minuten laufen.

die wichtigsten Änderungen:

- Erstellung eines eigenen Iptable Chain
- Verzicht auf einzelne Port-Bans um zu viele Regel zu vermeiden
- überarbeite Unban-Funktion
- Unban abschaltbar
- Banlist Infos erweitert
- mehr Debug-Infos bei Bedarf

>>> Download <<<

Gruße

OldMan

 Code
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
 
#!/bin/bash

##################################################################################
##################################################################################
#                                                                                #
#  Variante of GetStatus AntiFlood Script by OldMan                              #
#  Version 1.0                                                                   #
#                                                                                #
#  based on Q3-Engine-GetStatus-Flood-Fixer  Version 1.4                         #
#  by schnoog (schnoog@wolffiles.de)                                             #
#  Thanks schnoog!                                                               #
#                                                                                #
# Thanks to benny from Hirntot for the regexp                                    #
##################################################################################
########################       DESCRIPTION     ###################################
#                                                                                #
# This script try to get rid of the Q3-Engine getstatus-Abuse-Exploit            #
#                                                                                #
# About the exploit                                                              #
#                                                                                #
# This exploit use the getstatus udp query command with a spoofed sender         #
# adress. This 14 byte long command enganges the gameserver engine to            #
# respond the whole status of the gameserver ( > ~600 bytes on empty server)     #
# This amplification is visible if you use a tool like vnstat (vnstat -l)        #
# The outgoint traffic exceeds the incoming traffic with a faktor > 3            #
#                                                                                #
#                                                                                #
# About the script                                                               #
# This script capture the count of tcp packets set in config and search for      #
# answered getstatus queries. For any requesting IP adress the count of          #
# those packets is compared to the defind limit.                                 #
# If the limit is broken by an IP adress, the access for this IP will ne denied  #
# with iptables by adding a drop rule.                                           #
#                                                                                #
# Configuration                                                                  #
#                                                                                #
# By default, the script don`t need any configuration                            #
# The default values                                                             #
#                                                                                #
# For Debian 5.0 ! other Linux distribution please fix paths                     #
# Disable auto unban with the option RunPart   1= Ban only, 2= Ban & Unban       #
#                                                                                #
# CAPTURETIME=12                                                                 #
# MAXPERSECONDS=4                                                                #
# RunPart=2                                                                      #
# IPTABLESBIN=/sbin/iptables                                                     #
# TCPDUMPBIN=/usr/sbin/tcpdump                                                   #
# LOGGERBIN=/usr/bin/logger                                                      #
#                                                                                #
#                                                                                #
#                                                                                #
# will enforces drops in the case that:                                          #
#                                                                                #
# Each IP which requests more than 4 getstatus respones per second,              #
# averaged over 12 seconds                                                       #
#                                                                                #
# Requirements                                                                   #
#                                                                                #
# This script use a few open source tools to offence against this attacks        #
# tcpdump - capture incoming packets: http://www.tcpdump.org/                    #
# iptables - the most used linux firewall (packet filter)                        #
# GNU-tools - grep, cat                                                          #
#                                                                                #
# THIS SCRIPT COMES WITH NO WARRANTY! USE IT AT YOUR OWN RISK ONLY!              #
#                                                                                #
##################################################################################
##################################################################################
##################################################################################
#                                                                                #
#                                SETUP                                           #
#                                                                                #
##################################################################################
##################################################################################
#                                                                                #
#      1. Ensure you installed iptables and tcpdump                              #
#                                                                                #
#      2. Place this script on your server, and allow execution for it           #
#           #chmod +x getstatus_*                                                #
#                                                                                #
#      3. Change the configuration below to your system requirements             #
#         Hint: which iptables  and  which tcpdump  and which logger             #
#               will return the values needed to insert below                    #
#                                                                                #
#      4. Run the script once to see any errors occour                           #
#           #./getstatus_ban.sh                                                  #
#                                                                                #
#      5. If all went well, configure a cronjob -Fto run the script periodically #
#                                                                                #
#      6. Optional create a Logfile-Rotation for the banfile-List                #
#                                                                                #
#      7. When the script runs without any problem disable the debug option      #
#                                                                                #
#                                                                                #
######################       CONFIGURATION      ##################################
##################################################################################
CAPTURETIME=12
MAXPERSECONDS=4
RunPart=2
IPTABLESBIN=/sbin/iptables
TCPDUMPBIN=/usr/sbin/tcpdump
LOGGERBIN=/usr/bin/logger


############################# Debug ##############################################
MYDEBUGBAN=5  # <- 1=show allips | 2=show noBan | 3=show Ban | 4=unban | 5=showAll
MYDEBUGUNBAN=3  # <- 1=show unban IP's | 2=show no unban IP's | 3=show all
IPTABLEDEBUG=1   # <- 1=show iptable entrys

##################################################################################
##################################################################################
##################################################################################
##################################################################################
#######################      initialisation     ##################################
##################################################################################
thisscript=$(readlink -f $0)
mygoto=`dirname $thisscript`
mygoto="$mygoto"
cd $mygoto
MYIFS=$IFS
IFS="
"
##################################################################################
##################################################################################
###################### set some variables and files ##############################
##################################################################################
# All bans where stored in the file defined on next line
banfile="$mygoto/banlist"
iptablesoutputlist=iptables_content
export iptablesoutputlist
rm $iptablesoutputlist 2>/dev/null
captured_data="$mygoto/tmp_captured"
touch $captured_data
captured_data_num="$mygoto/tmp_captured_mypidnum"
touch $captured_data_num
calclimit=$((MAXPERSECONDS*CAPTURETIME))
export calclimit
export MYDEBUGBAN
export MYDEBUGUNBAN
export IPTABLEDEBUG
export DEBUGOUT
export captured_data
export captured_data_num
export IPTABLESBIN
export TCPDUMPBIN
export CAPTURETIME
export MAXPERSECONDS
export LOGGERBIN

##################################################################################
################## Add new Chain and Rules for getstatus - Bans ##################

$IPTABLESBIN -nL > $mygoto/iptab.tmp

myChain=`grep "Chain getstatus" $mygoto/iptab.tmp | awk '{print $2}'`

if [ $myChain ]
then
if [ $IPTABLEDEBUG == "1" ]
then
echo "getstatus Chain exists "
fi
else
iptables -N getstatus
if [ $IPTABLEDEBUG == "1" ]
then
echo "Chain getstatus created"
fi
fi

$IPTABLESBIN  -nL > $mygoto/iptab.tmp

myRules=`grep "getstatus  udp  --  0.0.0.0/0" $mygoto/iptab.tmp | awk '{print $1}'`

if [ "$myRules" ]
then
if [ $IPTABLEDEBUG == "1" ]
then
echo "getstatus rules exists"
fi
else
$IPTABLESBIN  -A INPUT -p udp -m udp -j getstatus
if [ $IPTABLEDEBUG == "1" ]
then
echo "Rules getstatus created"
fi
fi


$IPTABLESBIN  -nL > $mygoto/iptab.tmp
iptab="$mygoto/iptab.tmp"
if [ $IPTABLEDEBUG == "1" ]
then
cat $mygoto/iptab.tmp
fi
##################################################################################
##################################################################################
##################################################################################
################################  functions ######################################
##################################################################################
##################################################################################
#######   catpure data - captures all tcp packets for the defined time   #########
#######                  output is saved to predefined file              #########
##################################################################################
function capture_data {
$TCPDUMPBIN -f -c 100000 -A >$captured_data 2>$captured_data_num & pid=$!
sleep $CAPTURETIME

mypid=`ps aux | awk '/tcpdump/ && !/awk/ { print $2 }'`
if [ $mypid <> "0" ]
then
kill $pid
fi
}
##################################################################################
#######   ban          - Ban the given IP ($1) - Port ($2) combination,  #########
#######                  and log data together with request frequence    #########
#######                  to "banlist"                                    #########
##################################################################################
function ban {
IP=$1

reqps=$((cnt/CAPTURETIME))

$IPTABLESBIN -A getstatus -s $IP -j DROP
$LOGGERBIN -t "GetStatusBan" -- "$IP  -- $cnt Requests -- $reqps Requests per second"
ts=`date --utc +%s`
rpsipcnt=$((IPCNT/CAPTURETIME))
tshr=`date --utc --date "1970-01-01 $ts sec" "+%Y-%m-%d %T"`

out="$ts $IP $IPCNT = banned $tshr for $cnt Requests in $CAPTURETIME seconds / $reqps  Requests per second "
echo $out >> $banfile
}

##################################################################################
#######   autoban      - starts the ban routine: calls capture_data      #########
#######                  greps the IPs to which getStatusRepsonsed where #########
#######                  delivered. If more then defined responses       #########
#######                  sent to a single IP, the ban routine is called  #########
##################################################################################
function autoban {
capture_data
allips=$(grep -B2 Respon $captured_data | grep UDP  | awk '{print $5}' | cut -d '.' -f 1,2,3,4 | sort -u) 

if [ $MYDEBUGBAN == "1" -o $MYDEBUGBAN == "5" ]
then echo "$unbanIP"
echo "allips:
$allips"
fi

for newip in $allips
do

cnt=$(grep -B2 Respon $captured_data | grep $newip | wc -l)

rps=$((cnt/CAPTURETIME))

##################### Unban clean IP's #######################################
#
#
# if [ $rps -lt $MAXPERSECONDS ]
# then
# IPrm= $(grep $newip -F $iptab | awk '{print $5}' | cut -d '.' -f 1,2,3,4 | sort -u)
# echo $IPrm
# if [ $IPrm  ]
# then
# $IPTABLESBIN -D getstatus -s $IPrm -j DROP
#
# if [ $MYDEBUGBAN == "4" -o $MYDEBUGBAN == "5" ]
# then
# echo "unban $IPrm"
# fi
# fi
#
# if [ $MYDEBUGBAN == "2" -o $MYDEBUGBAN == "5" ]
# then
# echo "--No ban: $newip  for $cnt Requests in $CAPTURETIME seconds"
# fi
# fi

##################### Ban unclean IP's #######################################

if [ $rps -ge $MAXPERSECONDS ]
then
if [ $MYDEBUGBAN == "3" -o $MYDEBUGBAN == "5" ]
then
echo "ban $newip for $cnt Requests in $CAPTURETIME seconds / $rps Requests per second"
fi
ban "$newip" "$rps"
fi
done
if [ $RunPart == "2" ]
then
unban
else
echo "Script section "Unban" disabled !!!"
fi
}

###################### Unban iptables getstatus  #################################


function unban {

# read banned IP from iptables chain

$IPTABLESBIN -nL getstatus > $mygoto/chain   
banIP=$(grep [0-9]* $mygoto/chain | awk '{print $4}' )


# read all IP's request, the getstatus

ips=$(grep -B2 getsta $captured_data | grep UDP  | awk '{print $3}' | cut -d '.' -f 1,2,3,4 | sort -u) 


# Seeking IP's not to be unbanned

for oldip in $banIP
do

for banip in $ips
do

if [ $oldip == $banip ]
then

echo oldip $oldip banip $banip >> $mygoto/unb
fi
done
done

for noDel in $(cat $mygoto/unb | awk '{print $2 " " $4}')
do
if [ "$noDel awk '{print $1}'"  ==   "$noDel awk '{print $2}'" ]
then
echo $noDel | awk '{print $1}' >> $mygoto/noDel.tmp
fi

done

# remove duplicate IP's

grep . $mygoto/noDel.tmp | awk '{print $1}'| sort -u > $mygoto/noDel
rm $mygoto/noDel.tmp


# remove all clean IP's from iptables chain GetStatus

for oldip in $banIP
do

unban=$(grep $oldip -F $mygoto/noDel)

if  [ -z $unban ]
then
ts=`date --utc +%s`
tshr=`date --utc --date "1970-01-01 $ts sec" "+%Y-%m-%d %T"`
ubout="$ts $oldip = unbanned $tshr"
echo $ubout >> $banfile
$LOGGERBIN -t "GetStatusUnban" -- "$oldip clean IP"
$IPTABLESBIN -D getstatus -s $oldip -j DROP
if [ $MYDEBUGUNBAN == "1" -o $MYDEBUGUNBAN == "3" ]
then
echo remove banned IP $oldip
fi
else
if [ $MYDEBUGUNBAN == "2" -o $MYDEBUGUNBAN == "3" ]
then
echo no remove banned IP $oldip
fi
fi
done

if [ $IPTABLEDEBUG == "1" ]
then
$IPTABLESBIN -nL getstatus > $mygoto/chain
fi

rm $mygoto/noDel
rm $mygoto/unb
}


##################################################################################
##################################################################################
###################            Script routine startup             ################
##################################################################################
autoban
##################################################################################
##################################################################################
###################                 Cleanup               ########################
##################################################################################
IFS=$MYIFS
rm $captured_data 2>/dev/null
rm $captured_data_num 2>/dev/null
rm $iptablesoutputlist 2>/dev/null
rm $mygoto/iptab.tmp 2>/dev/null
rm $mygoto/chain 2>/dev/null
rm $mygoto/0 2>/dev/null
################################################################################
##################################################################################
##################################################################################




last changed by OldMan2011 am 29.08.2011 - 20:23:21

  OldMan
Private First Class

User Pic

Posts: 44
Registred: 28.08.2011

   

0 approved this posting.


29.08.2011 - 19:31:45

Sieht prima aus !!! Dankeschön

  schnoog
First Sergeant

User Pic

Posts: 293
Registred: 08.12.2010
Origin: Südbaden

    

0 approved this posting.


29.08.2011 - 19:36:29

Gerne doch :) , kannst es ja mal testen. Würde mich interessieren ob es auch auf anderen Systemen läuft.

  OldMan
Private First Class

User Pic

Posts: 44
Registred: 28.08.2011

   

0 approved this posting.




Images by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Powered by IlchBB Forum 3.1 © 2010 Weblösungen Florian Körner