def connectionLost(self, reason): transport.SSHClientTransport.connectionLost(self, reason) if self.factory.server.wasConnected: log.msg( log.LBLUE, '[CLIENT]', 'Lost connection with the Honeypot: ' + self.factory.server.sensor_name + ' (' + self.factory.server.honey_ip + ':' + str(self.factory.server.honey_port) + ')') #spi tg.tgMessage( "[3][CLIENT] Lost connection with the Honeypot: {} ({}:{}) )". format(self.factory.server.sensor_name, self.factory.server.honey_ip, self.factory.server.honey_port), 3) else: log.msg( log.LBLUE, '[CLIENT]', 'Lost connection with the Honeypot (Server<->Honeypot not connected)' ) if self.factory.server.post_auth_started or self.factory.server.post_auth.auth_plugin is None: self.factory.server.pre_auth.connection_lost() else: self.factory.server.post_auth.connection_lost()
def connectionMade(self): log.msg(log.LGREEN, '[CLIENT]', 'New client connection') #spi tg.tgMessage("[3][CLIENT] - New client connection", 3) self.out = self.factory.server.out self.factory.server.client = self self.factory.server.sshParse.set_client(self) transport.SSHClientTransport.connectionMade(self)
def packet_buffer(self, stage, message_num, payload): if not self.clientConnected: log.msg(log.LPURPLE, '[SERVER]', 'CONNECTION TO HONEYPOT NOT READY, BUFFERING PACKET') stage.delayedPackets.append([message_num, payload]) #spi tg.tgMessage( "[3][SERVER] Connection to Honey Net NOT REDY, BUFFERING PACKET", 3) else: if not stage.finishedSending: stage.delayedPackets.append([message_num, payload]) else: self.sshParse.parse_packet("[SERVER]", message_num, payload)
def __init__(self): self.cfg = Config.getInstance() self.otherVersionString = '' self.connections = connections.Connections() self.plugin_servers = [] self.ourVersionString = self.cfg.get(['honeypot', 'ssh_banner']) if len(self.ourVersionString) > 0: log.msg( log.LPURPLE, '[SERVER]', 'Using ssh_banner for SSH Version String: ' + self.ourVersionString) else: if self.cfg.getboolean(['honeypot-static', 'enabled']): log.msg( log.LPURPLE, '[SERVER]', 'Acquiring SSH Version String from honey_ip:honey_port') client_factory = client.HonsshSlimClientFactory() client_factory.server = self reactor.connectTCP( self.cfg.get(['honeypot-static', 'honey_ip']), int(self.cfg.get(['honeypot-static', 'honey_port'])), client_factory) elif self.cfg.getboolean(['honeypot-docker', 'enabled']): log.msg( log.LRED, '[SERVER][ERR]', 'You need to configure the ssh_banner for docker manually!' ) plugin_list = plugins.get_plugin_list() loaded_plugins = plugins.import_plugins(plugin_list) for plugin in loaded_plugins: plugin_server = plugins.run_plugins_function([plugin], 'start_server', False) plugin_name = plugins.get_plugin_name(plugin) self.plugin_servers.append({ 'name': plugin_name, 'server': plugin_server }) if self.ourVersionString != '': log.msg(log.LGREEN, '[HONSSH]', 'HonSSH Boot Sequence Complete - Ready for attacks!') #spi tg.tgMessage( "[3][SERVER] HonSSH Boot Sequence Complete - Ready for attacks!", 3)
def connection_lost(self): log.msg(log.LRED, '[OUTPUT]', 'Lost Connection with the attacker: %s' % self.end_ip) #spi tg.tgMessage( "[2] Lost Connection with the attacker {}".format(self.end_ip), 2) dt = self.get_date_time() channels = self.connections.get_channels(self.session_id) if channels is not None: for channel in channels: if 'end_time' not in channel: self._channel_closed(channel['uuid']) session = self.connections.set_session_close(self.session_id, dt) plugins.run_plugins_function(self.loaded_plugins, 'connection_lost', True, session) self.connections.del_session(self.session_id)
def write_spoof_log(conn_details): cfg = Config.getInstance() logfile = cfg.get(['folders', 'log_path']) + '/spoof.log' username = conn_details['username'] password = conn_details['password'] ip = conn_details['peer_ip'] #spi tg.tgMessage( "[1] New Attacker from {} ({}/{})".format(ip, username, password), 1) set_permissions = False found = False if os.path.isfile(logfile): f = file(logfile, 'r') lines = f.readlines() f.close() for i in range(len(lines)): lines[i] = lines[i].strip().split(' - ') if lines[i][0] == username and lines[i][1] == password: found = True if ip not in lines[i][2:]: lines[i].append(ip) f = file(logfile, 'w') for line in lines: f.write(' - '.join(line) + '\n') if not found: f.write("%s - %s - %s\n" % (username, password, ip)) f.close() else: f = file(logfile, 'a') f.write("%s - %s - %s\n" % (username, password, ip)) f.close() set_permissions = True if set_permissions: os.chmod(logfile, 0644)
def get_connection_details(conn_details): cfg = Config.getInstance() if cfg.getboolean(['spoof', 'enabled']): # Get credentials for username credentials = get_credentials(conn_details['username']) password = None if credentials is not None: for cred in credentials: # Check for real password match if cred[1] == conn_details['password']: log.msg( log.LYELLOW, '[SPOOF]', 'Real password match %s/%s' % (cred[0], conn_details['password'])) password = cred[1] break else: # Check fixed password allowed if cred[2] == 'fixed': passwords = re.sub(r'\s', '', cred[3]).split(',') # Check for fixed password match if conn_details['password'] in passwords: log.msg( log.LYELLOW, '[SPOOF]', 'Fixed password match %s/%s' % (cred[0], conn_details['password'])) #spi attackerUser = cred[0] attackerPass = conn_details['password'] tg.tgMessage( "[2] Password used: {}/{}".format( attackerUser, attackerPass), 2) password = cred[1] break # Check random password chance allowed elif cred[2] == 'random': # Try already used credentials from spoof log logfile = cfg.get(['folders', 'log_path' ]) + "/spoof.log" if os.path.isfile(logfile): f = file(logfile, 'r') used_credentials = f.read().splitlines() f.close() for used_credential in used_credentials: used_credential = used_credential.strip( ).split(' - ') if used_credential[0] == conn_details[ 'username'] and used_credential[ 1] == conn_details['password']: # Match - set password log.msg( log.LYELLOW, '[SPOOF]', 'Spoof.log password match %s/%s' % (cred[0], conn_details['password'])) password = cred[1] break # Break out from loop on match if password is not None: break # Check for random password chance if int(cred[3]) > 0: random_factor = (100 / int(cred[3])) + 1 rand = random.randrange(1, random_factor) if rand == 1: # Match - set password log.msg( log.LYELLOW, '[SPOOF]', 'Random password match %s/%s' % (cred[0], conn_details['password'])) password = cred[1] break # Do we have a match? if password is not None: write_spoof_log(conn_details) return True, conn_details['username'], password # No match! return False, '', ''
def connectionSecure(self): self.factory.server.clientConnected = True log.msg(log.LGREEN, '[CLIENT]', 'Client Connection Secured') #spi tg.tgMessage("[3][CLIENT] Client connection Secured", 3)
def parse_packet(self, parent, payload): self.data = payload if parent == '[SERVER]': # Log to TTY File self.out.input_tty(self.ttylog_file, self.data) while len(self.data) > 0: # If Tab Pressed if self.data[:1] == '\x09': self.tabPress = True self.data = self.data[1:] # If Backspace Pressed elif self.data[:1] == '\x7f' or self.data[:1] == '\x08': if self.pointer > 0: self.command = self.command[:self.pointer - 1] + self.command[self. pointer:] self.pointer -= 1 self.data = self.data[1:] # If enter or ctrl+c or newline elif self.data[: 1] == '\x0d' or self.data[: 1] == '\x03' or self.data[: 1] == '\x0a': if self.data[:1] == '\x03': self.command += "^C" self.data = self.data[1:] if self.command != '': log.msg(log.LPURPLE, '[TERM]', 'Entered command: %s' % self.command) tg.tgMessage("[CMD] {}".format(self.command), 3) self.out.command_entered(self.uuid, self.command) self.command = '' self.pointer = 0 # If Home Pressed elif self.data[:3] == '\x1b\x4f\x48': self.pointer = 0 self.data = self.data[3:] # If End Pressed elif self.data[:3] == '\x1b\x4f\x46': self.pointer = len(self.command) self.data = self.data[3:] # If Right Pressed elif self.data[:3] == '\x1b\x5b\x43': if self.pointer != len(self.command): self.pointer += 1 self.data = self.data[3:] # If Left Pressed elif self.data[:3] == '\x1b\x5b\x44': if self.pointer != 0: self.pointer -= 1 self.data = self.data[3:] # If up or down arrow elif self.data[: 3] == '\x1b\x5b\x41' or self.data[: 3] == '\x1b\x5b\x42': self.upArrow = True self.data = self.data[3:] else: self.command = self.command[:self. pointer] + self.data[:1] + self.command[ self.pointer:] self.pointer += 1 self.data = self.data[1:] elif parent == '[CLIENT]': # Log to TTY File self.out.output_tty(self.ttylog_file, self.data) for i in self.interactors: i.sendKeystroke(self.data) if self.tabPress: if not self.data.startswith('\x0d'): if self.data != '\x07': self.command = self.command + self.data self.tabPress = False if self.upArrow: while len(self.data) != 0: # Backspace if self.data[:1] == '\x08': self.command = self.command[:-1] self.pointer -= 1 self.data = self.data[1:] # ESC[K - Clear Line elif self.data[:3] == '\x1b\x5b\x4b': self.command = self.command[:self.pointer] self.data = self.data[3:] elif self.data[:1] == '\x0d': self.pointer = 0 self.data = self.data[1:] # Right Arrow elif self.data[:3] == '\x1b\x5b\x43': self.pointer += 1 self.data = self.data[3:] elif self.data[:2] == '\x1b\x5b' and self.data[3] == '\x50': self.data = self.data[4:] # Needed?! elif self.data[:1] != '\x07' and self.data[:1] != '\x0d': self.command = self.command[:self. pointer] + self.data[:1] + self.command[ self.pointer:] self.pointer += 1 self.data = self.data[1:] else: self.pointer += 1 self.data = self.data[1:] self.upArrow = False