diff --git a/cowrie/insults/insults.py b/cowrie/insults/insults.py index 64f0894..1613431 100644 --- a/cowrie/insults/insults.py +++ b/cowrie/insults/insults.py @@ -48,22 +48,22 @@ class LoggingServerProtocol(insults.ServerProtocol): transportId = self.transport.session.conn.transport.transportId channelId = self.transport.session.id - self.ttylog_file = '%s/tty/%s-%s-%s%s.log' % \ - (self.ttylogPath, - time.strftime('%Y%m%d-%H%M%S'), transportId, channelId, - self.type) - ttylog.ttylog_open(self.ttylog_file, time.time()) + self.startTime = time.time() + self.ttylogFile = '%s/tty/%s-%s-%s%s.log' % \ + (self.ttylogPath, time.strftime('%Y%m%d-%H%M%S'), + transportId, channelId, self.type) + ttylog.ttylog_open(self.ttylogFile, self.startTime) self.ttylog_open = True + self.ttylogSize = 0 log.msg(eventid='cowrie.log.open', - ttylog=self.ttylog_file, + ttylog=self.ttylogFile, format='Opening TTY Log: %(ttylog)s') - self.stdinlog_file = '%s/%s-%s-%s-stdin.log' % \ + self.stdinlogFile = '%s/%s-%s-%s-stdin.log' % \ (self.downloadPath, time.strftime('%Y%m%d-%H%M%S'), transportId, channelId) self.stdinlog_open = False - self.ttylogSize = 0 insults.ServerProtocol.connectionMade(self) @@ -76,9 +76,8 @@ class LoggingServerProtocol(insults.ServerProtocol): i.sessionWrite(bytes) if self.ttylog_open: - ttylog.ttylog_write(self.ttylog_file, len(bytes), + ttylog.ttylog_write(self.ttylogFile, len(bytes), ttylog.TYPE_OUTPUT, time.time(), bytes) - self.ttylogSize += len(bytes) insults.ServerProtocol.write(self, bytes) @@ -91,17 +90,16 @@ class LoggingServerProtocol(insults.ServerProtocol): self.bytesReceived += len(data) if self.bytesReceivedLimit \ and self.bytesReceived > self.bytesReceivedLimit: - log.msg(eventid='cowrie.direct-tcpip.data', - format='Data upload limit reached') + log.msg(format='Data upload limit reached') #self.loseConnection() self.eofReceived() return if self.stdinlog_open: - with open(self.stdinlog_file, 'ab') as f: + with open(self.stdinlogFile, 'ab') as f: f.write(data) elif self.ttylog_open: - ttylog.ttylog_write(self.ttylog_file, len(data), + ttylog.ttylog_write(self.ttylogFile, len(data), ttylog.TYPE_INPUT, time.time(), data) insults.ServerProtocol.dataReceived(self, data) @@ -141,23 +139,19 @@ class LoggingServerProtocol(insults.ServerProtocol): FIXME: this method is called 4 times on logout.... it's called once from Avatar.closed() if disconnected """ - log.msg("received call to LSP.connectionLost") - for i in self.interactors: i.sessionClosed() - transport = self.transport.session.conn.transport - if self.stdinlog_open: try: - with open(self.stdinlog_file, 'rb') as f: + with open(self.stdinlogFile, 'rb') as f: shasum = hashlib.sha256(f.read()).hexdigest() shasumfile = self.downloadPath + "/" + shasum if (os.path.exists(shasumfile)): - os.remove(self.stdinlog_file) + os.remove(self.stdinlogFile) else: - os.rename(self.stdinlog_file, shasumfile) - os.symlink(shasum, self.stdinlog_file) + os.rename(self.stdinlogFile, shasumfile) + os.symlink(shasum, self.stdinlogFile) log.msg(eventid='cowrie.session.file_download', format='Saved stdin contents to %(outfile)s', url='stdin', @@ -171,10 +165,11 @@ class LoggingServerProtocol(insults.ServerProtocol): if self.ttylog_open: # TODO: Add session duration to this entry log.msg(eventid='cowrie.log.closed', - format='Closing TTY Log: %(ttylog)s', - ttylog=self.ttylog_file, - size=self.ttylogSize) - ttylog.ttylog_close(self.ttylog_file, time.time()) + format='Closing TTY Log: %(ttylog)s after %(duration)d seconds', + ttylog=self.ttylogFile, + size=self.ttylogSize, + duration=time.time()-self.startTime) + ttylog.ttylog_close(self.ttylogFile, time.time()) self.ttylog_open = False insults.ServerProtocol.connectionLost(self, reason) diff --git a/cowrie/ssh/filetransfer.py b/cowrie/ssh/filetransfer.py index d245147..f4e5575 100644 --- a/cowrie/ssh/filetransfer.py +++ b/cowrie/ssh/filetransfer.py @@ -86,7 +86,7 @@ class CowrieSFTPFile(object): """ self.bytes_written += len(data) if self.bytesReceivedLimit and self.bytes_written > self.bytesReceivedLimit: - log.msg(eventid='cowrie.direct-tcpip.data', format='Data upload limit reached') + log.msg(format='Data upload limit reached') raise filetransfer.SFTPError( filetransfer.FX_FAILURE, "Quota exceeded" ) self.sftpserver.fs.lseek(self.fd, offset, os.SEEK_SET) self.sftpserver.fs.write(self.fd, data) diff --git a/cowrie/ssh/transport.py b/cowrie/ssh/transport.py index 7a785d7..60b6760 100644 --- a/cowrie/ssh/transport.py +++ b/cowrie/ssh/transport.py @@ -187,6 +187,7 @@ class HoneyPotTransport(transport.SSHServerTransport, TimeoutMixin): self.currentEncryptions = transport.SSHCiphers('none', 'none', 'none', 'none') self.currentEncryptions.setKeys('', '', '', '', '', '') self.setTimeout(120) + self.logintime = time.time() def sendKexInit(self): @@ -287,7 +288,10 @@ class HoneyPotTransport(transport.SSHServerTransport, TimeoutMixin): transport.SSHServerTransport.connectionLost(self, reason) self.transport.connectionLost(reason) self.transport = None - log.msg(eventid='cowrie.session.closed', format='Connection lost') + duration = time.time() - self.logintime + log.msg(eventid='cowrie.session.closed', + format='Connection lost after %(duration)d seconds', + duration=duration) def sendDisconnect(self, reason, desc): diff --git a/utils/asciinema.py b/utils/asciinema.py new file mode 100755 index 0000000..cfa33c8 --- /dev/null +++ b/utils/asciinema.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +import getopt +import json +import os +import sys +import struct + +OP_OPEN, OP_CLOSE, OP_WRITE, OP_EXEC = 1, 2, 3, 4 +TYPE_INPUT, TYPE_OUTPUT, TYPE_INTERACT = 1, 2, 3 + +COLOR_INTERACT = '\033[36m' +COLOR_INPUT = '\033[33m' +COLOR_RESET = '\033[0m' + +def playlog(fd, settings): + + thelog = {} + thelog['version'] = 1 + thelog['width'] = 80 + thelog['height'] = 24 + thelog['duration'] = 0.0 + thelog['command'] = "/bin/bash" + thelog['title'] = "Cowrie Recording" + theenv = {} + theenv['TERM'] = "xterm256-color" + theenv['SHELL'] = "/bin/bash" + thelog["env"] = theenv + stdout = [] + thelog["stdout"] = stdout + + ssize = struct.calcsize(' ...' % \ + os.path.basename(sys.argv[0]) + + if verbose: + print ' -c colorify the output based on what streams are being received' + print ' -h display this help' + print ' -o write to the specified output file' + + +if __name__ == '__main__': + + settings = { + 'colorify': 0, + 'output': "" + } + + try: + optlist, args = getopt.getopt(sys.argv[1:], 'hco:' ) + except getopt.GetoptError, error: + sys.stderr.write( '{}: {}\n'.format(sys.argv[0], error)) + help() + sys.exit(1) + + for o, a in optlist: + if o == '-h': help() + if o == '-c': settings['colorify'] = True + if o == '-o': settings['output'] = a + + if len(args)<1: + help() + sys.exit(2) + + for logfile in args: + try: + logfd = open(logfile, 'rb') + playlog(logfd, settings) + except IOError as e: + sys.stderr.write( "{}: {}\n".format(sys.argv[0], e)) +