diff --git a/cowrie.cfg.dist b/cowrie.cfg.dist index ba39b83..144edcd 100644 --- a/cowrie.cfg.dist +++ b/cowrie.cfg.dist @@ -83,18 +83,6 @@ txtcmds_path = txtcmds #download_limit_size = 10485760 -# Session management interface. -# -# This is a telnet based service that can be used to interact with active -# sessions. Disabled by default. The interact feature is only available on -# the loopback interface. -# -# (default: false) -interact_enabled = false -# (default: 5123) -interact_port = 5123 - - # ============================================================================ # Network Specific Options # ============================================================================ diff --git a/cowrie/core/interact.py b/cowrie/core/interact.py deleted file mode 100644 index cd46378..0000000 --- a/cowrie/core/interact.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright (c) 2009-2014 Upi Tamminen -# See the COPYRIGHT file for more information - -""" -This module contains ... -""" - -import time - -from twisted.internet import protocol -from twisted.conch import telnet, recvline - -from cowrie.core import ttylog - -class Interact(telnet.Telnet): - """ - """ - - def connectionMade(self): - """ - """ - self.interacting = None - self.cmdbuf = '' - self.honeypotFactory = self.factory.honeypotFactory - self.readonly = True - # Someone tell me if i'm doing this wrong? - d = self.do(telnet.LINEMODE) - self.requestNegotiation(telnet.LINEMODE, telnet.LINEMODE_EDIT + '\x00') - self.will(telnet.ECHO) - - self.transport.write('*** cowrie session management console ***\r\n') - self.cmd_help() - - - def connectionLost(self, reason): - """ - """ - if self.interacting != None: - self.interacting.terminal.delInteractor(self) - - - def enableRemote(self, option): - """ - """ - return option == telnet.LINEMODE - - - def disableRemote(self, option): - """ - """ - pass - - - def applicationDataReceived(self, bytes): - """ - """ - # In command mode, we want to echo characters and buffer the input - if not self.interacting: - self.transport.write(bytes) - if bytes in ('\r', '\n'): - self.transport.write('\n') - pieces = self.cmdbuf.split(' ', 1) - self.cmdbuf = '' - cmd, args = pieces[0], '' - if len(pieces) > 1: - args = pieces[1] - try: - func = getattr(self, 'cmd_' + cmd) - except AttributeError: - self.transport.write('** Unknown command.\r\n') - return - func(args) - else: - self.cmdbuf += bytes - - # In non-command mode we are passing input to the session we are - # watching - else: - for c in bytes: - if ord(c) == 27: # escape - self.interacting.terminal.delInteractor(self) - self.interacting = None - self.transport.write( - '\r\n** Interactive session closed.\r\n') - return - if not self.readonly: - if type(bytes) == type(''): - ttylog.ttylog_write( - self.interacting.terminal.ttylogFile, - len(bytes), ttylog.TYPE_INTERACT, time.time(), bytes) - for c in bytes: - recvline.HistoricRecvLine.keystrokeReceived( - self.interacting, c, None) - - - def sessionWrite(self, data): - """ - """ - buf, prev = '', '' - for c in data: - if c == '\n' and prev != '\r': - buf += '\r\n' - else: - buf += c - prev = c - self.transport.write(buf) - - - def sessionClosed(self): - """ - """ - self.interacting.terminal.delInteractor(self) - self.interacting = None - self.transport.write('\r\n** Interactive session disconnected.\r\n') - - - def cmd_hijack(self, args): - """ - """ - self.cmd_view(args) - self.readonly = False - - - def cmd_view(self, args): - """ - """ - self.readonly = True - try: - sessionno = int(args) - except ValueError: - self.transport.write('** Invalid session ID.\r\n') - return - for s in self.honeypotFactory.sessions: - if sessionno == s: - self.view(s) - return - self.transport.write('** No such session found.\r\n') - - - def view(self, sessionno): - """ - """ - session = self.honeypotFactory.sessions[sessionno] - self.transport.write( - '** Attaching to #%d, hit ESC to return\r\n' % (sessionno,)) - session.terminal.addInteractor(self) - self.interacting = session - - - def cmd_list(self, args): - """ - """ - self.transport.write('ID clientIP clientVersion\r\n') - for s in self.honeypotFactory.sessions: - session = self.honeypotFactory.sessions[s] - self.transport.write('%s %s %s\r\n' % \ - (str(s).ljust(4), - session.realClientIP.ljust(15), - session.clientVersion)) - - - def cmd_help(self, args=''): - """ - """ - self.transport.write('List of commands:\r\n') - self.transport.write(' list - list all active sessions\r\n') - self.transport.write( - ' view - attach to a session in read-only mode\r\n') - self.transport.write( - ' hijack - attach to a session in interactive mode\r\n') - self.transport.write( - ' disconnect - disconnect a session\r\n') - self.transport.write(' help - this help\r\n') - self.transport.write(' exit - disconnect the console\r\n') - - - def cmd_disconnect(self, args): - """ - """ - try: - sessionno = int(args) - except ValueError: - self.transport.write('** Invalid session ID.\r\n') - return - for s in self.honeypotFactory.sessions: - if sessionno == s: - self.transport.write( - '** Disconnecting session #%d\r\n' % (sessionno,)) - self.honeypotFactory.sessions[s].terminal.loseConnection() - return - self.transport.write('** No such session found.\r\n') - - - def cmd_exit(self, args=''): - """ - """ - self.transport.loseConnection() - - - -def makeInteractFactory(honeypotFactory): - """ - """ - ifactory = protocol.Factory() - ifactory.protocol = Interact - ifactory.honeypotFactory = honeypotFactory - return ifactory - diff --git a/cowrie/core/protocol.py b/cowrie/core/protocol.py index 99862e8..0b68434 100644 --- a/cowrie/core/protocol.py +++ b/cowrie/core/protocol.py @@ -251,9 +251,6 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin self.cmdstack = [honeypot.HoneyPotShell(self)] - pt = self.getProtoTransport() - pt.factory.sessions[pt.transport.sessionno] = self - self.keyHandlers.update({ '\x01': self.handle_HOME, # CTRL-A '\x02': self.handle_LEFT, # CTRL-B @@ -308,10 +305,6 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin def connectionLost(self, reason): """ """ - pt = self.getProtoTransport() - if pt.transport.sessionno in pt.factory.sessions: - del pt.factory.sessions[pt.transport.sessionno] - self.lastlogExit() HoneyPotBaseProtocol.connectionLost(self, reason) recvline.HistoricRecvLine.connectionLost(self, reason) diff --git a/cowrie/insults/insults.py b/cowrie/insults/insults.py index a15dfa3..5bf431c 100644 --- a/cowrie/insults/insults.py +++ b/cowrie/insults/insults.py @@ -27,7 +27,6 @@ class LoggingServerProtocol(insults.ServerProtocol): insults.ServerProtocol.__init__(self, prot, *a, **kw) cfg = a[0].cfg self.bytesReceived = 0 - self.interactors = [] self.ttylogPath = cfg.get('honeypot', 'log_path') self.downloadPath = cfg.get('honeypot', 'download_path') @@ -81,9 +80,6 @@ class LoggingServerProtocol(insults.ServerProtocol): """ Output sent back to user """ - for i in self.interactors: - i.sessionWrite(bytes) - if self.ttylogOpen: ttylog.ttylog_write(self.ttylogFile, len(bytes), ttylog.TYPE_OUTPUT, time.time(), bytes) @@ -122,20 +118,6 @@ class LoggingServerProtocol(insults.ServerProtocol): self.terminalProtocol.eofReceived() - def addInteractor(self, interactor): - """ - Add to list of interactors - """ - self.interactors.append(interactor) - - - def delInteractor(self, interactor): - """ - Remove from list of interactors - """ - self.interactors.remove(interactor) - - def loseConnection(self): """ Override super to remove the terminal reset on logout @@ -148,9 +130,6 @@ class LoggingServerProtocol(insults.ServerProtocol): FIXME: this method is called 4 times on logout.... it's called once from Avatar.closed() if disconnected """ - for i in self.interactors: - i.sessionClosed() - if self.stdinlogOpen: try: with open(self.stdinlogFile, 'rb') as f: diff --git a/cowrie/ssh/factory.py b/cowrie/ssh/factory.py index da27aff..27404eb 100644 --- a/cowrie/ssh/factory.py +++ b/cowrie/ssh/factory.py @@ -29,7 +29,6 @@ class CowrieSSHFactory(factory.SSHFactory): 'ssh-connection': connection.CowrieSSHConnection, } starttime = None - sessions = {} privateKeys = None publicKeys = None primes = None @@ -53,9 +52,6 @@ class CowrieSSHFactory(factory.SSHFactory): def startFactory(self): """ """ - # Interactive protocols are kept here for the interact feature - self.sessions = {} - # For use by the uptime command self.starttime = time.time() diff --git a/cowrie/telnet/session.py b/cowrie/telnet/session.py index 483d2d0..9959d45 100644 --- a/cowrie/telnet/session.py +++ b/cowrie/telnet/session.py @@ -74,9 +74,6 @@ class HoneyPotTelnetSession(TelnetBootstrapProtocol): def connectionLost(self, reason): """ - # TODO do I need to implement connectionLost? - # XXX verify if HoneyPotTelnetAuthProtocol's connectionLost fires otherwise - # we'll have to reimplement some of the stuff here """ TelnetBootstrapProtocol.connectionLost(self, reason) self.server = None @@ -84,11 +81,6 @@ class HoneyPotTelnetSession(TelnetBootstrapProtocol): self.avatar = None self.protocol = None - # pt = self.transport - # if pt.transport.sessionno in pt.factory.sessions: - # del pt.factory.sessions[pt.transport.sessionno] - # pt.connectionLost(reason) - # TODO this never fires in Telnet connections is it misplaced? def logout(self): diff --git a/cowrie/telnet/transport.py b/cowrie/telnet/transport.py index 4958c0c..7bffe76 100644 --- a/cowrie/telnet/transport.py +++ b/cowrie/telnet/transport.py @@ -53,9 +53,6 @@ class HoneyPotTelnetFactory(protocol.ServerFactory): except IOError: self.banner = "" - # Interactive protocols are kept here for the interact feature - self.sessions = {} - # For use by the uptime command self.starttime = time.time() @@ -86,8 +83,6 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): def connectionMade(self): """ """ - self.factory.sessions[self.transport.transport.sessionno] = self.transport.transportId - self.transport.negotiationMap[NAWS] = self.telnet_NAWS # Initial option negotation. Want something at least for Mirai for opt in (NAWS,): @@ -103,8 +98,6 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): """ Fires on pre-authentication disconnects """ - if self.transport.transport.sessionno in self.factory.sessions: - del self.factory.sessions[self.transport.transport.sessionno] AuthenticatingTelnetProtocol.connectionLost(self, reason) diff --git a/twisted/plugins/cowrie_plugin.py b/twisted/plugins/cowrie_plugin.py index a95a06d..3d37a3b 100644 --- a/twisted/plugins/cowrie_plugin.py +++ b/twisted/plugins/cowrie_plugin.py @@ -197,16 +197,6 @@ class CowrieServiceMaker(object): # FIXME: Use addService on topService ? tsvc.setServiceParent(topService) - if cfg.has_option('honeypot', 'interact_enabled') and \ - cfg.getboolean('honeypot', 'interact_enabled') == True: - iport = int(cfg.get('honeypot', 'interact_port')) - # FIXME this doesn't support checking both Telnet and SSH sessions - from cowrie.core import interact - svc = internet.TCPServer(iport, - interact.makeInteractFactory(factory), interface='127.0.0.1') - # FIXME: Use addService on topService ? - svc.setServiceParent(topService) - return topService # Now construct an object which *provides* the relevant interfaces