diff --git a/CHANGELOG.md b/CHANGELOG.md index 64daa5b..9501d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ +* 2015-02-20 Removed screen clear/reset on logout * 2015-02-19 Configuration directives have changed! ssh_addr has become listen_addr and ssh_port has become listen_port. The old keywords are still accepted for backwards compatibility * default behaviour is changed to disable the exit jail diff --git a/kippo/core/protocol.py b/kippo/core/protocol.py index a3dbae1..73eedbb 100644 --- a/kippo/core/protocol.py +++ b/kippo/core/protocol.py @@ -143,7 +143,7 @@ class HoneyPotExecProtocol(HoneyPotBaseProtocol): def connectionMade(self): HoneyPotBaseProtocol.connectionMade(self) - self.terminal.transport.session.conn.transport.stdinlog_open = True + self.terminal.stdinlog_open = True self.cmdstack = [honeypot.HoneyPotShell(self, interactive=False)] self.cmdstack[0].lineReceived(self.execcmd) @@ -229,9 +229,11 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin self.lineBufferIndex = 0 class LoggingServerProtocol(insults.ServerProtocol): + """ + Wrapper for ServerProtocol that implements TTY logging + """ def connectionMade(self): transport = self.transport.session.conn.transport - transport.ttylog_file = '%s/tty/%s-%s.log' % \ (config().get('honeypot', 'log_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) @@ -241,12 +243,12 @@ class LoggingServerProtocol(insults.ServerProtocol): format='Opening TTY Log: %(logfile)s') ttylog.ttylog_open(transport.ttylog_file, time.time()) - transport.ttylog_open = True + self.ttylog_open = True - transport.stdinlog_file = '%s/%s-%s-stdin.log' % \ + self.stdinlog_file = '%s/%s-%s-stdin.log' % \ (config().get('honeypot', 'download_path'), time.strftime('%Y%m%d-%H%M%S'), transport.transportId ) - transport.stdinlog_open = False + self.stdinlog_open = False insults.ServerProtocol.connectionMade(self) @@ -254,7 +256,7 @@ class LoggingServerProtocol(insults.ServerProtocol): transport = self.transport.session.conn.transport for i in transport.interactors: i.sessionWrite(bytes) - if transport.ttylog_open and not noLog: + if self.ttylog_open and not noLog: ttylog.ttylog_write(transport.ttylog_file, len(bytes), ttylog.TYPE_OUTPUT, time.time(), bytes) @@ -262,25 +264,31 @@ class LoggingServerProtocol(insults.ServerProtocol): def dataReceived(self, data, noLog = False): transport = self.transport.session.conn.transport - if transport.ttylog_open and not noLog: + if self.ttylog_open and not noLog: ttylog.ttylog_write(transport.ttylog_file, len(data), ttylog.TYPE_INPUT, time.time(), data) - if transport.stdinlog_open and not noLog: - f = file( transport.stdinlog_file, 'ab' ) + if self.stdinlog_open and not noLog: + log.msg( "Saving stdin log: %s" % self.stdinlog_file ) + f = file( self.stdinlog_file, 'ab' ) f.write(data) f.close insults.ServerProtocol.dataReceived(self, data) - # this is only called on explicit logout, not on disconnect + # override super to remove the terminal reset on logout + def loseConnection(self): + self.transport.loseConnection() + + # FIXME: this method is called 4 times on logout.... + # it's called once from Avatar.closed() if disconnected def connectionLost(self, reason): + # log.msg( "received call to LSP.connectionLost" ) transport = self.transport.session.conn.transport - if transport.ttylog_open: - ttylog.ttylog_close( transport.ttylog_file, time.time() ) - transport.ttylog_open = False + if self.ttylog_open: log.msg( eventid='KIPP0012', format='Closing TTY Log: %(ttylog)s', ttylog=transport.ttylog_file) - + ttylog.ttylog_close(transport.ttylog_file, time.time()) + self.ttylog_open = False insults.ServerProtocol.connectionLost(self, reason) # vim: set sw=4 et: diff --git a/kippo/core/ssh.py b/kippo/core/ssh.py index 2342fa2..4479eb2 100644 --- a/kippo/core/ssh.py +++ b/kippo/core/ssh.py @@ -21,7 +21,6 @@ from twisted.conch.ssh.common import NS, getNS import ConfigParser -import ttylog import utils import fs import sshserver @@ -224,9 +223,6 @@ class HoneyPotTransport(sshserver.KippoSSHServerTransport): if self.transport.sessionno in self.factory.sessions: 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 sshserver.KippoSSHServerTransport.connectionLost(self, reason) class HoneyPotSSHSession(session.SSHSession): @@ -251,6 +247,10 @@ class HoneyPotSSHSession(session.SSHSession): log.msg('request_x11: %s' % repr(data) ) return 0 + # this is reliably called on session close/disconnect and calls the avatar + def closed(self): + session.SSHSession.closed(self) + def loseConnection(self): self.conn.sendRequest(self, 'exit-status', "\x00"*4) session.SSHSession.loseConnection(self) @@ -268,6 +268,7 @@ class HoneyPotAvatar(avatar.ConchUser): self.env = env self.fs = fs.HoneyPotFilesystem(copy.deepcopy(self.env.fs)) self.hostname = self.env.cfg.get('honeypot', 'hostname') + self.protocol = None self.channelLookup.update({'session': HoneyPotSSHSession}) self.channelLookup['direct-tcpip'] = KippoOpenConnectForwardingClient @@ -289,6 +290,8 @@ class HoneyPotAvatar(avatar.ConchUser): self.protocol = serverProtocol serverProtocol.makeConnection(proto) proto.makeConnection(session.wrapProtocol(serverProtocol)) + #self.protocol = serverProtocol + self.protocol = proto def getPty(self, terminal, windowSize, attrs): #log.msg( 'Terminal size: %s %s' % windowSize[0:2] ) @@ -314,9 +317,13 @@ class HoneyPotAvatar(avatar.ConchUser): self.protocol = serverProtocol serverProtocol.makeConnection(proto) proto.makeConnection(session.wrapProtocol(serverProtocol)) + self.protocol = serverProtocol + # this is reliably called on both logout and disconnect + # we notify the protocol here we lost the connection def closed(self): - pass + if self.protocol: + self.protocol.connectionLost("disconnected") def eofReceived(self): pass