remove interact feature

This commit is contained in:
Michel Oosterhof
2016-12-20 11:40:26 +00:00
parent 20e6984793
commit a1675e3cea
8 changed files with 0 additions and 277 deletions

View File

@@ -83,18 +83,6 @@ txtcmds_path = txtcmds
#download_limit_size = 10485760 #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 # Network Specific Options
# ============================================================================ # ============================================================================

View File

@@ -1,208 +0,0 @@
# Copyright (c) 2009-2014 Upi Tamminen <desaster@gmail.com>
# 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

View File

@@ -251,9 +251,6 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin
self.cmdstack = [honeypot.HoneyPotShell(self)] self.cmdstack = [honeypot.HoneyPotShell(self)]
pt = self.getProtoTransport()
pt.factory.sessions[pt.transport.sessionno] = self
self.keyHandlers.update({ self.keyHandlers.update({
'\x01': self.handle_HOME, # CTRL-A '\x01': self.handle_HOME, # CTRL-A
'\x02': self.handle_LEFT, # CTRL-B '\x02': self.handle_LEFT, # CTRL-B
@@ -308,10 +305,6 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin
def connectionLost(self, reason): def connectionLost(self, reason):
""" """
""" """
pt = self.getProtoTransport()
if pt.transport.sessionno in pt.factory.sessions:
del pt.factory.sessions[pt.transport.sessionno]
self.lastlogExit() self.lastlogExit()
HoneyPotBaseProtocol.connectionLost(self, reason) HoneyPotBaseProtocol.connectionLost(self, reason)
recvline.HistoricRecvLine.connectionLost(self, reason) recvline.HistoricRecvLine.connectionLost(self, reason)

View File

@@ -27,7 +27,6 @@ class LoggingServerProtocol(insults.ServerProtocol):
insults.ServerProtocol.__init__(self, prot, *a, **kw) insults.ServerProtocol.__init__(self, prot, *a, **kw)
cfg = a[0].cfg cfg = a[0].cfg
self.bytesReceived = 0 self.bytesReceived = 0
self.interactors = []
self.ttylogPath = cfg.get('honeypot', 'log_path') self.ttylogPath = cfg.get('honeypot', 'log_path')
self.downloadPath = cfg.get('honeypot', 'download_path') self.downloadPath = cfg.get('honeypot', 'download_path')
@@ -81,9 +80,6 @@ class LoggingServerProtocol(insults.ServerProtocol):
""" """
Output sent back to user Output sent back to user
""" """
for i in self.interactors:
i.sessionWrite(bytes)
if self.ttylogOpen: if self.ttylogOpen:
ttylog.ttylog_write(self.ttylogFile, len(bytes), ttylog.ttylog_write(self.ttylogFile, len(bytes),
ttylog.TYPE_OUTPUT, time.time(), bytes) ttylog.TYPE_OUTPUT, time.time(), bytes)
@@ -122,20 +118,6 @@ class LoggingServerProtocol(insults.ServerProtocol):
self.terminalProtocol.eofReceived() 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): def loseConnection(self):
""" """
Override super to remove the terminal reset on logout 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.... FIXME: this method is called 4 times on logout....
it's called once from Avatar.closed() if disconnected it's called once from Avatar.closed() if disconnected
""" """
for i in self.interactors:
i.sessionClosed()
if self.stdinlogOpen: if self.stdinlogOpen:
try: try:
with open(self.stdinlogFile, 'rb') as f: with open(self.stdinlogFile, 'rb') as f:

View File

@@ -29,7 +29,6 @@ class CowrieSSHFactory(factory.SSHFactory):
'ssh-connection': connection.CowrieSSHConnection, 'ssh-connection': connection.CowrieSSHConnection,
} }
starttime = None starttime = None
sessions = {}
privateKeys = None privateKeys = None
publicKeys = None publicKeys = None
primes = None primes = None
@@ -53,9 +52,6 @@ class CowrieSSHFactory(factory.SSHFactory):
def startFactory(self): def startFactory(self):
""" """
""" """
# Interactive protocols are kept here for the interact feature
self.sessions = {}
# For use by the uptime command # For use by the uptime command
self.starttime = time.time() self.starttime = time.time()

View File

@@ -74,9 +74,6 @@ class HoneyPotTelnetSession(TelnetBootstrapProtocol):
def connectionLost(self, reason): 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) TelnetBootstrapProtocol.connectionLost(self, reason)
self.server = None self.server = None
@@ -84,11 +81,6 @@ class HoneyPotTelnetSession(TelnetBootstrapProtocol):
self.avatar = None self.avatar = None
self.protocol = 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? # TODO this never fires in Telnet connections is it misplaced?
def logout(self): def logout(self):

View File

@@ -53,9 +53,6 @@ class HoneyPotTelnetFactory(protocol.ServerFactory):
except IOError: except IOError:
self.banner = "" self.banner = ""
# Interactive protocols are kept here for the interact feature
self.sessions = {}
# For use by the uptime command # For use by the uptime command
self.starttime = time.time() self.starttime = time.time()
@@ -86,8 +83,6 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol):
def connectionMade(self): def connectionMade(self):
""" """
""" """
self.factory.sessions[self.transport.transport.sessionno] = self.transport.transportId
self.transport.negotiationMap[NAWS] = self.telnet_NAWS self.transport.negotiationMap[NAWS] = self.telnet_NAWS
# Initial option negotation. Want something at least for Mirai # Initial option negotation. Want something at least for Mirai
for opt in (NAWS,): for opt in (NAWS,):
@@ -103,8 +98,6 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol):
""" """
Fires on pre-authentication disconnects 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) AuthenticatingTelnetProtocol.connectionLost(self, reason)

View File

@@ -197,16 +197,6 @@ class CowrieServiceMaker(object):
# FIXME: Use addService on topService ? # FIXME: Use addService on topService ?
tsvc.setServiceParent(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 return topService
# Now construct an object which *provides* the relevant interfaces # Now construct an object which *provides* the relevant interfaces