Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- import SocketServer
- import string
- import datetime
- import subprocess
- import re
- import threading
- import time
- import os
- def _speak_thread(text_to_say):
- pattern = re.compile('[^A-Za-z0-9 .!?]+', re.UNICODE | re.MULTILINE)
- clean_text = text_to_say
- pattern.sub(' ', clean_text)
- inputcommand = ('if [ -x `which festival` ] ; then ' +
- 'echo "(SayText \\"%s\\")" |' % clean_text +
- ' festival -b --pipe ; fi')
- p = subprocess.Popen(inputcommand, stdout=subprocess.PIPE, shell=True)
- (output, err) = p.communicate()
- return output
- def speak(text_to_say):
- t = threading.Thread(target=_speak_thread, args=(text_to_say,))
- t.daemon = True
- t.start()
- class RequestHandler(SocketServer.BaseRequestHandler):
- def setup(self):
- timestamp = "%s" % datetime.datetime.now()
- speak('Sir, a new connection on the honeypot.')
- print("%s Connection from %s:%s" % (timestamp,
- self.client_address[0], self.client_address[1]))
- self.server.connections[self.client_address] = {'instance': self,
- 'nickname': 'newbie'}
- self.broadcast_others("Someone has entered the room.\r\n")
- night_time = ' -d' if datetime.datetime.hour < 6 else ''
- p = subprocess.Popen('fortune | cowsay %s' % night_time,
- stdout=subprocess.PIPE, shell=True)
- (fortune, err) = p.communicate()
- self.request.send("%s\r\nYou are in a dark room.\r\n> " % fortune)
- def handle(self):
- self.input_buffer = ''
- self.is_root = False
- while True:
- try:
- data = self.request.recv(1024)
- except Exception, err:
- print("%s Receive error (%s) from %s:%s" %
- (datetime.datetime.now(),
- err,
- self.client_address[0], self.client_address[1]))
- self.broadcast_others("Someone has left the room.\r\n")
- del self.server.connections[self.client_address]
- self.finish()
- speak("Sir, someone disconnected from the honeypot.")
- break
- timestamp = "%s" % datetime.datetime.now()
- my_nickname = self.server. \
- connections[self.client_address]['nickname']
- if (data == ''):
- print("%s Connection terminated from %s:%s" % (timestamp,
- self.client_address[0], self.client_address[1]))
- self.broadcast_others("Someone has left the room.\r\n")
- del self.server.connections[self.client_address]
- self.finish()
- speak("Sir, someone disconnected from the honeypot.")
- break
- print(timestamp, self.client_address, my_nickname, 'data', data)
- # Ctrl D in character mode is \xff\xec
- if data == "\xff\xec":
- data = "\x04"
- # TODO: Implement full support for TELNET protocol:
- if data.startswith("\xff"):
- continue
- # TODO: If any connection terminates just before we send a packet
- # then we get an unhandled exception. Not so bad because
- # only the thread dies.
- self.input_buffer = self.input_buffer + data
- if (not self.input_buffer.endswith("\n") and
- not self.input_buffer.endswith("\r") and
- not self.input_buffer.endswith("\x04") and
- not self.input_buffer.endswith("\x00")):
- continue
- print(timestamp, self.client_address, my_nickname,
- 'line', self.input_buffer)
- data = self.input_buffer.replace("\x00", "")
- self.input_buffer = ''
- # bots get snooped on, lol.
- if self.is_root:
- msg = "\r\n" + str(('bot_sent', self.client_address,
- my_nickname, data)) + \
- "\r\n"
- self.broadcast_others(msg)
- if (data.strip() == 'exit' or data.strip() == '\x04'):
- print("%s Disconnection from %s:%s" % (timestamp,
- self.client_address[0], self.client_address[1]))
- self.broadcast_others("Someone has left the room.\r\n")
- del self.server.connections[self.client_address]
- self.finish()
- speak("Sir, someone disconnected from the honeypot.")
- break
- elif (data.strip() == 'shutdown'):
- print("%s Shutdown issued from %s:%s" % (timestamp,
- self.client_address[0], self.client_address[1]))
- self.server.shutdown()
- speak("Sir, someone has shut down the honeypot. Goodbye.")
- time.sleep(5)
- break
- if data.strip() == 'help':
- self.request.sendall(self.usage())
- elif data.strip() == 'who':
- print(self.server.connections)
- nicknames = []
- for client in self.server.connections.values():
- nicknames.append(client['nickname'])
- self.request.sendall(str(nicknames) + "\r\n")
- else:
- if data.strip().find(' ') != -1:
- command, arguments = string.split(data.strip(), ' ', 1)
- else:
- command = data.strip()
- arguments = ''
- if command == 'say':
- msg = "\r\n" + str(('said', my_nickname, arguments)) + \
- "\r\n"
- self.broadcast_others(msg)
- elif command == 'speak':
- speak(arguments)
- msg = "\r\n" + str(('spake', my_nickname, arguments)) + \
- "\r\n"
- self.broadcast_others(msg)
- elif command == 'root':
- # Right, we have a bot, everything it says gets broadcast.
- self.is_root = True
- elif command == 'quine':
- this_file_path = os.path.realpath(__file__)
- with open(this_file_path, 'r') as this_file_handle:
- this_file_contents = this_file_handle.read()
- self.request.sendall(this_file_contents)
- elif command == 'nick':
- if len(arguments) < 1 or len(arguments) > 20:
- self.request.sendall(str(('error', 'nick',
- 'Too long or too short.')) +
- "\r\n")
- else:
- speak('Sir, a human is using the honeypot.')
- my_nickname = arguments
- client = self.server.connections[self.client_address]
- client['nickname'] = my_nickname
- self.request.sendall("root@honeypot:~# " if self.is_root else "> ")
- def broadcast_others(self, message):
- for client in self.server.connections.values():
- if not client['instance'] == self:
- client['instance'].request.sendall(message)
- def usage(self):
- return """Valid commands:
- help - Shows this help.
- who - Shows who is currently connected to the server.
- nick <name> - Sets your nickname.
- say <msg> - The message that follows the 'say' command will be sent to all.
- speak <msg> - Audibly speaks the given message to the server owner (TTS) and
- also works like the say command.
- quine - Print the source code of this service.
- exit - Disconnect from the server.
- shutdown - Immediately shutdown the entire server. Yup, anyone can. Gone.
- """
- if __name__ == "__main__":
- SocketServer.ThreadingTCPServer.allow_reuse_address = True
- # 5 is default anyway.
- SocketServer.ThreadingTCPServer.request_queue_size = 5
- server_address = ('', 2323)
- server = SocketServer.ThreadingTCPServer(server_address,
- RequestHandler)
- server.connections = {}
- server.serve_forever()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement