mirror of
https://github.com/aljazceru/cowrie.git
synced 2025-12-18 22:44:29 +01:00
Fixes and restructuring for the session management code, as well as
disconnect handling in general git-svn-id: https://kippo.googlecode.com/svn/trunk@212 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
@@ -254,15 +254,12 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
|
|||||||
self.cmdstack = [HoneyPotShell(self)]
|
self.cmdstack = [HoneyPotShell(self)]
|
||||||
|
|
||||||
transport = self.terminal.transport.session.conn.transport
|
transport = self.terminal.transport.session.conn.transport
|
||||||
transport.factory.sessions.append(self) # this is for the interactors
|
transport.factory.sessions[transport.transport.sessionno] = self
|
||||||
|
|
||||||
# You are in a maze of twisty little passages, all alike
|
|
||||||
p = transport.transport.getPeer()
|
|
||||||
|
|
||||||
# real source IP of client
|
|
||||||
self.realClientIP = p.host
|
|
||||||
|
|
||||||
|
self.realClientIP = transport.transport.getPeer().host
|
||||||
self.clientVersion = transport.otherVersionString
|
self.clientVersion = transport.otherVersionString
|
||||||
|
self.logintime = transport.logintime
|
||||||
|
self.ttylog_file = transport.ttylog_file
|
||||||
|
|
||||||
# source IP of client in user visible reports (can be fake or real)
|
# source IP of client in user visible reports (can be fake or real)
|
||||||
cfg = config()
|
cfg = config()
|
||||||
@@ -271,8 +268,6 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
|
|||||||
else:
|
else:
|
||||||
self.clientIP = self.realClientIP
|
self.clientIP = self.realClientIP
|
||||||
|
|
||||||
self.logintime = time.time()
|
|
||||||
|
|
||||||
self.keyHandlers.update({
|
self.keyHandlers.update({
|
||||||
'\x04': self.handle_CTRL_D,
|
'\x04': self.handle_CTRL_D,
|
||||||
'\x15': self.handle_CTRL_U,
|
'\x15': self.handle_CTRL_U,
|
||||||
@@ -286,24 +281,15 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def lastlogExit(self):
|
# this doesn't seem to be called upon disconnect, so please use
|
||||||
starttime = time.strftime('%a %b %d %H:%M',
|
# HoneyPotTransport.connectionLost instead
|
||||||
time.localtime(self.logintime))
|
|
||||||
endtime = time.strftime('%H:%M',
|
|
||||||
time.localtime(time.time()))
|
|
||||||
duration = utils.durationHuman(time.time() - self.logintime)
|
|
||||||
utils.addToLastlog('root\tpts/0\t%s\t%s - %s (%s)' % \
|
|
||||||
(self.clientIP, starttime, endtime, duration))
|
|
||||||
|
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
recvline.HistoricRecvLine.connectionLost(self, reason)
|
recvline.HistoricRecvLine.connectionLost(self, reason)
|
||||||
transport = self.terminal.transport.session.conn.transport
|
|
||||||
transport.factory.sessions.remove(self)
|
|
||||||
self.lastlogExit()
|
|
||||||
|
|
||||||
# not sure why i need to do this:
|
# not sure why i need to do this:
|
||||||
del self.fs
|
# scratch that, these don't seem to be necessary anymore:
|
||||||
del self.commands
|
#del self.fs
|
||||||
|
#del self.commands
|
||||||
|
|
||||||
# Overriding to prevent terminal.reset()
|
# Overriding to prevent terminal.reset()
|
||||||
def initializeScreen(self):
|
def initializeScreen(self):
|
||||||
@@ -347,8 +333,9 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
|
|||||||
self.cmdstack[-1].lineReceived(line)
|
self.cmdstack[-1].lineReceived(line)
|
||||||
|
|
||||||
def keystrokeReceived(self, keyID, modifier):
|
def keystrokeReceived(self, keyID, modifier):
|
||||||
|
transport = self.terminal.transport.session.conn.transport
|
||||||
if type(keyID) == type(''):
|
if type(keyID) == type(''):
|
||||||
ttylog.ttylog_write(self.terminal.ttylog_file, len(keyID),
|
ttylog.ttylog_write(transport.ttylog_file, len(keyID),
|
||||||
ttylog.TYPE_INPUT, time.time(), keyID)
|
ttylog.TYPE_INPUT, time.time(), keyID)
|
||||||
recvline.HistoricRecvLine.keystrokeReceived(self, keyID, modifier)
|
recvline.HistoricRecvLine.keystrokeReceived(self, keyID, modifier)
|
||||||
|
|
||||||
@@ -396,37 +383,40 @@ class HoneyPotProtocol(recvline.HistoricRecvLine):
|
|||||||
self.cmdstack[-1].handle_TAB()
|
self.cmdstack[-1].handle_TAB()
|
||||||
|
|
||||||
def addInteractor(self, interactor):
|
def addInteractor(self, interactor):
|
||||||
self.terminal.interactors.append(interactor)
|
transport = self.terminal.transport.session.conn.transport
|
||||||
|
transport.interactors.append(interactor)
|
||||||
|
|
||||||
def delInteractor(self, interactor):
|
def delInteractor(self, interactor):
|
||||||
self.terminal.interactors.remove(interactor)
|
transport = self.terminal.transport.session.conn.transport
|
||||||
|
transport.interactors.remove(interactor)
|
||||||
|
|
||||||
class LoggingServerProtocol(insults.ServerProtocol):
|
class LoggingServerProtocol(insults.ServerProtocol):
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
self.ttylog_file = '%s/tty/%s-%s.log' % \
|
transport = self.transport.session.conn.transport
|
||||||
|
|
||||||
|
transport.ttylog_file = '%s/tty/%s-%s.log' % \
|
||||||
(config().get('honeypot', 'log_path'),
|
(config().get('honeypot', 'log_path'),
|
||||||
time.strftime('%Y%m%d-%H%M%S'),
|
time.strftime('%Y%m%d-%H%M%S'),
|
||||||
int(random.random() * 10000))
|
int(random.random() * 10000))
|
||||||
print 'Opening TTY log: %s' % self.ttylog_file
|
print 'Opening TTY log: %s' % transport.ttylog_file
|
||||||
ttylog.ttylog_open(self.ttylog_file, time.time())
|
ttylog.ttylog_open(transport.ttylog_file, time.time())
|
||||||
self.ttylog_open = True
|
|
||||||
self.interactors = []
|
transport.ttylog_open = True
|
||||||
|
|
||||||
insults.ServerProtocol.connectionMade(self)
|
insults.ServerProtocol.connectionMade(self)
|
||||||
|
|
||||||
def write(self, bytes, noLog = False):
|
def write(self, bytes, noLog = False):
|
||||||
for i in self.interactors:
|
transport = self.transport.session.conn.transport
|
||||||
|
for i in transport.interactors:
|
||||||
i.sessionWrite(bytes)
|
i.sessionWrite(bytes)
|
||||||
if self.ttylog_open and not noLog:
|
if transport.ttylog_open and not noLog:
|
||||||
ttylog.ttylog_write(self.ttylog_file, len(bytes),
|
ttylog.ttylog_write(transport.ttylog_file, len(bytes),
|
||||||
ttylog.TYPE_OUTPUT, time.time(), bytes)
|
ttylog.TYPE_OUTPUT, time.time(), bytes)
|
||||||
insults.ServerProtocol.write(self, bytes)
|
insults.ServerProtocol.write(self, bytes)
|
||||||
|
|
||||||
|
# this doesn't seem to be called upon disconnect, so please use
|
||||||
|
# HoneyPotTransport.connectionLost instead
|
||||||
def connectionLost(self, reason):
|
def connectionLost(self, reason):
|
||||||
for i in self.interactors:
|
|
||||||
i.sessionClosed()
|
|
||||||
if self.ttylog_open:
|
|
||||||
ttylog.ttylog_close(self.ttylog_file, time.time())
|
|
||||||
self.ttylog_open = False
|
|
||||||
insults.ServerProtocol.connectionLost(self, reason)
|
insults.ServerProtocol.connectionLost(self, reason)
|
||||||
|
|
||||||
class HoneyPotAvatar(avatar.ConchUser):
|
class HoneyPotAvatar(avatar.ConchUser):
|
||||||
@@ -501,12 +491,36 @@ class HoneyPotTransport(transport.SSHServerTransport):
|
|||||||
(self.transport.getPeer().host, self.transport.getPeer().port,
|
(self.transport.getPeer().host, self.transport.getPeer().port,
|
||||||
self.transport.getHost().host, self.transport.getHost().port,
|
self.transport.getHost().host, self.transport.getHost().port,
|
||||||
self.transport.sessionno)
|
self.transport.sessionno)
|
||||||
|
self.interactors = []
|
||||||
|
self.logintime = time.time()
|
||||||
|
self.ttylog_open = False
|
||||||
transport.SSHServerTransport.connectionMade(self)
|
transport.SSHServerTransport.connectionMade(self)
|
||||||
|
|
||||||
def ssh_KEXINIT(self, packet):
|
def ssh_KEXINIT(self, packet):
|
||||||
print 'Remote SSH version: %s' % (self.otherVersionString,)
|
print 'Remote SSH version: %s' % (self.otherVersionString,)
|
||||||
return transport.SSHServerTransport.ssh_KEXINIT(self, packet)
|
return transport.SSHServerTransport.ssh_KEXINIT(self, packet)
|
||||||
|
|
||||||
|
def lastlogExit(self):
|
||||||
|
starttime = time.strftime('%a %b %d %H:%M',
|
||||||
|
time.localtime(self.logintime))
|
||||||
|
endtime = time.strftime('%H:%M',
|
||||||
|
time.localtime(time.time()))
|
||||||
|
duration = utils.durationHuman(time.time() - self.logintime)
|
||||||
|
clientIP = self.transport.getPeer().host
|
||||||
|
utils.addToLastlog('root\tpts/0\t%s\t%s - %s (%s)' % \
|
||||||
|
(clientIP, starttime, endtime, duration))
|
||||||
|
|
||||||
|
# this seems to be the only reliable place of catching lost connection
|
||||||
|
def connectionLost(self, reason):
|
||||||
|
for i in self.interactors:
|
||||||
|
i.sessionClosed()
|
||||||
|
del self.factory.sessions[self.transport.sessionno]
|
||||||
|
self.lastlogExit()
|
||||||
|
if self.ttylog_open:
|
||||||
|
ttylog.ttylog_close(self.ttylog_file, time.time())
|
||||||
|
self.ttylog_open = False
|
||||||
|
transport.SSHServerTransport.connectionLost(self, reason)
|
||||||
|
|
||||||
from twisted.conch.ssh.common import NS, getNS
|
from twisted.conch.ssh.common import NS, getNS
|
||||||
class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
|
class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer):
|
||||||
def serviceStarted(self):
|
def serviceStarted(self):
|
||||||
@@ -546,8 +560,8 @@ class HoneyPotSSHFactory(factory.SSHFactory):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
cfg = config()
|
cfg = config()
|
||||||
|
|
||||||
# protocol instances are kept here for use by the interact feature
|
# protocol^Wwhatever instances are kept here for the interact feature
|
||||||
self.sessions = []
|
self.sessions = {}
|
||||||
|
|
||||||
# convert old pass.db root passwords
|
# convert old pass.db root passwords
|
||||||
passdb_file = '%s/pass.db' % (cfg.get('honeypot', 'data_path'),)
|
passdb_file = '%s/pass.db' % (cfg.get('honeypot', 'data_path'),)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class Interact(telnet.Telnet):
|
|||||||
if not self.readonly:
|
if not self.readonly:
|
||||||
if type(bytes) == type(''):
|
if type(bytes) == type(''):
|
||||||
ttylog.ttylog_write(
|
ttylog.ttylog_write(
|
||||||
self.interacting.terminal.ttylog_file,
|
self.interacting.ttylog_file,
|
||||||
len(bytes), ttylog.TYPE_INTERACT, time.time(), bytes)
|
len(bytes), ttylog.TYPE_INTERACT, time.time(), bytes)
|
||||||
recvline.HistoricRecvLine.keystrokeReceived(
|
recvline.HistoricRecvLine.keystrokeReceived(
|
||||||
self.interacting, bytes, None)
|
self.interacting, bytes, None)
|
||||||
@@ -97,15 +97,13 @@ class Interact(telnet.Telnet):
|
|||||||
self.transport.write('** Invalid session ID.\r\n')
|
self.transport.write('** Invalid session ID.\r\n')
|
||||||
return
|
return
|
||||||
for s in self.honeypotFactory.sessions:
|
for s in self.honeypotFactory.sessions:
|
||||||
transport = s.terminal.transport.session.conn.transport
|
if sessionno == s:
|
||||||
if sessionno == transport.transport.sessionno:
|
|
||||||
self.view(s)
|
self.view(s)
|
||||||
return
|
return
|
||||||
self.transport.write('** No such session found.\r\n')
|
self.transport.write('** No such session found.\r\n')
|
||||||
|
|
||||||
def view(self, session):
|
def view(self, sessionno):
|
||||||
transport = session.terminal.transport.session.conn.transport
|
session = self.honeypotFactory.sessions[sessionno]
|
||||||
sessionno = transport.transport.sessionno
|
|
||||||
self.transport.write(
|
self.transport.write(
|
||||||
'** Attaching to #%d, hit ESC to return\r\n' % sessionno)
|
'** Attaching to #%d, hit ESC to return\r\n' % sessionno)
|
||||||
session.addInteractor(self)
|
session.addInteractor(self)
|
||||||
@@ -114,12 +112,11 @@ class Interact(telnet.Telnet):
|
|||||||
def cmd_list(self, args):
|
def cmd_list(self, args):
|
||||||
self.transport.write('ID clientIP clientVersion\r\n')
|
self.transport.write('ID clientIP clientVersion\r\n')
|
||||||
for s in self.honeypotFactory.sessions:
|
for s in self.honeypotFactory.sessions:
|
||||||
transport = s.terminal.transport.session.conn.transport
|
session = self.honeypotFactory.sessions[s]
|
||||||
sessionno = transport.transport.sessionno
|
|
||||||
self.transport.write('%s %s %s\r\n' % \
|
self.transport.write('%s %s %s\r\n' % \
|
||||||
(str(sessionno).ljust(4),
|
(str(s).ljust(4),
|
||||||
s.realClientIP.ljust(15),
|
session.realClientIP.ljust(15),
|
||||||
s.clientVersion))
|
session.clientVersion))
|
||||||
|
|
||||||
def cmd_help(self, args = ''):
|
def cmd_help(self, args = ''):
|
||||||
self.transport.write('List of commands:\r\n')
|
self.transport.write('List of commands:\r\n')
|
||||||
@@ -140,11 +137,10 @@ class Interact(telnet.Telnet):
|
|||||||
self.transport.write('** Invalid session ID.\r\n')
|
self.transport.write('** Invalid session ID.\r\n')
|
||||||
return
|
return
|
||||||
for s in self.honeypotFactory.sessions:
|
for s in self.honeypotFactory.sessions:
|
||||||
transport = s.terminal.transport.session.conn.transport
|
if sessionno == s:
|
||||||
if sessionno == transport.transport.sessionno:
|
|
||||||
self.transport.write(
|
self.transport.write(
|
||||||
'** Disconnecting session #%d\r\n' % sessionno)
|
'** Disconnecting session #%d\r\n' % sessionno)
|
||||||
transport.loseConnection()
|
self.honeypotFactory.sessions[s].terminal.loseConnection()
|
||||||
return
|
return
|
||||||
self.transport.write('** No such session found.\r\n')
|
self.transport.write('** No such session found.\r\n')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user