Advertisement
Guest User

TimelessP's 2014-08-27 honeypot.py

a guest
Aug 27th, 2014
1,147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.31 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. import SocketServer
  4. import string
  5. import datetime
  6. import subprocess
  7. import re
  8. import threading
  9. import time
  10. import os
  11.  
  12.  
  13. def _speak_thread(text_to_say):
  14.     pattern = re.compile('[^A-Za-z0-9 .!?]+', re.UNICODE | re.MULTILINE)
  15.     clean_text = text_to_say
  16.     pattern.sub(' ', clean_text)
  17.     inputcommand = ('if [ -x `which festival` ] ; then ' +
  18.                     'echo "(SayText \\"%s\\")" |' % clean_text +
  19.                     ' festival -b --pipe ; fi')
  20.     p = subprocess.Popen(inputcommand, stdout=subprocess.PIPE, shell=True)
  21.     (output, err) = p.communicate()
  22.     return output
  23.  
  24.  
  25. def speak(text_to_say):
  26.     t = threading.Thread(target=_speak_thread, args=(text_to_say,))
  27.     t.daemon = True
  28.     t.start()
  29.  
  30.  
  31. class RequestHandler(SocketServer.BaseRequestHandler):
  32.     def setup(self):
  33.         timestamp = "%s" % datetime.datetime.now()
  34.         speak('Sir, a new connection on the honeypot.')
  35.         print("%s Connection from %s:%s" % (timestamp,
  36.               self.client_address[0], self.client_address[1]))
  37.         self.server.connections[self.client_address] = {'instance': self,
  38.                                                         'nickname': 'newbie'}
  39.         self.broadcast_others("Someone has entered the room.\r\n")
  40.         night_time = ' -d' if datetime.datetime.hour < 6 else ''
  41.         p = subprocess.Popen('fortune | cowsay %s' % night_time,
  42.                              stdout=subprocess.PIPE, shell=True)
  43.         (fortune, err) = p.communicate()
  44.         self.request.send("%s\r\nYou are in a dark room.\r\n> " % fortune)
  45.  
  46.     def handle(self):
  47.         self.input_buffer = ''
  48.         self.is_root = False
  49.         while True:
  50.             try:
  51.                 data = self.request.recv(1024)
  52.             except Exception, err:
  53.                 print("%s Receive error (%s) from %s:%s" %
  54.                       (datetime.datetime.now(),
  55.                        err,
  56.                        self.client_address[0], self.client_address[1]))
  57.                 self.broadcast_others("Someone has left the room.\r\n")
  58.                 del self.server.connections[self.client_address]
  59.                 self.finish()
  60.                 speak("Sir, someone disconnected from the honeypot.")
  61.                 break
  62.  
  63.             timestamp = "%s" % datetime.datetime.now()
  64.  
  65.             my_nickname = self.server. \
  66.                 connections[self.client_address]['nickname']
  67.  
  68.             if (data == ''):
  69.                 print("%s Connection terminated from %s:%s" % (timestamp,
  70.                       self.client_address[0], self.client_address[1]))
  71.                 self.broadcast_others("Someone has left the room.\r\n")
  72.                 del self.server.connections[self.client_address]
  73.                 self.finish()
  74.                 speak("Sir, someone disconnected from the honeypot.")
  75.                 break
  76.  
  77.             print(timestamp, self.client_address, my_nickname, 'data', data)
  78.  
  79.             # Ctrl D in character mode is \xff\xec
  80.             if data == "\xff\xec":
  81.                 data = "\x04"
  82.             # TODO: Implement full support for TELNET protocol:
  83.             if data.startswith("\xff"):
  84.                 continue
  85.  
  86.             # TODO: If any connection terminates just before we send a packet
  87.             #       then we get an unhandled exception. Not so bad because
  88.             #       only the thread dies.
  89.  
  90.             self.input_buffer = self.input_buffer + data
  91.             if (not self.input_buffer.endswith("\n") and
  92.                     not self.input_buffer.endswith("\r") and
  93.                     not self.input_buffer.endswith("\x04") and
  94.                     not self.input_buffer.endswith("\x00")):
  95.                 continue
  96.  
  97.             print(timestamp, self.client_address, my_nickname,
  98.                   'line', self.input_buffer)
  99.             data = self.input_buffer.replace("\x00", "")
  100.             self.input_buffer = ''
  101.  
  102.             # bots get snooped on, lol.
  103.             if self.is_root:
  104.                 msg = "\r\n" + str(('bot_sent', self.client_address,
  105.                                     my_nickname, data)) + \
  106.                       "\r\n"
  107.                 self.broadcast_others(msg)
  108.  
  109.             if (data.strip() == 'exit' or data.strip() == '\x04'):
  110.                 print("%s Disconnection from %s:%s" % (timestamp,
  111.                       self.client_address[0], self.client_address[1]))
  112.                 self.broadcast_others("Someone has left the room.\r\n")
  113.                 del self.server.connections[self.client_address]
  114.                 self.finish()
  115.                 speak("Sir, someone disconnected from the honeypot.")
  116.                 break
  117.             elif (data.strip() == 'shutdown'):
  118.                 print("%s Shutdown issued from %s:%s" % (timestamp,
  119.                       self.client_address[0], self.client_address[1]))
  120.                 self.server.shutdown()
  121.                 speak("Sir, someone has shut down the honeypot. Goodbye.")
  122.                 time.sleep(5)
  123.                 break
  124.  
  125.             if data.strip() == 'help':
  126.                 self.request.sendall(self.usage())
  127.             elif data.strip() == 'who':
  128.                 print(self.server.connections)
  129.                 nicknames = []
  130.                 for client in self.server.connections.values():
  131.                     nicknames.append(client['nickname'])
  132.                 self.request.sendall(str(nicknames) + "\r\n")
  133.             else:
  134.                 if data.strip().find(' ') != -1:
  135.                     command, arguments = string.split(data.strip(), ' ', 1)
  136.                 else:
  137.                     command = data.strip()
  138.                     arguments = ''
  139.  
  140.                 if command == 'say':
  141.                     msg = "\r\n" + str(('said', my_nickname, arguments)) + \
  142.                           "\r\n"
  143.                     self.broadcast_others(msg)
  144.                 elif command == 'speak':
  145.                     speak(arguments)
  146.                     msg = "\r\n" + str(('spake', my_nickname, arguments)) + \
  147.                           "\r\n"
  148.                     self.broadcast_others(msg)
  149.                 elif command == 'root':
  150.                     # Right, we have a bot, everything it says gets broadcast.
  151.                     self.is_root = True
  152.                 elif command == 'quine':
  153.                     this_file_path = os.path.realpath(__file__)
  154.                     with open(this_file_path, 'r') as this_file_handle:
  155.                         this_file_contents = this_file_handle.read()
  156.                     self.request.sendall(this_file_contents)
  157.                 elif command == 'nick':
  158.                     if len(arguments) < 1 or len(arguments) > 20:
  159.                         self.request.sendall(str(('error', 'nick',
  160.                                                   'Too long or too short.')) +
  161.                                              "\r\n")
  162.                     else:
  163.                         speak('Sir, a human is using the honeypot.')
  164.                         my_nickname = arguments
  165.                         client = self.server.connections[self.client_address]
  166.                         client['nickname'] = my_nickname
  167.  
  168.             self.request.sendall("root@honeypot:~# " if self.is_root else "> ")
  169.  
  170.     def broadcast_others(self, message):
  171.         for client in self.server.connections.values():
  172.             if not client['instance'] == self:
  173.                 client['instance'].request.sendall(message)
  174.  
  175.     def usage(self):
  176.         return """Valid commands:
  177. help        - Shows this help.
  178. who         - Shows who is currently connected to the server.
  179. nick <name> - Sets your nickname.
  180. say <msg>   - The message that follows the 'say' command will be sent to all.
  181. speak <msg> - Audibly speaks the given message to the server owner (TTS) and
  182.              also works like the say command.
  183. quine       - Print the source code of this service.
  184. exit        - Disconnect from the server.
  185. shutdown    - Immediately shutdown the entire server. Yup, anyone can. Gone.
  186. """
  187.  
  188. if __name__ == "__main__":
  189.     SocketServer.ThreadingTCPServer.allow_reuse_address = True
  190.     # 5 is default anyway.
  191.     SocketServer.ThreadingTCPServer.request_queue_size = 5
  192.     server_address = ('', 2323)
  193.     server = SocketServer.ThreadingTCPServer(server_address,
  194.                                              RequestHandler)
  195.     server.connections = {}
  196.     server.serve_forever()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement