2016-04-17 08:55:59 +00:00
|
|
|
#!/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('<iLiiLL')
|
|
|
|
|
|
|
|
currtty, prevtime, prefdir = 0, 0, 0
|
|
|
|
sleeptime = 0.0
|
|
|
|
|
|
|
|
color = None
|
|
|
|
|
|
|
|
while 1:
|
|
|
|
try:
|
|
|
|
(op, tty, length, dir, sec, usec) = \
|
|
|
|
struct.unpack('<iLiiLL', fd.read(ssize))
|
|
|
|
data = fd.read(length)
|
|
|
|
except struct.error:
|
|
|
|
break
|
|
|
|
|
|
|
|
if currtty == 0: currtty = tty
|
|
|
|
|
|
|
|
if str(tty) == str(currtty) and op == OP_WRITE:
|
|
|
|
# the first stream seen is considered 'output'
|
|
|
|
if prefdir == 0:
|
|
|
|
prefdir = dir
|
|
|
|
if dir == TYPE_INTERACT:
|
|
|
|
color = COLOR_INTERACT
|
|
|
|
elif dir == TYPE_INPUT:
|
|
|
|
color = COLOR_INPUT
|
|
|
|
if dir == prefdir:
|
|
|
|
curtime = float(sec) + float(usec) / 1000000
|
|
|
|
if prevtime != 0:
|
|
|
|
sleeptime = curtime - prevtime
|
|
|
|
prevtime = curtime
|
|
|
|
if settings['colorify'] and color:
|
|
|
|
sys.stdout.write(color)
|
|
|
|
|
2016-07-09 13:06:31 +00:00
|
|
|
# rtrox: While playback works properly
|
|
|
|
# with the asciinema client, upload
|
|
|
|
# causes mangling of the data due to
|
|
|
|
# newlines being misinterpreted without
|
|
|
|
# carriage returns.
|
|
|
|
data = data.replace("\n", "\r\n")
|
|
|
|
|
2016-04-17 08:55:59 +00:00
|
|
|
thedata = [sleeptime, data]
|
2017-07-03 10:20:34 +00:00
|
|
|
thelog['duration'] += sleeptime
|
2016-04-17 08:55:59 +00:00
|
|
|
stdout.append(thedata)
|
2016-07-09 13:06:31 +00:00
|
|
|
|
2016-04-17 08:55:59 +00:00
|
|
|
if settings['colorify'] and color:
|
|
|
|
sys.stdout.write(COLOR_RESET)
|
|
|
|
color = None
|
|
|
|
|
|
|
|
elif str(tty) == str(currtty) and op == OP_CLOSE:
|
|
|
|
break
|
|
|
|
|
|
|
|
if settings['output'] == "":
|
|
|
|
json.dump(thelog, sys.stdout, indent=4)
|
|
|
|
else:
|
|
|
|
with open(settings['output'], "w") as outfp:
|
|
|
|
json.dump(thelog, outfp, indent=4)
|
|
|
|
|
|
|
|
|
|
|
|
def help(verbose=False):
|
|
|
|
|
2016-09-18 21:25:50 +00:00
|
|
|
print(( 'usage: %s [-c] [-o output] <tty-log-file> <tty-log-file>...' % \
|
|
|
|
os.path.basename(sys.argv[0])))
|
2016-04-17 08:55:59 +00:00
|
|
|
|
|
|
|
if verbose:
|
2016-09-18 21:25:50 +00:00
|
|
|
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')
|
2016-04-17 08:55:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
settings = {
|
|
|
|
'colorify': 0,
|
|
|
|
'output': ""
|
|
|
|
}
|
|
|
|
|
|
|
|
try:
|
|
|
|
optlist, args = getopt.getopt(sys.argv[1:], 'hco:' )
|
2016-09-18 21:25:50 +00:00
|
|
|
except getopt.GetoptError as error:
|
2016-04-17 08:55:59 +00:00
|
|
|
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()
|
2016-04-17 08:59:15 +00:00
|
|
|
sys.exit(2)
|
2016-04-17 08:55:59 +00:00
|
|
|
|
|
|
|
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))
|
|
|
|
|