3 Honeypots in Python
Results 1 to 6 of 6

Thread: 3 Honeypots in Python

  1. #1
    Junior Member
    Join Date
    Jun 2006
    Posts
    8

    3 Honeypots in Python

    Hey all,
    Over the past week or so I've preoccupied myself with programming Honeypots in Python, and I thought
    I'd share them for all you to use as you want. Any feedback / modifications would be appreciated.

    HTTP- This one was designed for catching IIS Worms, so it only responds to GET and HEAD Requests:
    Code:
    import socket, time
    
    ListenPort = 80
    errpacket = """HTTP/1.1 404 Object Not Found\r
    Server: Microsoft-IIS/5.0\r
    Date: Sun, 28 May 2006 09:52:58 GMT\r
    Content-Type: text/html\r
    
    <html dir=ltr><head>\r
    <style>a:link{font:8pt/11pt verdana; color:FF0000} a:visited{font:8pt/11pt verdana; color:#4e4e4e}</style>\r
    <title>The page cannot be found</title></head><body bgcolor=\"FFFFFF\">\r
    <table width=\"410\" cellpadding=\"3\" cellspacing=\"5\">\r
    <tr><td align=\"left\" valign=\"middle\" width=\"360\"><h1 style=\"COLOR:000000; FONT:\r
    13pt/15pt verdana\">The page cannot be found</h1></td></tr><tr><td\r
    width=\"400\" colspan=\"2\"><font style=\"COLOR:000000; FONT: 8pt/11pt verdana\">The page you\r
    are looking for might have been removed, had its name changed, or is temporarily unavailable.</font></td></tr><tr>\r
    <td width=\"400\" colspan=\"2\"><font style=\"COLOR:000000; FONT: 8pt/11pt verdana\"><hr color=\"#C0C0C0\"\r
    noshade><p>Please try the following:</p>\r
    <ul><li>If you typed the page address in the Address bar, make sure that it is spelled\r
    correctly.<br></li><li>Open the <A HREF=\"http://xxxxxx.ath.cx/\">xxxxxx.ath.cx</A> home\r
    page, and then look for links to the information you want.</li><li>Click the <a\r
    href=\"javascript:history.back(1)\">Back</a> button to try another link.</li></ul><h2 style=\"font:8pt/11pt\r
    verdana; color:000000\">HTTP 404 - File not found<br>Internet Information\r
    Services<BR></h2><hr color=\"#C0C0C0\" noshade><p>Technical Information (for support personnel)</p><ul>\r
    <li>More information:<br><a href=\"http://www.microsoft.com/ContentRedirect.asp?prd=iis&sbp=&pver=5.0&pid=&ID=404&cat=web&os=&over=&hrd=&Opt1=&Opt2=&Opt3=\" \r
    target=\"_blank\">Microsoft Support</a></li></ul></font></td></tr></table></body></html>\r
    \r
    """
    headpacket = """HTTP/1.0 302 Found\r
    Server: Microsoft-IIS/5.0\r
    Content-Type: text/html\r
    \r
    \r
    """
    
    serversocket = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind((socket.gethostname(), ListenPort))
    serversocket.listen(5)
    
    while 1:
     print "Listening on port", ListenPort
     conn, addr = serversocket.accept()
     print "Connection from ", addr
     data = ""
     while 1:
      try:  
       temp = conn.recv(1000000)
       data = data + temp
      except:
       conn.close()
       break
      if temp == "":
       break
      if data.count("\r\n\r\n"):
       break 
        
     print data  
    # Tell difference between a HEAD and a GET request
     if data.count("GET") : conn.send(errpacket) 
     if data.count("HEAD") : conn.send(headpacket)
    
     conn.close()
     flFile = file("/home/brett/Honeypots-Tarpits/honeylog.txt", "a")
     flFile.write(addr[0] + " - " + time.strftime("%a, %d %b %Y %H:%M:%S %Z"))
     flFile.write("\n")
     flFile.write(data)
     flFile.write("\n")
     flFile.close()
    FTP- This one was for wasting as much of an attacker's time as possible. It accepts any
    username/password combination, but waits 2 seconds for every command, and doesn't respond to
    "QUIT". It doesn't have a data transfer section to it:
    Code:
    import socket, time
    
    ListenPort = 21
    
    serversocket = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind((socket.gethostname(), ListenPort))
    serversocket.listen(5)
    
    while 1:
     print "Listening on port", ListenPort
     conn, addr = serversocket.accept()
     print "Connection from ", addr
     data = ""
     try:
      conn.send("220-FileZilla Server version 2.2 \r\n Welcome to My FTP Server\r\n") #FTP Opening
      conn.send("220 Authorised Use Only\r\n") # Yeah Right
     except:
      conn.close()
      
     while 1: #While the connection's open, accept commands and respond appropriately
      try:  
       temp = conn.recv(1000000)
       data = data + temp
      except:
       conn.close()
       break
      if temp.count("AUTH SSL"):
       time.sleep(2)
       conn.send("500 AUTH not understood\r\n")   
      if temp.count("USER"):
       time.sleep(2)
       conn.send("331 Password required.\r\n")
      if temp.count("PASS"):
       time.sleep(2)
       conn.send("230 Authenticated.\r\n")
      if temp.count("SYST"):
       time.sleep(2)
       conn.send("215 UNIX Type: L8\r\n")
      if temp.count("PWD"):
       time.sleep(2)   
       conn.send("257 \"/\" is your current location\r\n")
      if temp.count("TYPE I"):
       time.sleep(2)   
       conn.send("200 TYPE is now 8-bit binary\r\n")
      if temp.count("SIZE"):
       time.sleep(2)   
       conn.send("550 I can only retrieve regular files\r\n")
      if temp.count("MDTM"):
       time.sleep(2)   
       conn.send("550 I can only retrieve regular files\r\n")
      if temp.count("RETR"):
       time.sleep(2)   
       conn.send("550 I can only retrieve regular files\r\n")
      if temp.count("CWD"):
       time.sleep(2)   
       conn.send("250 OK. Current directory is /\r\n")
      if temp.count("LIST"):
       time.sleep(30)
       conn.send("150 Accepted data connection\r\n")
       conn.send("226-ASCII\r\n")
    
       conn.send("226-Options: -a -l\r\n")
    
       conn.send("226 0 matches total\r\n")
      if temp.count("PASV"):
       time.sleep(2)   
       conn.send("227 Entering Passive Mode (123,123,123,123,140,109)\r\n")
      if temp == "":
       break
     conn.close()
     flFile = file("/home/brett/Honeypots-Tarpits/tarlog.txt", "a")
     flFile.write(addr[0])
     flFile.write("\n")
     flFile.write(data)
     flFile.write("\n")
     flFile.close()
    And SMTP- This one I wrote in order to see how quickly I could do it, originally I was going to add it to an
    Open Mail Relay list so spammers could try to hide behind it, and as you can see it never actually sends
    the email along, so the spam never would get delivered:
    Code:
    import socket, time
    
    ListenPort = 25
    
    serversocket = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind((socket.gethostname(), ListenPort))
    serversocket.listen(5)
    
    while 1:
     print "Listening on port", ListenPort
     conn, addr = serversocket.accept()
     print "Connection from ", addr
     data = ""
     try:
      conn.send("220 computer ESMTP Server (Microsoft Exchange Internet Mail Service 4.0.994.63) ready\r\n")
     except:
      conn.close()
      
     while 1: #While the connection's open, accept commands and respond appropriately
      try:  
       temp = conn.recv(1000000)
       data = data + temp
      except:
       conn.close()
       break
      if temp.count("HELO"):
       conn.send("250 computer\r\n") 
      if temp.count("EHLO"):
       conn.send("250 computer\r\n")  
      if temp.count("MAIL"):
       conn.send("250 Sender OK\r\n")
      if temp.count("RCPT"):
       conn.send("250 Recipient OK.\r\n")
      if temp.count("RSET"):
       conn.send("250 Ok resetting state\r\n")
      if temp.count("DATA"):
       conn.send("354 Ok Send data ending with <CRLF>.<CRLF>\r\n")
      if temp.count("\r\n.\r\n"):
       conn.send("250 Message received\r\n")
      if temp.count("QUIT"):
       conn.send("221 computer ESMTP server closing connection\r\n")
       break
      if temp.count("HELP"):
       conn.send("""
    214-Commands:\r
    214-    HELO    EHLO    MAIL    RCPT    DATA\r
    214-    RSET    NOOP    QUIT    HELP    VRFY\r
    214-    EXPN\r
    """)
      if temp.count("VRFY"):
       conn.send("250\r\n")
      if temp.count("NOOP"):
       conn.send("250\r\n")
      if temp.count("EXPN"):
       conn.send("250\r\n")
      if temp == "":
       break
     conn.close()
     flFile = file("/home/brett/Honeypots-Tarpits/smtplog.txt", "a")
     flFile.write(addr[0])
     flFile.write("\n")
     flFile.write(data)
     flFile.write("\n")
     flFile.close()
    So there they are. Hope you enjoy them,

    Brett

  2. #2
    Member
    Join Date
    Nov 2004
    Posts
    71
    They look nice. I think I might have to have a crack myself...
    How much traffic have you had in them? Or have you not put them online yet?
    If everything looks perfect, then there is something you don\'t know

  3. #3
    Super Moderator
    Know-it-All Master Beaver

    Join Date
    Jan 2003
    Posts
    3,914
    Hey Hey,

    If you look through the forums, at some point in the past I posted a small SMTP Honeypot that I wrote in python... rather lacking in features... I wrote it while experimenting with Python...

    Also I'm curious as to why you import pickle as you don't seem to use it at all.

    Peace,
    HT
    IT Blog: .:Computer Defense:.
    PnCHd (Pronounced Pinched): Acronym - Point 'n Click Hacked. As in: "That website was pinched" or "The skiddie pinched my computer because I forgot to patch".

  4. #4
    Junior Member
    Join Date
    Jun 2006
    Posts
    8
    I've got a few hits on the HTTP one from Spybot.worm and some proxy scanner, and I imported pickle because I read somewhere it was needed for the writing to the file.

    Brett

    (EDIT: After googling "pickle", I've finally found out what it does. So consider it removed.)

  5. #5
    Senior Member
    Join Date
    May 2003
    Posts
    472
    saw this thread...took you code and convereted into a multi threaded code, also organized it a bit , made it more pythonic,more flexible etc etc. Did it quickly so it is still bit buggy, ex: [\r]\n.[\r]\n doesnt works properly... need to fix it...
    Code:
    #!/usr/bin/env python
    
    import  sys
    # I love short variables
    import  threading as t
    import socket as s
    
    LOGFILE="/home/me/tmp/SMTPHoneyd.log"
    MaxThreadCount=20
    ThreadCount=0
    ThreadCountLock=t.Lock()
    LogFileLock=t.Lock()
    ListenPort = 25
    DEBUG=1
    
    def debug(data):
    	if DEBUG:
    		print "[SMTPHoneyd]", " ",data
    	else:
    		pass	
    
    class SMTPHoneyPot( t.Thread ):
    	def __init__ ( self, channel, details,lfd ):
    		global ThreadCount, ThreadCountLock, MaxThreadCount
    		self.conn = channel
    		self.rWhoPort=details[1]
    		self.rWhoIP=details[0]
    		self.logBuffer=""
    		self.lfd=lfd
    		self.id=0
    		#This dict is in the following form
    		#COMMAND_RCVED :[MSG_2_SND,FUNCTION_2_IVOKE]
    		#You do more than just logging here
    		# To create a true honeypot it will be a good idea to im plement the state machine of the SMTP Server you are emulating.
    		# or probably even making it template based so that with just a few changes in configuration file, you can make
    		# it emulate a diff server
    		self.CommandResponseDict={
    		"HELO" :["250 computer\r\n",self.log],
    		"EHLO" :["250 computer\r\n",self.log],
    		"MAIL" :["250 Sender OK\r\n",self.log],
    		"RCPT" :["250 Recipient OK.\r\n",self.log],
    		"RSET" :["250 Ok resetting state\r\n",self.log],
    		"DATA" :["354 Ok Send data ending with <CRLF>.<CRLF>\r\n",self.log],
    		"\r\n.\r\n" :["250 Message received\r\n",self.log],
    		"\n.\n" :["250 Message received\r\n",self.log],
    		"QUIT" :["221 computer ESMTP server closing connection\r\n",self.log],
    		"HELP" :["""
    214-Commands:\r\n
    214-    HELO    EHLO    MAIL    RCPT    DATA\r
    214-    RSET    NOOP    QUIT    HELP    VRFY\r
    214-    EXPN\r\n
    			""",self.log],
    		"VRFY" :["250\r\n",self.log],
    		"NOOP" :["250\r\n",self.log],
    		"EXPN" :["250\r\n",self.log]
    		}
    		if ThreadCount < MaxThreadCount:
    			ThreadCountLock.acquire()
    			ThreadCount += 1
    			debug("ThreadCount Now : %d" % ThreadCount)
    			self.id=ThreadCount
    			ThreadCountLock.release()
    			
    		t.Thread.__init__ ( self )
    	
    	def log(self,data):
    		newdata="SMTPHoneyPot [Thread ID %d,SrcIP %s,SrcPort %s]: Command : %s" % (self.id,self.rWhoIP,self.rWhoPort,data)
    		debug(newdata)
    		self.logBuffer += data
    	
    	def dumpLog(self):
    		global LogFileLock
    		LogFileLock.acquire()
    		debug("dumping data")
    		self.lfd.write(data)
    		self.lfd.flush()
    		
    	def run ( self ):
    		#send banner
    		try:
    			self.conn.send("220 computer ESMTP Server (Microsoft Exchange Internet Mail Service 4.0.994.63) ready\r\n")
    			self.log("Connected")
    		except (s.error,s.timeout):
    			self.conn.close()
    			return
    		#Handle Commands
    		while True:
    			try:
    				attkrdata=self.conn.recv(10000)
    				if not attkrdata:
    					debug("Remote machine has closed the socket")
    					break
    			except (s.error,s.timeout):
    				self.conn.close()
    				return
    			try:
    				debug("DATA: %s"%attkrdata)
    				try:
    					cmd=attkrdata.split()[0]
    				except IndexError:
    					cmd=attkrdata
    				debug("COMMAND: %s"%cmd)
    				res_action=self.CommandResponseDict[cmd]
    				res_action[1](attkrdata) # call the action method
    				debug("Sending : %s"%res_action[0])
    				try:
    					self.conn.send(res_action[0])
    				except s.error:
    					self.conn.close()
    					break
    			except KeyError:
    				self.log(attkrdata)
    if __name__=="__main__":	
    	try:
    		lfd=open(LOGFILE,"rw")
    	except (IOError,OSError):
    		print "Unable to Open the log file..Quiting"
    		sys.exit(-1)
    	debug("Opened logfile")	
    	server = s.socket ( s.AF_INET, s.SOCK_STREAM )
    	try:
    		server.bind ( ( '', ListenPort ) )
    	except s.error:
    		print "Unable to bind to port %d" % ListenPort
    		sys.exit(-1)
    	debug("bound to socket")
    	server.listen ( 5 )
    	debug("server listening")
    	
    	# Have the server serve "forever":
    	while True:
    		channel, details = server.accept()
    		debug("Got connection %s"%str(details))
    		SMTPHoneyPot( channel, details,lfd ).start()
    guru@linux:~> who I grep -i blonde I talk; cd ~; wine; talk; touch; unzip; touch; strip; gasp; finger; mount; fsck; more; yes; gasp; umount; make clean; sleep;

  6. #6
    Junior Member
    Join Date
    Jun 2006
    Posts
    8
    Whoa. I really need to learn more about Python.

    And yeah, I realise I should have made it have an internal state, but I figured if I just tell the spammer/attacker what they want to hear, they hopefully won't question it too much.

    Brett

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •