mirror of
https://github.com/aljazceru/cowrie.git
synced 2025-12-18 06:24:20 +01:00
remove interact feature
This commit is contained in:
@@ -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
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user