5min hack in python

Date06 Jun 2010 ContentComments

So I was trying to test some SELlinux stuff out on my KVM box and was getting flooded by tail -f thanks to someone trying to brute force my box (good luck by the way because a) password authentication is disabled and b) root login is disabled >.>) anyway I got bored with this after about 5min and then spent the next 5min writing this:

#!/usr/bin/python
import os
import socket

bannedHosts = []
failedHosts = []
ignoredIPs = []
failLimit = 0 # Better change this
bannedChain = "BadIp"

os.system("iptables -N %s &>/dev/null" % (bannedChain))
iptables = os.popen("iptables --list %s -n | egrep -v \"target.+prot.+opt.+source.+destination\" | egrep -v \"Chain %s .+ references\" | awk '{print $4}'" % (bannedChain, bannedChain))
for bannedIP in iptables.readlines():
 bannedHosts.append(bannedIP.rstrip())

loginFailures = os.popen("grep failure /var/log/secure | grep pam | awk -F \"rhost=\" '{print $2}' | awk '{print $1}' | uniq --count")
for line in loginFailures.readlines():
 (number, host) = line.split()
 try:
 ip = socket.gethostbyaddr(host)[2][0]
 except socket.error:
 ip = host

if int(number) > failLimit:
 print "%s is currently over fail limit, processing" % (ip)

if ip in bannedHosts:
 print "%s is allready banned, ignoring" % (ip)
 continue

if ip in ignoredIPs:
 print "%s is an ignored ip, ignoring" % (ip)
 continue

print "%s not allready banned, banning for %s failed attempts" % (host, number)
 os.system("iptables -A %s -s %s -j DROP" % (bannedChain, ip))
 else:
 print "%s is currently under fail limit, ignoring" % (host)

Which happens to nicely do the job as can be seen below:

[root@virtual1 ~]# ./check_bad_ip.py
213.225.207.41 is currently over fail limit, processing
mx-pool207-res41.momax.it not allready banned, banning for 15 failed attempts
88.191.92.219 is currently over fail limit, processing
sd-15684.dedibox.fr not already banned, banning for 1317 failed attempts
81.5.150.24 is currently under fail limit, ignoring
sd-15684.dedibox.fr is currently under fail limit, ignoring
81.5.150.24 is currently under fail limit, ignoring
sd-15684.dedibox.fr is currently under fail limit, ignoring
81.5.150.24 is currently under fail limit, ignoring
sd-15684.dedibox.fr is currently under fail limit, ignoring
81.5.150.24 is currently under fail limit, ignoring
sd-15684.dedibox.fr is currently under fail limit, ignoring
81.5.150.24 is currently under fail limit, ignoring
88.191.92.219 is currently over fail limit, processing
sd-15684.dedibox.fr not already banned, banning for 1014 failed attempts
114.207.245.128 is currently over fail limit, processing
114.207.245.128 not already banned, banning for 1350 failed attempts
62.182.30.165 is currently over fail limit, processing
30-165.kartel.komi.me not already banned, banning for 171 failed attempts

Oh yeah and I know the code is rubbish, it was very much a make it work thing ;) Also even though this "makes" the chain in iptables you still need to do:

iptables -I INPUT -j BadIp
iptables -I OUTPUT -j BadIp
iptables -I FORWARD -j BadIp

Because I didn't add in any code to check if they existed, nor the chain for that matter. Without them traffic won't get processed by these rules, also make sure they go near the top above any other allow rule C=

The difference

Date08 May 2010 ContentComments

I have nothing but Python to post at the moment so I shall post the difference instead! Once I have some cool stable python up I will be posting more.

Why I love Python

Date17 Apr 2010 ContentComments

So I've been playing with Python a lot recently and it is just so amazing!

Here are some quick example that all took less than 10mins to write:

SMTP proxy to allow you to connect to a server via the specified port and have it silently forwarded to another server on another port! (Note: it's a bad idea to use localhost as it will make you an open proxy)

#!/usr/bin/python
'''
Meta data
'''
__author__="Damian Zaremba"

'''
Import modules
'''
import smtpd
import asyncore

smtpd.PureProxy(('localhost', 2535), ('mail.damianzaremba.co.uk', 25))
asyncore.loop()

Email parser to allow you to process email using a IMAP connection. This is really slow currently and would be improved massively by threading but it's still really cool and took about 10min to write!

#!/usr/bin/python
'''
Meta data
'''
__author__="Damian Zaremba"

'''
Import modules
'''
import imaplib
import string

MH = imaplib.IMAP4('mail.damianzaremba.co.uk')
MH.login('inboximporter-text@damianzaremba.co.uk', 'testy')
MH.select('INBOX')

emails = {}
typ, data = MH.search(None, 'ALL')
for num in data[0].split():
 typ, data = MH.fetch(num, '(RFC822)')
 if typ == 'OK':
 data = data[0][1].split("\r\n\r\n"); headers = data[0]; message = data[1]; attachments = data[2:]

email_data = emails[num] = {
 'body': message,
 'message_id': None,
 'date': None,
 'subject': None,
 'from': None,
 'to': None,
 'attachments': []
 }

for header in headers.strip().split('\r\n'):
 data = header.split(); key = data[0]; value = string.join(data[1:])
 if key == 'Message-ID:':
 email_data['message_id'] = value
 elif key == 'Date:':
 email_data['date'] = value
 elif key == 'Subject:':
 email_data['subject'] = value
 elif key == 'From:':
 email_data['from'] = value
 elif key == 'To:':
 email_data['to'] = value

for attachment in attachments:
 email_data['attachments'].append(attachment)

MH.close()
MH.logout()
print emails

Now I just need to learn Django properly and I can do some really cool socket based interfaces to things! Hopefully if I can get what I'm working on at the moment to function correctly I can reveal some cool things in the future!