Simple Python Honeypot

I've been thinking about honeypots for the last few weeks and as I've been playing around with the various products, I wondered what it would take to write something up in Python.  Initially, I had these grand ideas but then it sort of dawned on me that a lot of what I'd been conjuring up would be a reinvention of the wheel.  

With a honeypot, what do we really need?  If we're building a web server, we need to answer HTTP requests, we need some sort of logging, and we need some method to alert.  I could build something from scratch or I could leverage some existing tools.  Rather than alerting, I'm going with an IP ban by using Fail2Ban but it can also trigger emails which is something I might add later.

My script is hosted under /opt and this is the structure:





The script is pretty simple:

We're defining the working directory: ./web
We're bringing in the logging functionality.
We're setting up the server.
And we're writing our log file.



import SimpleHTTPServer
import SocketServer
import os
import logging
import sys

PORT = 8000

web_dir = os.path.join(os.path.dirname(__file__), 'web')
os.chdir(web_dir)

class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        logging.error(self.headers)
        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)

Handler = GetHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
buffer=1
sys.stderr = open('http.log', 'w', buffer)
httpd.serve_forever()


Assuming you don't have it running already, with Fail2Ban, we have to setup a few things:

sudo apt-get install iptables-persistent
Answer Y
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
sudo iptables -A INPUT -j DROP
sudo su (if you don't, this next line will fail)
sudo iptables-save > /etc/iptables/rules.v4

sudo apt-get install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

sudo nano /etc/fail2ban/jail.local

At the bottom, add the following:




In the above, we define our new service, we point it to the log file, maxretry is the number of hits in the log file, and bantime is the amount of time the IP will be banned in seconds.

sudo nano /etc/fail2ban/filter.d/framework-PyServ.conf

The above file doesn't exist, we add the following:





In the above, we're parsing the log file for a GET request.  If we see it, we trigger the ban.

If you look back at the directory structure, there's an index.html file in /web.  I thought it would be fun to make it look like a broken WordPress site:





One GET request is all it takes.  We we look in /web/http.log, we see the following:





If we run:  sudo iptables -S

We see...





Setting an action in jail.local would be all that is required to send off an email alert when an IP was banned.  

If you wanted to give someone the benefit of the doubt, you could change the failed regex to:

^<HOST> - - \[.*\] "GET \/wp-admin.*.*$
^<HOST> - - \[.*\] "GET \/wp-login.php.*$

This way, if someone hits the server, they have to take an extra step to get banned.  Personally, in my head, this is running on its own and it only has one purpose.  One touch -- you get banned.