diff --git a/.travis.yml b/.travis.yml index b49f776f..181b3bc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: pip install -r requirements.txt before_script: - pip install flake8 twistedchecker # pytest # add another testing frameworks later # stop the build if there are Python syntax errors or undefined names - - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics + - flake8 . --count --select=E1,E2,E901,E999,F821,F822,F823 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide # ignore E3xx errors, Twisted has different empty line convention - flake8 . --count --ignore=E3 --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/cowrie/commands/apt.py b/cowrie/commands/apt.py index 8f6a7fe4..a6458924 100644 --- a/cowrie/commands/apt.py +++ b/cowrie/commands/apt.py @@ -39,7 +39,7 @@ class command_aptget(HoneyPotCommand): else: self.do_locked() - def sleep(self, time, time2 = None): + def sleep(self, time, time2=None): d = defer.Deferred() if time2: time = random.randint(time * 100, time2 * 100) / 100.0 @@ -110,20 +110,18 @@ pages for more information and options. return @inlineCallbacks - def do_install(self,*args): + def do_install(self, *args): if len(self.args) <= 1: - self.write('0 upgraded, 0 newly installed, 0 to remove and %s not upgraded.\n' % random.randint(200,300)) + msg = '0 upgraded, 0 newly installed, 0 to remove and {0} not upgraded.\n' + self.write(msg.format(random.randint(200, 300))) self.exit() return packages = {} for y in [re.sub('[^A-Za-z0-9]', '', x) for x in self.args[1:]]: packages[y] = { - 'version': '%d.%d-%d' % - (random.choice((0, 1)), - random.randint(1, 40), - random.randint(1, 10)), - 'size': random.randint(100, 900) + 'version': '{0}.{1}-{2}'.format(random.choice(0, 1), random.randint(1, 40), random.randint(1, 10)), + 'size': random.randint(100, 900) } totalsize = sum([packages[x]['size'] for x in packages]) diff --git a/cowrie/commands/base.py b/cowrie/commands/base.py index 231ecb04..28e11ba4 100644 --- a/cowrie/commands/base.py +++ b/cowrie/commands/base.py @@ -26,7 +26,7 @@ class command_whoami(HoneyPotCommand): def call(self): """ """ - self.write(self.protocol.user.username+'\n') + self.write('{0}\n'.format(self.protocol.user.username)) commands['/usr/bin/whoami'] = command_whoami commands['/usr/bin/users'] = command_whoami @@ -112,7 +112,7 @@ class command_who(HoneyPotCommand): """ self.write('%-8s pts/0 %s %s (%s)\n' % (self.protocol.user.username, - time.strftime('%Y-%m-%d',time.localtime(self.protocol.logintime)), + time.strftime('%Y-%m-%d', time.localtime(self.protocol.logintime)), time.strftime('%H:%M', time.localtime(self.protocol.logintime)), self.protocol.clientIP)) commands['/usr/bin/who'] = command_who @@ -243,7 +243,7 @@ class command_hostname(HoneyPotCommand): else: self.write("hostname: you must be root to change the host name\n") else: - self.write(self.protocol.hostname+'\n') + self.write('{0}\n'.format(self.protocol.hostname)) commands['/bin/hostname'] = command_hostname @@ -310,7 +310,7 @@ class command_ps(HoneyPotCommand): s = ''.join([output[i][x] for x in l]) if 'w' not in args: s = s[:80] - self.write(s+'\n') + self.write('{0}\n'.format(s)) commands['/bin/ps'] = command_ps @@ -399,7 +399,7 @@ class command_shutdown(HoneyPotCommand): "** the \"time\" argument is mandatory! (try \"now\") **", ) for l in output: - self.write(l+'\n') + self.write('{0}\n'.format(l)) self.exit() elif len(self.args) > 1 and self.args[0].strip().count('-h') \ and self.args[1].strip().count('now'): @@ -492,7 +492,7 @@ class command_date(HoneyPotCommand): """ """ time = datetime.datetime.utcnow() - self.write(time.strftime("%a %b %d %H:%M:%S UTC %Y")+'\n') + self.write('{0}\n'.format(time.strftime("%a %b %d %H:%M:%S UTC %Y"))) commands['/bin/date'] = command_date class command_yes(HoneyPotCommand): @@ -508,7 +508,7 @@ class command_yes(HoneyPotCommand): """ """ if len(self.args): - self.write(' '.join(self.args)+'\n') + self.write("{0}{1}".format(' '.join(self.args, '\n'))) else: self.write('y\n') self.scheduled = reactor.callLater(0.01, self.y) @@ -593,7 +593,7 @@ class command_php(HoneyPotCommand): 'Copyright (c) 1997-2010 The PHP Group' ) for l in output: - self.write(l+'\n') + self.write('{0}\n'.format(l)) self.exit() elif self.args[0] == '-h': output = ( @@ -637,7 +637,7 @@ class command_php(HoneyPotCommand): '' ) for l in output: - self.write(l+'\n') + self.write('{0}\n'.format(l)) self.exit() else: self.exit() diff --git a/cowrie/commands/busybox.py b/cowrie/commands/busybox.py index aafe5d5e..26d70cbd 100644 --- a/cowrie/commands/busybox.py +++ b/cowrie/commands/busybox.py @@ -3,12 +3,12 @@ from __future__ import division, absolute_import -from cowrie.shell.honeypot import HoneyPotCommand,StdOutStdErrEmulationProtocol +from cowrie.shell.honeypot import HoneyPotCommand, StdOutStdErrEmulationProtocol from twisted.python import log commands = {} -busybox_help=(''' +busybox_help = (''' BusyBox v1.20.2 (Debian 1:1.20.0-7) multi-call binary. Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko and others. Licensed under GPLv2. @@ -59,7 +59,7 @@ class command_busybox(HoneyPotCommand): """ """ for ln in busybox_help: - self.errorWrite(ln+'\n') + self.errorWrite('{0}\n'.format(ln)) def call(self): diff --git a/cowrie/commands/cat.py b/cowrie/commands/cat.py index 93ecfeb3..c508042b 100644 --- a/cowrie/commands/cat.py +++ b/cowrie/commands/cat.py @@ -76,7 +76,7 @@ class command_cat(HoneyPotCommand): if self.number: self.write("{:>6} ".format(self.linenumber)) self.linenumber = self.linenumber + 1 - self.write(line+"\n") + self.write("{0}\n".format(line)) def lineReceived(self, line): diff --git a/cowrie/commands/curl.py b/cowrie/commands/curl.py index 06bb772e..69811e73 100644 --- a/cowrie/commands/curl.py +++ b/cowrie/commands/curl.py @@ -82,7 +82,7 @@ class command_curl(HoneyPotCommand): self.exit() return - url=url.encode('ascii') + url = url.encode('ascii') self.url = url self.limit_size = 0 if CONFIG.has_option('honeypot', 'download_limit_size'): @@ -291,7 +291,7 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only contextFactory = ssl.ClientContextFactory() contextFactory.method = SSL.SSLv23_METHOD reactor.connectSSL(host, port, factory, contextFactory, bindAddress=out_addr) - else: # Can only be http + else: # Can only be http self.connection = reactor.connectTCP( host, port, factory, bindAddress=out_addr) @@ -346,12 +346,9 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only def error(self, error, url): """ """ - if hasattr(error, 'getErrorMessage'): # Exceptions + if hasattr(error, 'getErrorMessage'): # Exceptions error = error.getErrorMessage() - self.write(error+'\n') - # Real curl also adds this: - # self.write('%s ERROR 404: Not Found.\n' % \ - # time.strftime('%Y-%m-%d %T')) + self.write('{0}\n'.format(error)) self.protocol.logDispatch(eventid='cowrie.session.file_download.failed', format='Attempt to download file(s) from URL (%(url)s) failed', url=self.url) @@ -380,8 +377,9 @@ class HTTPProgressDownloader(client.HTTPDownloader): self.nomore = False - def noPage(self, reason): # Called for non-200 responses + def noPage(self, reason): """ + Called for non-200 responses """ if self.status == '304': client.HTTPDownloader.page(self, '') @@ -434,10 +432,10 @@ class HTTPProgressDownloader(client.HTTPDownloader): if (time.time() - self.lastupdate) < 0.5: return client.HTTPDownloader.pagePart(self, data) if self.totallength: - percent = (self.currentlength/self.totallength)*100 - spercent = "%i%%" % (percent,) + percent = (self.currentlength / self.totallength) * 100 + spercent = "{0}%%".format(percent) else: - spercent = '%dK' % (self.currentlength/1000) + spercent = '{0}K'.format(self.currentlength / 1000) percent = 0 self.speed = self.currentlength / (time.time() - self.started) self.lastupdate = time.time() @@ -461,7 +459,7 @@ class HTTPProgressDownloader(client.HTTPDownloader): self.curl.safeoutfile) else: with open(self.curl.safeoutfile, 'r') as f: - self.curl.write(f.read()+'\n') + self.curl.write('{0}\n'.format(f.read())) self.curl.fileName = self.fileName return client.HTTPDownloader.pageEnd(self) diff --git a/cowrie/commands/env.py b/cowrie/commands/env.py index 1e81dc60..d2ea48b1 100644 --- a/cowrie/commands/env.py +++ b/cowrie/commands/env.py @@ -38,7 +38,7 @@ class command_env(HoneyPotCommand): """ """ for i in list(self.environ.keys()): - self.write(b"%s=%s\n" % (i,self.environ[i])) + self.write(b'{0}={1}\n'.format(i, self.environ[i])) commands['/usr/bin/env'] = command_env diff --git a/cowrie/commands/free.py b/cowrie/commands/free.py index 3df7471d..133c9876 100644 --- a/cowrie/commands/free.py +++ b/cowrie/commands/free.py @@ -13,17 +13,17 @@ from cowrie.shell.honeypot import HoneyPotCommand commands = {} -FREE_BYTES=""" total used free shared buffers cached +FREE_BYTES = """ total used free shared buffers cached Mem: 8069256 7872920 196336 0 410340 5295748 -/+ buffers/cache: 2166832 5902424 Swap: 3764220 133080 3631140""" -FREE_MEGA=""" total used free shared buffers cached +FREE_MEGA = """ total used free shared buffers cached Mem: 7880 7690 189 0 400 5171 -/+ buffers/cache: 2118 5761 Swap: 3675 129 3546""" -FREE_HUMAN=""" total used free shared buffers cached +FREE_HUMAN = """ total used free shared buffers cached Mem: 7.7G 7.5G 189M 0B 400M 5.1G -/+ buffers/cache: 2.1G 5.6G Swap: 3.6G 129M 3.5G""" @@ -57,12 +57,12 @@ class command_free(HoneyPotCommand): """ print free statistics """ - if fmt=='bytes': - self.write(FREE_BYTES+'\n') - elif fmt=='megabytes': - self.write(FREE_MEGA+'\n') - elif fmt=='human': - self.write(FREE_HUMAN+'\n') + if fmt == 'bytes': + self.write('{0}\n'.format(FREE_BYTES)) + elif fmt == 'megabytes': + self.write('{0}\n'.format(FREE_MEGA)) + elif fmt == 'human': + self.write('{0}\n'.format(FREE_HUMAN)) commands['/usr/bin/free'] = command_free diff --git a/cowrie/commands/fs.py b/cowrie/commands/fs.py index e04686fb..cb922488 100644 --- a/cowrie/commands/fs.py +++ b/cowrie/commands/fs.py @@ -33,7 +33,7 @@ class command_grep(HoneyPotCommand): def grep_application(self, contents, match): match = path.basename(match) - match = match.replace("\"","") + match = match.replace("\"", "") contentsplit = contents.split('\n') matches = re.compile(".*" + match + ".*") for line in contentsplit: @@ -42,10 +42,10 @@ class command_grep(HoneyPotCommand): def help(self): - self.write( 'usage: grep [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]]\n') - self.write( '\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n') - self.write( '\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n') - self.write( '\t[--null] [pattern] [file ...]\n') + self.write('usage: grep [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]]\n') + self.write('\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n') + self.write('\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n') + self.write('\t[--null] [pattern] [file ...]\n') def start(self): diff --git a/cowrie/commands/gcc.py b/cowrie/commands/gcc.py index 1cab3f60..9ba0f29e 100644 --- a/cowrie/commands/gcc.py +++ b/cowrie/commands/gcc.py @@ -18,7 +18,7 @@ commands = {} class command_gcc(HoneyPotCommand): # Name of program. Under OSX, you might consider i686-apple-darwin11-llvm-gcc-X.X - APP_NAME = "gcc" + APP_NAME = "gcc" # GCC verson, used in help, version and the commandline name gcc-X.X APP_VERSION = (4, 7, 2) @@ -163,7 +163,7 @@ Thread model: posix gcc version %s (Debian %s-5)""" % (version, version_short, version_short, version_short, version, version)) # Write - self.write(data+'\n') + self.write('{0}\n'.format(data)) self.exit() def generate_file(self, outfile): diff --git a/cowrie/commands/ifconfig.py b/cowrie/commands/ifconfig.py index 443614c6..81d49b54 100644 --- a/cowrie/commands/ifconfig.py +++ b/cowrie/commands/ifconfig.py @@ -31,7 +31,7 @@ lo Link encap:Local Loopback RX bytes:19932 (19.9 KB) TX bytes:19932 (19.9 KB)""" % \ (self.protocol.kippoIP, self.protocol.kippoIP.rsplit('.', 1)[0]) - self.write(l+'\n') + self.write('{0}\n'.format(l)) commands['/sbin/ifconfig'] = command_ifconfig diff --git a/cowrie/commands/iptables.py b/cowrie/commands/iptables.py index 46f48dae..219e4f69 100644 --- a/cowrie/commands/iptables.py +++ b/cowrie/commands/iptables.py @@ -66,13 +66,13 @@ class command_iptables(HoneyPotCommand): # Utils def optional_arg(arg_default): - def func(option,opt_str,value,parser): + def func(option, opt_str, value, parser): if parser.rargs and not parser.rargs[0].startswith('-'): - val=parser.rargs[0] + val = parser.rargs[0] parser.rargs.pop(0) else: - val=arg_default - setattr(parser.values,option.dest,val) + val = arg_default + setattr(parser.values, option.dest, val) return func # Initialize options @@ -317,7 +317,7 @@ Options: output.append("-P %s ACCEPT" % chain) # Done - self.write("\n".join(output)+'\n') + self.write('{0}\n'.format('\n'.join(output))) self.exit() else: self.no_permission() @@ -356,7 +356,7 @@ Options: output.append("\n".join(chain_output)) # Done - self.write("\n\n".join(output)+'\n') + self.write("{0}\n".format('\n\n'.join(output))) self.exit() else: self.no_permission() diff --git a/cowrie/commands/last.py b/cowrie/commands/last.py index 9ec48175..30711505 100644 --- a/cowrie/commands/last.py +++ b/cowrie/commands/last.py @@ -27,13 +27,13 @@ class command_last(HoneyPotCommand): numlines = int(l.pop(0)) self.write('%-8s %-12s %-16s %s still logged in\n' % - (self.protocol.user.username,"pts/0", self.protocol.clientIP, + (self.protocol.user.username, "pts/0", self.protocol.clientIP, time.strftime('%a %b %d %H:%M', time.localtime(self.protocol.logintime)))) self.write("\n") self.write("wtmp begins %s\n" % time.strftime('%a %b %d %H:%M:%S %Y', - time.localtime(self.protocol.logintime // (3600*24) * (3600*24) + 63 )) ) + time.localtime(self.protocol.logintime // (3600 * 24) * (3600 * 24) + 63))) commands['/usr/bin/last'] = command_last diff --git a/cowrie/commands/ls.py b/cowrie/commands/ls.py index 63d4e5ac..864b2f83 100644 --- a/cowrie/commands/ls.py +++ b/cowrie/commands/ls.py @@ -186,7 +186,7 @@ class command_ls(HoneyPotCommand): file[A_NAME], linktarget) - self.write(l+'\n') + self.write('{0}\n'.format(l)) commands['/bin/ls'] = command_ls commands['/bin/dir'] = command_ls diff --git a/cowrie/commands/netstat.py b/cowrie/commands/netstat.py index a6261916..579b8613 100644 --- a/cowrie/commands/netstat.py +++ b/cowrie/commands/netstat.py @@ -72,8 +72,8 @@ Destination Gateway Genmask Flags MSS Window irtt Iface\n l2 = "%s%s255.255.255.0 U 0 0 0 eth0" % \ ('{:<16}'.format(destination), '{:<16}'.format(lgateway)) - self.write(l1+'\n') - self.write(l2+'\n') + self.write('{0}\n'.format(l1)) + self.write('{0}\n'.format(l2)) def do_netstat_normal(self): self.write("""Active Internet connections (w/o servers) @@ -94,10 +94,10 @@ Proto Recv-Q Send-Q Local Address Foreign Address State\n""") self.write("tcp 0 0 *:ssh *:* LISTEN\n") if not self.show_listen or self.show_all: l = 'tcp 0 308 %s:%s%s%s:%s%s%s' % \ - (s_name, s_port, " "*(24-len(s_name+s_port)-1), - c_name, c_port, " "*(24-len(c_name+c_port)-1), + (s_name, s_port, " " * (24 - len(s_name + s_port) - 1), + c_name, c_port, " " * (24 - len(c_name + c_port) - 1), "ESTABLISHED") - self.write(l+'\n') + self.write('{0}\n'.format(l)) if self.show_listen or self.show_all: self.write("tcp6 0 0 [::]:ssh [::]:* LISTEN\n") self.write("""Active UNIX domain sockets (only servers) diff --git a/cowrie/commands/ping.py b/cowrie/commands/ping.py index f68bb5eb..0c91cdb7 100644 --- a/cowrie/commands/ping.py +++ b/cowrie/commands/ping.py @@ -54,14 +54,14 @@ class command_ping(HoneyPotCommand): self.exit() return - if len(args)==0: + if len(args) == 0: for l in ( 'Usage: ping [-LRUbdfnqrvVaA] [-c count] [-i interval] [-w deadline]', ' [-p pattern] [-s packetsize] [-t ttl] [-I interface or address]', ' [-M mtu discovery hint] [-S sndbuf]', ' [ -T timestamp option ] [ -Q tos ] [hop1 ...] destination', ): - self.write(l+'\n') + self.write('{0}\n'.format(l)) self.exit() return self.host = args[0].strip() diff --git a/cowrie/commands/python.py b/cowrie/commands/python.py index e9889e44..2d651f45 100644 --- a/cowrie/commands/python.py +++ b/cowrie/commands/python.py @@ -80,7 +80,7 @@ class command_python(HoneyPotCommand): try: opts, args = getopt.gnu_getopt(self.args, 'BdEhiORsStuvVx3c:m:Q:W:', ['help', 'version']) except getopt.GetoptError as err: - self.write("Unknown option: -" + err.opt + "\n") + self.write("Unknown option: -{0}\n".format(err.opt)) self.write("usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... \n") self.write("Try `python -h' for more information.\n") self.exit() diff --git a/cowrie/commands/scp.py b/cowrie/commands/scp.py index 0d3e7ec0..2af1c489 100644 --- a/cowrie/commands/scp.py +++ b/cowrie/commands/scp.py @@ -232,7 +232,7 @@ class command_scp(HoneyPotCommand): data = f.read() header = data[:data.find('\n')] if re.match('C0[\d]{3} [\d]+ [^\s]+', header): - data = data[data.find('\n')+1:] + data = data[data.find('\n') + 1:] else: data = '' diff --git a/cowrie/commands/ssh.py b/cowrie/commands/ssh.py index 785c737d..bc8389b3 100644 --- a/cowrie/commands/ssh.py +++ b/cowrie/commands/ssh.py @@ -55,7 +55,7 @@ class command_ssh(HoneyPotCommand): ' [-R [bind_address:]port:host:hostport] [-S ctl_path]', ' [-w local_tun[:remote_tun]] [user@]hostname [command]', ): - self.write(l+'\n') + self.write('{0}\n'.format(l)) self.exit() return user, host = 'root', args[0] diff --git a/cowrie/commands/sudo.py b/cowrie/commands/sudo.py index 894dd67e..5c65e308 100644 --- a/cowrie/commands/sudo.py +++ b/cowrie/commands/sudo.py @@ -6,11 +6,11 @@ import getopt from twisted.python import log -from cowrie.shell.honeypot import HoneyPotCommand,StdOutStdErrEmulationProtocol +from cowrie.shell.honeypot import HoneyPotCommand, StdOutStdErrEmulationProtocol commands = {} -sudo_shorthelp=(''' +sudo_shorthelp = (''' sudo: Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified usage: sudo [-D level] -h | -K | -k | -V usage: sudo -v [-AknS] [-D level] [-g groupname|#gid] [-p prompt] [-u user name|#uid] @@ -19,7 +19,7 @@ usage: sudo [-AbEHknPS] [-r role] [-t type] [-C fd] [-D level] [-g groupname|#gi usage: sudo -e [-AknS] [-r role] [-t type] [-C fd] [-D level] [-g groupname|#gid] [-p prompt] [-u user name|#uid] file ... ''').strip().split('\n') -sudo_longhelp=(''' +sudo_longhelp = (''' sudo - execute a command as another user usage: sudo [-D level] -h | -K | -k | -V @@ -63,7 +63,7 @@ class command_sudo(HoneyPotCommand): """ """ for ln in sudo_shorthelp: - self.errorWrite(ln+'\n') + self.errorWrite('{0}\n'.format(ln)) self.exit() @@ -71,7 +71,7 @@ class command_sudo(HoneyPotCommand): """ """ for ln in sudo_longhelp: - self.errorWrite(ln+'\n') + self.errorWrite('{0}\n'.format(ln)) self.exit() @@ -92,13 +92,13 @@ class command_sudo(HoneyPotCommand): """ start_value = None parsed_arguments = [] - for count in range(0,len(self.args)): - class_found = self.protocol.getCommand(self.args[count], self.environ['PATH'].split(':')) + for count in range(0, len(self.args)): + class_found = self.protocol.getCommand(self.args[count], self.environ['PATH'].split(':')) if class_found: start_value = count break if start_value is not None: - for index_2 in range(start_value,len(self.args)): + for index_2 in range(start_value, len(self.args)): parsed_arguments.append(self.args[index_2]) try: @@ -122,10 +122,7 @@ class command_sudo(HoneyPotCommand): cmdclass = self.protocol.getCommand(cmd, self.environ['PATH'].split(':')) if cmdclass: - #log.msg(eventid='cowrie.command.success', - # input=line, - # format='Command found: %(input)s') - command = StdOutStdErrEmulationProtocol(self.protocol,cmdclass,parsed_arguments[1:], None ,None) + command = StdOutStdErrEmulationProtocol(self.protocol, cmdclass, parsed_arguments[1:], None, None) self.protocol.pp.insert_command(command) # this needs to go here so it doesn't write it out.... if self.input_data: diff --git a/cowrie/commands/tar.py b/cowrie/commands/tar.py index b68f3832..a2048687 100644 --- a/cowrie/commands/tar.py +++ b/cowrie/commands/tar.py @@ -72,7 +72,7 @@ class command_tar(HoneyPotCommand): for f in t: dest = self.fs.resolve_path(f.name.strip('/'), self.protocol.cwd) if verbose: - self.write(f.name+'\n') + self.write('{0}\n'.format(f.name)) if not extract or not len(dest): continue if f.isdir(): diff --git a/cowrie/core/dblog.py b/cowrie/core/dblog.py index 85c1cd5d..159387da 100644 --- a/cowrie/core/dblog.py +++ b/cowrie/core/dblog.py @@ -23,8 +23,6 @@ class DBLogger(object): self.sessions = {} self.ttylogs = {} # FIXME figure out what needs to be done here regarding - # HoneyPotTransport renamed to HoneyPotSSHTransport - #:* Handles ipv6 self.re_sessionlog = re.compile( r'.*HoneyPotSSHTransport,([0-9]+),[:a-f0-9.]+$') diff --git a/cowrie/core/output.py b/cowrie/core/output.py index bff9bb2b..b9d55c4e 100644 --- a/cowrie/core/output.py +++ b/cowrie/core/output.py @@ -168,14 +168,6 @@ class Output(object): except: pass - # On disconnect add the tty log - #if ev['eventid'] == 'cowrie.log.closed': - # FIXME: file is read for each output plugin - #f = file(ev['ttylog']) - #ev['ttylog'] = f.read(10485760) - #f.close() - #pass - # Explicit sessionno (from logDispatch) overrides from 'system' if 'sessionno' in ev: sessionno = ev['sessionno'] @@ -185,11 +177,11 @@ class Output(object): sessionno = 0 telnetmatch = self.telnetRegex.match(ev['system']) if telnetmatch: - sessionno = 'T'+str(telnetmatch.groups()[0]) + sessionno = 'T'.format(telnetmatch.groups()[0]) else: sshmatch = self.sshRegex.match(ev['system']) if sshmatch: - sessionno = 'S'+str(sshmatch.groups()[0]) + sessionno = 'S'.format(sshmatch.groups()[0]) if sessionno == 0: return diff --git a/cowrie/core/realm.py b/cowrie/core/realm.py index 0a314e26..7b7a46ff 100644 --- a/cowrie/core/realm.py +++ b/cowrie/core/realm.py @@ -58,25 +58,10 @@ class HoneyPotRealm(object): def __init__(self): pass - # self.servers = {} - def requestAvatar(self, avatarId, mind, *interfaces): """ """ - - # if mind in self.servers: - # log.msg( "Using existing server for mind %s" % mind) - # for i in self.servers[mind].avatars: - # log.msg( "attached avatar: %s" % repr(i)) - #else: - # log.msg( "Starting new server for mind %s" % mind) - # self.servers[mind] = server.CowrieServer(self.cfg) - - # for i in list(self.servers.keys()): - # log.msg( "REFCOUNT: key: %s, refcount %d" % ( i, sys.getrefcount(self.servers[i]))) - # log.msg( "Refer: %s" % repr( gc.get_referrers(self.servers[i]))) - try: backend = CONFIG.get('honeypot', 'backend') except: diff --git a/cowrie/core/utils.py b/cowrie/core/utils.py index 34e8c74e..7691613a 100644 --- a/cowrie/core/utils.py +++ b/cowrie/core/utils.py @@ -32,16 +32,16 @@ def durationHuman(seconds): duration = [] if years > 0: - duration.append('{} year'.format(syears) + 's'*(years != 1) + ' ') + duration.append('{0} year{1} '.format(syears, 's' * (years != 1))) else: if days > 0: - duration.append('{} day'.format(days) + 's'*(days != 1) + ' ') + duration.append('{0} day{1} '.format(days, 's' * (days != 1))) if hours > 0: - duration.append('{}:'.format(shours)) + duration.append('{0}:'.format(shours)) if minutes >= 0: - duration.append('{}:'.format(sminutes)) + duration.append('{0}:'.format(sminutes)) if seconds >= 0: - duration.append('{}'.format(sseconds)) + duration.append('{0}'.format(sseconds)) return ''.join(duration) @@ -54,9 +54,9 @@ def tail(the_file, lines_2find=20): the_file.seek(0, 2) bytes_in_file = the_file.tell() lines_found, total_bytes_scanned = 0, 0 - while lines_2find+1 > lines_found and bytes_in_file > total_bytes_scanned: - byte_block = min(1024, bytes_in_file-total_bytes_scanned) - the_file.seek(-(byte_block+total_bytes_scanned), 2) + while lines_2find + 1 > lines_found and bytes_in_file > total_bytes_scanned: + byte_block = min(1024, bytes_in_file - total_bytes_scanned) + the_file.seek(-(byte_block + total_bytes_scanned), 2) total_bytes_scanned += byte_block lines_found += the_file.read(1024).count('\n') the_file.seek(-total_bytes_scanned, 2) diff --git a/cowrie/dblog/xmpp.py b/cowrie/dblog/xmpp.py index a012d3ea..0c432a72 100644 --- a/cowrie/dblog/xmpp.py +++ b/cowrie/dblog/xmpp.py @@ -17,13 +17,13 @@ class XMPPLoggerProtocol(muc.MUCClient): def __init__(self, rooms, server, nick): muc.MUCClient.__init__(self) - self.server = rooms.host + self.server = rooms.host self.jrooms = rooms self._roomOccupantMap = {} log.msg(rooms.user) log.msg(rooms.host) - self.nick = nick - self.last = {} + self.nick = nick + self.last = {} self.activity = None def connectionInitialized(self): @@ -35,13 +35,13 @@ class XMPPLoggerProtocol(muc.MUCClient): log.msg('Joined room %s' % room.name) def connectionMade(self): - log.msg('Connected!' ) + log.msg('Connected!') # send initial presence self.send(AvailablePresence()) def connectionLost(self, reason): - log.msg('Disconnected!' ) + log.msg('Disconnected!') def onMessage(self, msg): pass @@ -63,10 +63,10 @@ class DBLogger(dblog.DBLogger): from random import choice import string - server = CONFIG.get('database_xmpp', 'server') - user = CONFIG.get('database_xmpp', 'user') - password = CONFIG.get('database_xmpp', 'password') - muc = CONFIG.get('database_xmpp', 'muc') + server = CONFIG.get('database_xmpp', 'server') + user = CONFIG.get('database_xmpp', 'user') + password = CONFIG.get('database_xmpp', 'password') + muc = CONFIG.get('database_xmpp', 'muc') channels = {} for i in ('createsession', 'connectionlost', 'loginfailed', 'loginsucceeded', 'command', 'clientversion'): @@ -78,14 +78,14 @@ class DBLogger(dblog.DBLogger): resource = ''.join([choice(string.ascii_letters) for i in range(8)]) jid = user + '/' + resource application = service.Application('honeypot') - self.run(application, jid, password, JID(None,[muc,server,None]), channels) + self.run(application, jid, password, JID(None, [muc, server, None]), channels) def run(self, application, jidstr, password, muc, channels, anon=True): self.xmppclient = XMPPClient(JID(jidstr), password) if CONFIG.has_option('database_xmpp', 'debug') and \ CONFIG.getboolean('database_xmpp', 'debug') == True: - self.xmppclient.logTraffic = True # DEBUG HERE + self.xmppclient.logTraffic = True # DEBUG HERE (user, host, resource) = jid.parse(jidstr) self.muc = XMPPLoggerProtocol( muc, list(channels.keys()), user + '-' + resource) @@ -100,13 +100,13 @@ class DBLogger(dblog.DBLogger): def broadcast(self, msgtype, msg): if msgtype in self.signals: - self.report(msgtype, '%s@%s' % (self.signals[msgtype], self.muc.server) , msg) + self.report(msgtype, '{}@{}'.format(self.signals[msgtype], self.muc.server), msg) def report(self, msgtype, to, xmsg): msg = {} msg['type'] = msgtype msg['message'] = xmsg - msgJson = json.dumps(msg,indent=5) + msgJson = json.dumps(msg, indent=5) self.muc.groupChat(self.muc.jrooms, msgJson) # We have to return an unique ID @@ -158,7 +158,7 @@ class DBLogger(dblog.DBLogger): ses = {} ses['session'] = session ses['command'] = 'unknown' - ses['input'] = args['input'] + ses['input'] = args['input'] self.broadcast('command', ses) def handleInput(self, session, args): diff --git a/cowrie/insults/insults.py b/cowrie/insults/insults.py index f00e17bf..2199004c 100644 --- a/cowrie/insults/insults.py +++ b/cowrie/insults/insults.py @@ -48,9 +48,9 @@ class LoggingServerProtocol(insults.ServerProtocol): self.bytesReceivedLimit = 0 if prot is protocol.HoneyPotExecProtocol: - self.type = 'e' # Execcmd + self.type = 'e' # Execcmd else: - self.type = 'i' # Interactive + self.type = 'i' # Interactive def getSessionId(self): @@ -83,7 +83,7 @@ class LoggingServerProtocol(insults.ServerProtocol): if self.type == 'e': self.stdinlogOpen = True - else: #i + else: self.stdinlogOpen = False insults.ServerProtocol.connectionMade(self) @@ -112,7 +112,6 @@ class LoggingServerProtocol(insults.ServerProtocol): self.bytesReceived += len(data) if self.bytesReceivedLimit and self.bytesReceived > self.bytesReceivedLimit: log.msg(format='Data upload limit reached') - #self.loseConnection() self.eofReceived() return @@ -178,7 +177,7 @@ class LoggingServerProtocol(insults.ServerProtocol): if rp[1]: url = rp[1] else: - url = rf[rf.find('redir_')+len('redir_'):] + url = rf[rf.find('redir_') + len('redir_'):] try: if not os.path.exists(rf): @@ -212,7 +211,7 @@ class LoggingServerProtocol(insults.ServerProtocol): format='Closing TTY Log: %(ttylog)s after %(duration)d seconds', ttylog=self.ttylogFile, size=self.ttylogSize, - duration=time.time()-self.startTime) + duration=time.time() - self.startTime) ttylog.ttylog_close(self.ttylogFile, time.time()) self.ttylogOpen = False diff --git a/cowrie/output/dshield.py b/cowrie/output/dshield.py index 00478df7..48a2a878 100644 --- a/cowrie/output/dshield.py +++ b/cowrie/output/dshield.py @@ -36,7 +36,7 @@ class Output(cowrie.core.output.Output): def start(self): - self.batch = [] # This is used to store login attempts in batches + self.batch = [] # This is used to store login attempts in batches def stop(self): @@ -47,12 +47,12 @@ class Output(cowrie.core.output.Output): if entry["eventid"] == 'cowrie.login.success' or entry["eventid"] == 'cowrie.login.failed': date = dateutil.parser.parse(entry["timestamp"]) self.batch.append({ - 'date' : date.date().__str__(), - 'time' : date.time().strftime("%H:%M:%S"), - 'timezone' : time.strftime("%z"), - 'source_ip' : entry['src_ip'], - 'user' : entry['username'], - 'password' : entry['password'], + 'date': date.date().__str__(), + 'time': date.time().strftime("%H:%M:%S"), + 'timezone': time.strftime("%z"), + 'source_ip': entry['src_ip'], + 'user': entry['username'], + 'password': entry['password'], }) if len(self.batch) >= self.batch_size: @@ -99,20 +99,19 @@ class Output(cowrie.core.output.Output): auth_header = 'credentials={0} nonce={1} userid={2}'.format(digest, _nonceb64, self.userid) headers = { 'X-ISC-Authorization': auth_header, - 'Content-Type':'text/plain' + 'Content-Type': 'text/plain' } - #log.msg(headers) if self.debug: log.msg('dshield: posting: {}'.format(log_output)) req = threads.deferToThread( requests.request, - method ='PUT', - url = 'https://secure.dshield.org/api/file/sshlog', - headers = headers, - timeout = 10, - data = log_output + method='PUT', + url='https://secure.dshield.org/api/file/sshlog', + headers=headers, + timeout=10, + data=log_output ) @@ -129,7 +128,7 @@ class Output(cowrie.core.output.Output): sha1_match = sha1_regex.search(response) if sha1_match is None: log.err('dshield: ERROR: Could not find sha1checksum in response') - log.err('dshield: ERROR: Response: '+repr(response)) + log.err('dshield: ERROR: Response: {0}'.format(repr(response))) failed = True sha1_local = hashlib.sha1() sha1_local.update(log_output) diff --git a/cowrie/output/elasticsearch.py b/cowrie/output/elasticsearch.py index cbedb291..a1294103 100644 --- a/cowrie/output/elasticsearch.py +++ b/cowrie/output/elasticsearch.py @@ -19,7 +19,7 @@ class Output(cowrie.core.output.Output): """ self.host = CONFIG.get('output_elasticsearch', 'host') self.port = CONFIG.get('output_elasticsearch', 'port') - self.index =CONFIG.get('output_elasticsearch', 'index') + self.index = CONFIG.get('output_elasticsearch', 'index') self.type = CONFIG.get('output_elasticsearch', 'type') self.pipeline = CONFIG.get('output_elasticsearch', 'pipeline') cowrie.core.output.Output.__init__(self) diff --git a/cowrie/output/hpfeeds.py b/cowrie/output/hpfeeds.py index ee399ee7..b3183fea 100644 --- a/cowrie/output/hpfeeds.py +++ b/cowrie/output/hpfeeds.py @@ -30,19 +30,19 @@ From https://github.com/threatstream/kippo/blob/master/kippo/dblog/hpfeeds.py BUFSIZ = 16384 -OP_ERROR = 0 -OP_INFO = 1 -OP_AUTH = 2 -OP_PUBLISH = 3 -OP_SUBSCRIBE = 4 +OP_ERROR = 0 +OP_INFO = 1 +OP_AUTH = 2 +OP_PUBLISH = 3 +OP_SUBSCRIBE = 4 -MAXBUF = 1024**2 +MAXBUF = 1024 ** 2 SIZES = { - OP_ERROR: 5+MAXBUF, - OP_INFO: 5+256+20, - OP_AUTH: 5+256+20, - OP_PUBLISH: 5+MAXBUF, - OP_SUBSCRIBE: 5+256*2, + OP_ERROR: 5 + MAXBUF, + OP_INFO: 5 + 256 + 20, + OP_AUTH: 5 + 256 + 20, + OP_PUBLISH: 5 + MAXBUF, + OP_SUBSCRIBE: 5 + 256 * 2, } COWRIECHAN = 'cowrie.sessions' @@ -70,12 +70,12 @@ def strpack8(x): # unpacks a string with 1 byte length field def strunpack8(x): l = x[0] - return x[1:1+l], x[1+l:] + return x[1:1 + l], x[1 + l:] def msghdr(op, data): - return struct.pack('!iB', 5+len(data), op) + data + return struct.pack('!iB', 5 + len(data), op) + data @@ -91,7 +91,7 @@ def msgsubscribe(ident, chan): def msgauth(rand, ident, secret): - hash = hashlib.sha1(bytes(rand)+secret).digest() + hash = hashlib.sha1(bytes(rand) + secret).digest() return msghdr(OP_AUTH, strpack8(ident) + hash) @@ -124,7 +124,7 @@ class FeedUnpack(object): if len(self.buf) < ml: raise StopIteration('No message.') - data = bytearray(buffer(self.buf, 5, ml-5)) + data = bytearray(buffer(self.buf, 5, ml - 5)) del self.buf[:ml] return opcode, data @@ -245,7 +245,7 @@ class hpclient(object): self.filehandle = open(filepath, 'rb') fsize = os.stat(filepath).st_size headc = strpack8(self.ident) + strpack8(COWRIECHAN) - headh = struct.pack('!iB', 5+len(headc)+fsize, OP_PUBLISH) + headh = struct.pack('!iB', 5 + len(headc) + fsize, OP_PUBLISH) self.send(headh + headc) @@ -297,18 +297,18 @@ class Output(cowrie.core.output.Output): session = entry["session"] if entry["eventid"] == 'cowrie.session.connect': self.meta[session] = { - 'session':session, + 'session': session, 'startTime': entry["timestamp"], - 'endTime':'', + 'endTime': '', 'peerIP': entry["src_ip"], 'peerPort': entry["src_port"], 'hostIP': entry["dst_ip"], 'hostPort': entry["dst_port"], 'loggedin': None, - 'credentials':[], - 'commands':[], - 'unknownCommands':[], - 'urls':[], + 'credentials': [], + 'commands': [], + 'unknownCommands': [], + 'urls': [], 'version': None, 'ttylog': None, 'hashes': set(), diff --git a/cowrie/output/hpfeeds3.py b/cowrie/output/hpfeeds3.py index 029fad5d..5b5e15a7 100644 --- a/cowrie/output/hpfeeds3.py +++ b/cowrie/output/hpfeeds3.py @@ -65,18 +65,18 @@ class Output(cowrie.core.output.Output): session = entry["session"] if entry["eventid"] == 'cowrie.session.connect': self.meta[session] = { - 'session':session, + 'session': session, 'startTime': entry["timestamp"], - 'endTime':'', + 'endTime': '', 'peerIP': entry["src_ip"], 'peerPort': entry["src_port"], 'hostIP': entry["dst_ip"], 'hostPort': entry["dst_port"], 'loggedin': None, - 'credentials':[], - 'commands':[], - 'unknownCommands':[], - 'urls':[], + 'credentials': [], + 'commands': [], + 'unknownCommands': [], + 'urls': [], 'version': None, 'ttylog': None, 'hashes': set(), diff --git a/cowrie/output/influx.py b/cowrie/output/influx.py index bb8796cc..f0f28725 100644 --- a/cowrie/output/influx.py +++ b/cowrie/output/influx.py @@ -106,7 +106,7 @@ class Output(cowrie.core.output.Output): # measurement init m = { - 'measurement': eventid.replace('.','_'), + 'measurement': eventid.replace('.', '_'), 'tags': { 'session': entry['session'], 'src_ip': entry['src_ip'] diff --git a/cowrie/output/jsonlog.py b/cowrie/output/jsonlog.py index 84ed8c91..a1efe6a2 100644 --- a/cowrie/output/jsonlog.py +++ b/cowrie/output/jsonlog.py @@ -70,7 +70,7 @@ class Output(cowrie.core.output.Output): """ for i in list(logentry.keys()): # Remove twisted 15 legacy keys - if i.startswith('log_') or i == 'time' or i =='system': + if i.startswith('log_') or i == 'time' or i == 'system': del logentry[i] json.dump(logentry, self.outfile) self.outfile.write('\n') diff --git a/cowrie/output/mysql.py b/cowrie/output/mysql.py index b38dfa22..f1104be9 100644 --- a/cowrie/output/mysql.py +++ b/cowrie/output/mysql.py @@ -34,7 +34,7 @@ class ReconnectingConnectionPool(adbapi.ConnectionPool): self, interaction, *args, **kw) except MySQLdb.OperationalError as e: if e[0] not in (2003, 2006, 2013): - raise log.msg("RCP: got error %s, retrying operation" %(e,)) + raise log.msg("RCP: got error {0}, retrying operation".format(e)) conn = self.connections.get(self.threadID()) self.disconnect(conn) # Try the interaction again @@ -71,13 +71,13 @@ class Output(cowrie.core.output.Output): try: self.db = ReconnectingConnectionPool( 'MySQLdb', - host = CONFIG.get('output_mysql', 'host'), - db = CONFIG.get('output_mysql', 'database'), - user = CONFIG.get('output_mysql', 'username'), - passwd = CONFIG.get('output_mysql', 'password', raw=True), - port = port, - cp_min = 1, - cp_max = 1 + host=CONFIG.get('output_mysql', 'host'), + db=CONFIG.get('output_mysql', 'database'), + user=CONFIG.get('output_mysql', 'username'), + passwd=CONFIG.get('output_mysql', 'password', raw=True), + port=port, + cp_min=1, + cp_max=1 ) except MySQLdb.Error as e: log.msg("output_mysql: Error %d: %s" % (e.args[0], e.args[1])) @@ -125,7 +125,7 @@ class Output(cowrie.core.output.Output): sensorid = int(r[0][0]) self.simpleQuery( "INSERT INTO `sessions` (`id`, `starttime`, `sensor`, `ip`)" - + " VALUES (%s, FROM_UNIXTIME(%s), %s, %s)", + + " VALUES (%s, FROM_UNIXTIME(%s), %s, %s)", (entry["session"], entry["time"], sensorid, entry["src_ip"])) elif entry["eventid"] == 'cowrie.login.success': diff --git a/cowrie/output/sqlite.py b/cowrie/output/sqlite.py index 16287313..e54ed1e0 100644 --- a/cowrie/output/sqlite.py +++ b/cowrie/output/sqlite.py @@ -33,7 +33,7 @@ class Output(cowrie.core.output.Output): try: self.db = adbapi.ConnectionPool( 'sqlite3', - database = sqliteFilename, + database=sqliteFilename, check_same_thread=False ) except sqlite3.OperationalError as e: @@ -83,7 +83,7 @@ class Output(cowrie.core.output.Output): sensorid = int(r[0][0]) self.simpleQuery( "INSERT INTO `sessions` (`id`, `starttime`, `sensor`, `ip`)" - + " VALUES (?, ?, ?, ?)", + + " VALUES (?, ?, ?, ?)", (entry["session"], entry["timestamp"], sensorid, entry["src_ip"])) diff --git a/cowrie/output/textlog.py b/cowrie/output/textlog.py index 06e8b000..af7119e1 100644 --- a/cowrie/output/textlog.py +++ b/cowrie/output/textlog.py @@ -60,10 +60,10 @@ class Output(cowrie.core.output.Output): """ """ if self.format == 'cef': - self.outfile.write(logentry['timestamp']+" ") - self.outfile.write(cowrie.core.cef.formatCef(logentry)+'\n') + self.outfile.write('{0} '.format(logentry['timestamp'])) + self.outfile.write('{0}\n'.format(cowrie.core.cef.formatCef(logentry))) else: - self.outfile.write(logentry['timestamp']+" ") - self.outfile.write(logentry['message']+"\n") + self.outfile.write('{0} '.format(logentry['timestamp'])) + self.outfile.write('{0}\n'.format(logentry['message'])) self.outfile.flush() diff --git a/cowrie/output/virustotal.py b/cowrie/output/virustotal.py index b69cfceb..fb993148 100644 --- a/cowrie/output/virustotal.py +++ b/cowrie/output/virustotal.py @@ -90,10 +90,7 @@ class Output(cowrie.core.output.Output): """ """ if entry["eventid"] == 'cowrie.session.file_download': - #TODO: RENABLE - #log.msg("Sending url to VT") - #self.scanurl(entry["url"]) - + # TODO: RENABLE file upload to virustotal (git commit 6546f1ee) log.msg("Checking scan report at VT") self.scanfile(entry) @@ -101,16 +98,12 @@ class Output(cowrie.core.output.Output): log.msg("Checking scan report at VT") self.scanfile(entry["shasum"]) - #log.msg("Sending file to VT") - #self.postfile(entry["outfile"], entry["filename"]) - - def scanfile(self, entry): """ Check file scan report for a hash Argument is full event so we can access full file later on """ - vtUrl = VTAPI_URL+b'file/report' + vtUrl = b'{0}file/report'.format(VTAPI_URL) headers = http_headers.Headers({'User-Agent': [COWRIE_USER_AGENT]}) fields = {'apikey': self.apiKey, 'resource': entry["shasum"]} body = StringProducer(urlencode(fields).encode("utf-8")) @@ -123,7 +116,6 @@ class Output(cowrie.core.output.Output): if response.code == 200: d = client.readBody(response) d.addCallback(cbBody) - #d.addErrback(cbPartial) return d else: log.msg("VT Request failed: {} {}".format(response.code, response.phrase)) @@ -177,7 +169,6 @@ class Output(cowrie.core.output.Output): log.msg("VT: {}/{} bad; permalink: {}".format(j["positives"], j["total"], j["permalink"])) elif j["response_code"] == -2: log.msg("VT: response=-2: this has been queued for analysis already") - #log.msg("VT: permalink: {}".format(j["permalink"])) else: log.msg("VT: unexpected response code".format(j["response_code"])) @@ -190,11 +181,11 @@ class Output(cowrie.core.output.Output): """ Send a file to VirusTotal """ - vtUrl = VTAPI_URL+b'file/scan' + vtUrl = b'{0}file/scan'.format(VTAPI_URL) fields = {('apikey', self.apiKey)} files = {('file', fileName, open(artifact, 'rb'))} if self.debug: - log.msg("submitting to VT: "+repr(files)) + log.msg("submitting to VT: {0}".format(repr(files))) contentType, body = encode_multipart_formdata(fields, files) producer = StringProducer(body) headers = http_headers.Headers({ @@ -258,7 +249,7 @@ class Output(cowrie.core.output.Output): """ Check url scan report for a hash """ - vtUrl = VTAPI_URL+b'url/report' + vtUrl = b'{0}url/report'.format(VTAPI_URL) headers = http_headers.Headers({'User-Agent': [COWRIE_USER_AGENT]}) fields = {'apikey': self.apiKey, 'resource': url, 'scan': 1} body = StringProducer(urlencode(fields).encode("utf-8")) @@ -271,7 +262,6 @@ class Output(cowrie.core.output.Output): if response.code == 200: d = client.readBody(response) d.addCallback(cbBody) - #d.addErrback(cbPartial) return d else: log.msg("VT Request failed: {} {}".format(response.code, response.phrase)) @@ -326,10 +316,12 @@ class Output(cowrie.core.output.Output): """ Send a comment to VirusTotal with Twisted """ - vtUrl = VTAPI_URL+b'comments/put' - parameters = { "resource": resource, - "comment": self.commenttext, - "apikey": self.apiKey} + vtUrl = b'{0}comments/put'.format(VTAPI_URL) + parameters = { + "resource": resource, + "comment": self.commenttext, + "apikey": self.apiKey + } headers = http_headers.Headers({'User-Agent': [COWRIE_USER_AGENT]}) body = StringProducer(urlencode(parameters).encode("utf-8")) d = self.agent.request(b'POST', vtUrl, headers, body) diff --git a/cowrie/output/xmpp.py b/cowrie/output/xmpp.py index 7ac511f0..05459bbe 100644 --- a/cowrie/output/xmpp.py +++ b/cowrie/output/xmpp.py @@ -16,13 +16,13 @@ class XMPPLoggerProtocol(muc.MUCClient): def __init__(self, rooms, server, nick): muc.MUCClient.__init__(self) - self.server = rooms.host + self.server = rooms.host self.jrooms = rooms self._roomOccupantMap = {} log.msg(rooms.user) log.msg(rooms.host) - self.nick = nick - self.last = {} + self.nick = nick + self.last = {} self.activity = None def connectionInitialized(self): @@ -68,22 +68,22 @@ class Output(cowrie.core.output.Output): from random import choice import string - server = CONFIG.get('output_xmpp', 'server') - user = CONFIG.get('output_xmpp', 'user') - password = CONFIG.get('output_xmpp', 'password') - muc = CONFIG.get('output_xmpp', 'muc') + server = CONFIG.get('output_xmpp', 'server') + user = CONFIG.get('output_xmpp', 'user') + password = CONFIG.get('output_xmpp', 'password') + muc = CONFIG.get('output_xmpp', 'muc') resource = ''.join([choice(string.ascii_letters) for i in range(8)]) jid = user + '/' + resource application = service.Application('honeypot') - self.run(application, jid, password,JID(None,[muc,server,None]), server) + self.run(application, jid, password, JID(None, [muc, server, None]), server) def run(self, application, jidstr, password, muc, server): self.xmppclient = XMPPClient(JID(jidstr), password) if CONFIG.has_option('output_xmpp', 'debug') and \ CONFIG.getboolean('output_xmpp', 'debug') == True: - self.xmppclient.logTraffic = True # DEBUG HERE + self.xmppclient.logTraffic = True # DEBUG HERE (user, host, resource) = jid.parse(jidstr) self.muc = XMPPLoggerProtocol( muc, server, user + '-' + resource) @@ -99,7 +99,7 @@ class Output(cowrie.core.output.Output): del logentry[i] elif i == "time": del logentry[i] - msgJson = json.dumps(logentry,indent=5) + msgJson = json.dumps(logentry, indent=5) self.muc.groupChat(self.muc.jrooms, msgJson) diff --git a/cowrie/proxy/avatar.py b/cowrie/proxy/avatar.py index 3a8a1bef..78838ac6 100644 --- a/cowrie/proxy/avatar.py +++ b/cowrie/proxy/avatar.py @@ -11,7 +11,6 @@ from zope.interface import implementer from twisted.conch import avatar from twisted.conch.interfaces import IConchUser, ISession, ISFTPServer -#from twisted.conch.ssh import filetransfer as conchfiletransfer from twisted.python import log, components from cowrie.ssh import session as sshsession @@ -34,12 +33,7 @@ class CowrieUser(avatar.ConchUser): self.channelLookup[b'session'] = proxysession.ProxySSHSession - # SFTP support enabled only when option is explicitly set - #try: - # if CONFIG.getboolean('ssh', 'sftp_enabled') == True: - # self.subsystemLookup[b'sftp'] = conchfiletransfer.FileTransferServer - #except ValueError as e: - # pass + # TODO: Is SFTP still supported? Check git commit 30949e0 for cleaned up code # SSH forwarding disabled only when option is explicitly set self.channelLookup[b'direct-tcpip'] = forwarding.cowrieOpenConnectForwardingClient @@ -55,7 +49,5 @@ class CowrieUser(avatar.ConchUser): """ log.msg('avatar {} logging out'.format(self.username)) - -#components.registerAdapter(filetransfer.SFTPServerForCowrieUser, CowrieUser, ISFTPServer) components.registerAdapter(shellsession.SSHSessionForCowrieUser, CowrieUser, ISession) diff --git a/cowrie/proxy/endpoints.py b/cowrie/proxy/endpoints.py index f198ad2c..4822b99a 100644 --- a/cowrie/proxy/endpoints.py +++ b/cowrie/proxy/endpoints.py @@ -211,7 +211,7 @@ class _CommandChannel(SSHChannel): @param ignored: The (ignored) result of the execute request """ - log.msg("command = "+self._command) + log.msg("command = {0}".format(self._command)) self._protocol = self._protocolFactory.buildProtocol( SSHCommandAddress( @@ -230,7 +230,7 @@ class _CommandChannel(SSHChannel): @param data: The bytes from the command's stdout. @type data: L{bytes} """ - log.msg("command output received"+repr(data)) + log.msg("command output received{0}".format(repr(data))) self._protocol.dataReceived(data) @@ -320,7 +320,7 @@ class _ShellChannel(SSHSession): def ttyRequest(self, something): log.msg("tty-request") term = "vt100" - winSize = (25,80,0,0) # struct.unpack('4H', winsz) + winSize = (25, 80, 0, 0) # struct.unpack('4H', winsz) ptyReqData = packRequest_pty_req(term, winSize, '') req = self.conn.sendRequest(self, b'pty-req', ptyReqData, wantReply=True) req.addCallback(self.shellRequest) @@ -343,7 +343,7 @@ class _ShellChannel(SSHSession): @param reason: The cause of the shell opening failure. @type reason: L{Failure} """ - log.msg("failed to connect to proxy backend: "+reason) + log.msg("failed to connect to proxy backend: {0}".format(reason)) self._shellConnected.errback(reason) @@ -377,7 +377,7 @@ class _ShellChannel(SSHSession): @param data: The bytes from the command's stdout. @type data: L{bytes} """ - log.msg("client-session dataReceived: "+repr(data)) + log.msg("client-session dataReceived: {0}".format(repr(data))) self._protocol.dataReceived(data) @@ -821,7 +821,7 @@ class SSHShellClientEndpoint(object): def disconnectOnFailure(passthrough): # Close the connection immediately in case of cancellation, since # that implies user wants it gone immediately (e.g. a timeout): - immediate = passthrough.check(CancelledError) + immediate = passthrough.check(CancelledError) self._creator.cleanupConnection(connection, immediate) return passthrough shellConnected.addErrback(disconnectOnFailure) @@ -989,7 +989,7 @@ class SSHCommandClientEndpoint(object): def disconnectOnFailure(passthrough): # Close the connection immediately in case of cancellation, since # that implies user wants it gone immediately (e.g. a timeout): - immediate = passthrough.check(CancelledError) + immediate = passthrough.check(CancelledError) self._creator.cleanupConnection(connection, immediate) return passthrough commandConnected.addErrback(disconnectOnFailure) diff --git a/cowrie/proxy/session.py b/cowrie/proxy/session.py index 9c7557fc..72a49650 100644 --- a/cowrie/proxy/session.py +++ b/cowrie/proxy/session.py @@ -12,7 +12,6 @@ from twisted.python import log from twisted.conch.ssh import common, keys, session from twisted.conch.client.knownhosts import KnownHostsFile from twisted.conch.ssh.common import getNS -#from twisted.conch import endpoints from cowrie.core.config import CONFIG from cowrie.proxy import endpoints @@ -57,9 +56,9 @@ class InBetween(protocol.Protocol): SSH client on the other side """ - transport = None # Transport is the back-end the ssh-server - client = None # Client is the front-end, the ssh-client - buf = b"" # buffer to send to back-end + transport = None # Transport is the back-end the ssh-server + client = None # Client is the front-end, the ssh-client + buf = b"" # buffer to send to back-end def makeConnection(self, transport): protocol.Protocol.makeConnection(self, transport) @@ -68,7 +67,6 @@ class InBetween(protocol.Protocol): def connectionMade(self): log.msg("IB: connection Made") if len(self.buf) and self.transport != None: - #self.transport.dataReceived(self.buf) self.transport.write(self.buf) self.buf = None @@ -80,7 +78,7 @@ class InBetween(protocol.Protocol): if not self.transport: self.buf += bytes return - log.msg("IB: write: "+repr(bytes)+" to transport "+repr(self.transport)) + log.msg("IB: write: {0} to transport {1}".format(repr(bytes), repr(self.transport))) self.transport.write(bytes) @@ -88,7 +86,7 @@ class InBetween(protocol.Protocol): """ This is data going from the back-end to the end-user """ - log.msg("IB: dataReceived: "+repr(data)) + log.msg("IB: dataReceived: {0}".format(repr(data))) self.client.write(data) @@ -143,7 +141,6 @@ class ProxySSHSession(channel.CowrieSSHChannel): def __init__(self, *args, **kw): channel.CowrieSSHChannel.__init__(self, *args, **kw) - #self.__dict__['request_auth_agent_req@openssh.com'] = self.request_agent keyPath = CONFIG.get('proxy', 'private_key') self.keys.append(keys.Key.fromFile(keyPath)) @@ -165,10 +162,10 @@ class ProxySSHSession(channel.CowrieSSHChannel): except: self.password = None - log.msg("knownHosts = "+repr(self.knownHosts)) - log.msg("host = "+self.host) - log.msg("port = "+str(self.port)) - log.msg("user = "+self.user) + log.msg("knownHosts = {0}".format(repr(self.knownHosts))) + log.msg("host = {0}".format(self.host)) + log.msg("port = {0}".format(self.port)) + log.msg("user = {0}".format(self.user)) self.client = ProxyClient(self) @@ -182,11 +179,11 @@ class ProxySSHSession(channel.CowrieSSHChannel): log.msg("channelOpen") helper = endpoints._NewConnectionHelper(reactor, self.host, self.port, self.user, self.keys, self.password, None, self.knownHosts, None) - log.msg("helper = "+repr(helper)) + log.msg("helper = {0}".format(repr(helper))) d = helper.secureConnection() d.addCallback(self._cbConnect) d.addErrback(self._ebConnect) - log.msg("d = "+repr(d)) + log.msg("d = {0}".format(repr(d))) return d @@ -247,7 +244,6 @@ class ProxySSHSession(channel.CowrieSSHChannel): cmd, data = common.getNS(data) log.msg('request_exec "{}"'.format(cmd)) pf = _ProtocolFactory(self.client.transport) - #ep = endpoints.SSHCommandClientEndpoint.existingConnection(self.conn, cmd).connect(pf) ep = endpoints.SSHCommandClientEndpoint.newConnection(reactor, cmd, self.user, self.host, port=self.port, password=self.password).connect(pf) return 1 @@ -319,7 +315,6 @@ class ProxySSHSession(channel.CowrieSSHChannel): def dataReceived(self, data): if not self.client: - #self.conn.sendClose(self) self.buf += data return self.client.transport.write(data) diff --git a/cowrie/shell/customparser.py b/cowrie/shell/customparser.py index 3175911d..88cb8381 100644 --- a/cowrie/shell/customparser.py +++ b/cowrie/shell/customparser.py @@ -53,7 +53,7 @@ class CustomParser(argparse.ArgumentParser): def _print_message(self, message, file=None): - super(CustomParser,self)._print_message(message, self.protocol) + super(CustomParser, self)._print_message(message, self.protocol) def error(self, message): self.print_usage(self.protocol) diff --git a/cowrie/shell/filetransfer.py b/cowrie/shell/filetransfer.py index 061218e8..8c150266 100644 --- a/cowrie/shell/filetransfer.py +++ b/cowrie/shell/filetransfer.py @@ -80,7 +80,7 @@ class CowrieSFTPFile(object): def readChunk(self, offset, length): """ """ - return self.contents[offset:offset+length] + return self.contents[offset:offset + length] def writeChunk(self, offset, data): @@ -113,7 +113,7 @@ class CowrieSFTPDirectory(object): def __init__(self, server, directory): self.server = server self.files = server.fs.listdir(directory) - self.files = [".", ".."]+self.files + self.files = [".", ".."] + self.files self.dir = directory @@ -306,7 +306,6 @@ class SFTPServerForCowrieUser(object): def realPath(self, path): """ """ - #log.msg("SFTP realPath: {}".format(path)) return self.fs.realpath(self._absPath(path)) diff --git a/cowrie/shell/fs.py b/cowrie/shell/fs.py index bc72afe4..98025e35 100644 --- a/cowrie/shell/fs.py +++ b/cowrie/shell/fs.py @@ -226,7 +226,7 @@ class HoneyPotFilesystem(object): return False for x in p[A_CONTENTS]: if x[A_NAME] == piece: - if piece == pieces[-1] and follow_symlinks==False: + if piece == pieces[-1] and follow_symlinks == False: p = x elif x[A_TYPE] == T_LINK: if x[A_TARGET][0] == '/': @@ -374,7 +374,6 @@ class HoneyPotFilesystem(object): time.strftime('%Y%m%d-%H%M%S'), re.sub('[^A-Za-z0-9]', '_', filename) ) - #log.msg("fs.open file for writing, saving to %s" % safeoutfile) self.mkfile(filename, 0, 0, 0, stat.S_IFREG | mode) fd = os.open(hostfile, openFlags, hostmode) self.update_realfile(self.getfile(filename), hostfile) @@ -413,7 +412,6 @@ class HoneyPotFilesystem(object): os.remove(self.tempfiles[fd]) else: os.rename(self.tempfiles[fd], shasumfile) - #os.symlink(shasum, self.tempfiles[fd]) self.update_realfile(self.getfile(self.filenames[fd]), shasumfile) log.msg(format='SFTP Uploaded file \"%(filename)s\" to %(outfile)s', eventid='cowrie.session.file_upload', @@ -454,7 +452,7 @@ class HoneyPotFilesystem(object): raise OSError(errno.EEXIST, os.strerror(errno.EEXIST), path) if dir[A_TYPE] != T_DIR: raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR), path) - if len(self.get_path(path))>0: + if len(self.get_path(path)) > 0: raise OSError(errno.ENOTEMPTY, os.strerror(errno.ENOTEMPTY), path) pdir = self.get_path(parent, follow_symlinks=True) for i in pdir[:]: @@ -555,12 +553,12 @@ class HoneyPotFilesystem(object): """ if (path == "/"): p = { - A_TYPE:T_DIR, - A_UID:0, - A_GID:0, - A_SIZE:4096, - A_MODE:16877, - A_CTIME:time.time() + A_TYPE: T_DIR, + A_UID: 0, + A_GID: 0, + A_SIZE: 4096, + A_MODE: 16877, + A_CTIME: time.time() } else: p = self.getfile(path, follow_symlinks=follow_symlinks) diff --git a/cowrie/shell/honeypot.py b/cowrie/shell/honeypot.py index 47068387..94a4399b 100644 --- a/cowrie/shell/honeypot.py +++ b/cowrie/shell/honeypot.py @@ -207,7 +207,6 @@ class HoneyPotShell(object): """ """ log.msg(eventid='cowrie.command.input', input=line, format='CMD: %(input)s') - #line = b"".join(line) self.lexer = shlex.shlex(instream=line, punctuation_chars=True) tokens = [] while True: @@ -344,7 +343,7 @@ class HoneyPotShell(object): for index, pipe_indice in enumerate(pipe_indices): multipleCmdArgs.append(cmdAndArgs[start:pipe_indice]) - start = pipe_indice+1 + start = pipe_indice + 1 cmd['rargs'] = parse_file_arguments(multipleCmdArgs.pop(0)) cmd_array.append(cmd) @@ -362,8 +361,8 @@ class HoneyPotShell(object): cmdclass = self.protocol.getCommand(cmd['command'], environ['PATH'].split(':')) if cmdclass: log.msg(input=cmd['command'] + " " + ' '.join(cmd['rargs']), format='Command found: %(input)s') - if index == len(cmd_array)-1: - lastpp = StdOutStdErrEmulationProtocol(self.protocol, cmdclass, cmd['rargs'], None, None) + if index == len(cmd_array) - 1: + lastpp = StdOutStdErrEmulationProtocol(self.protocol, cmdclass, cmd['rargs'], None, None) pp = lastpp else: pp = StdOutStdErrEmulationProtocol(self.protocol, cmdclass, cmd['rargs'], None, lastpp) @@ -394,24 +393,19 @@ class HoneyPotShell(object): homelen = len(self.protocol.user.avatar.home) if cwd == self.protocol.user.avatar.home: cwd = '~' - elif len(cwd) > (homelen+1) and \ - cwd[:(homelen+1)] == self.protocol.user.avatar.home + '/': + elif len(cwd) > (homelen + 1) and \ + cwd[:(homelen + 1)] == self.protocol.user.avatar.home + '/': cwd = '~' + cwd[homelen:] - # Uncomment the three lines below for a 'better' CentOS look. - # Rather than '[root@svr03 /var/log]#' is shows '[root@svr03 log]#'. - #cwd = cwd.rsplit('/', 1)[-1] - #if not cwd: - # cwd = '/' # Example: [root@svr03 ~]# (More of a "CentOS" feel) # Example: root@svr03:~# (More of a "Debian" feel) - prompt = self.protocol.user.username+'@'+self.protocol.hostname+':'+cwd + prompt = '{0}@{1}:{2}'.format(self.protocol.user.username, self.pr.hostname, cwd) if not self.protocol.user.uid: prompt += '# ' # "Root" user else: prompt += '$ ' # "Non-Root" user self.protocol.terminal.write(prompt) - self.protocol.ps = (prompt , '> ') + self.protocol.ps = (prompt, '> ') def eofReceived(self): @@ -437,7 +431,7 @@ class HoneyPotShell(object): """ log.msg('Received CTRL-D, exiting..') - cmdclass = self.protocol.commands['exit'] + cmdclass = self.protocol.commands['exit'] pp = StdOutStdErrEmulationProtocol(self.protocol, cmdclass, None, None, None) self.protocol.call_command(pp, self.protocol.commands['exit']) diff --git a/cowrie/shell/protocol.py b/cowrie/shell/protocol.py index 386a7ac9..59a6eec0 100644 --- a/cowrie/shell/protocol.py +++ b/cowrie/shell/protocol.py @@ -60,7 +60,7 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin): self.commands.update(module.commands) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() - log.err("Failed to import command {}: {}: {}".format(c, e, ''.join(traceback.format_exception(exc_type,exc_value,exc_traceback)))) + log.err("Failed to import command {}: {}: {}".format(c, e, ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))) self.password_input = False self.cmdstack = [] @@ -136,15 +136,13 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin): """ self.setTimeout(None) insults.TerminalProtocol.connectionLost(self, reason) - self.terminal = None # (this should be done by super above) + self.terminal = None # (this should be done by super above) self.cmdstack = [] del self.commands self.fs = None self.pp = None self.user = None self.environ = None - #log.msg("honeypot terminal protocol connection lost {}".format(reason)) - def txtcmd(self, txt): """ @@ -228,8 +226,6 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin): """ pt = self.getProtoTransport() r = time.time() - pt.factory.starttime - #if reset: - # pt.factory.starttime = reset return r @@ -306,21 +302,21 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin self.cmdstack = [honeypot.HoneyPotShell(self)] self.keyHandlers.update({ - b'\x01': self.handle_HOME, # CTRL-A - b'\x02': self.handle_LEFT, # CTRL-B - b'\x03': self.handle_CTRL_C, # CTRL-C - b'\x04': self.handle_CTRL_D, # CTRL-D - b'\x05': self.handle_END, # CTRL-E - b'\x06': self.handle_RIGHT, # CTRL-F - b'\x08': self.handle_BACKSPACE, # CTRL-H - b'\x09': self.handle_TAB, - b'\x0b': self.handle_CTRL_K, # CTRL-K - b'\x0c': self.handle_CTRL_L, # CTRL-L - b'\x0e': self.handle_DOWN, # CTRL-N - b'\x10': self.handle_UP, # CTRL-P - b'\x15': self.handle_CTRL_U, # CTRL-U - b'\x16': self.handle_CTRL_V, # CTRL-V - b'\x1b': self.handle_ESC, # ESC + b'\x01': self.handle_HOME, # CTRL-A + b'\x02': self.handle_LEFT, # CTRL-B + b'\x03': self.handle_CTRL_C, # CTRL-C + b'\x04': self.handle_CTRL_D, # CTRL-D + b'\x05': self.handle_END, # CTRL-E + b'\x06': self.handle_RIGHT, # CTRL-F + b'\x08': self.handle_BACKSPACE, # CTRL-H + b'\x09': self.handle_TAB, + b'\x0b': self.handle_CTRL_K, # CTRL-K + b'\x0c': self.handle_CTRL_L, # CTRL-L + b'\x0e': self.handle_DOWN, # CTRL-N + b'\x10': self.handle_UP, # CTRL-P + b'\x15': self.handle_CTRL_U, # CTRL-U + b'\x16': self.handle_CTRL_V, # CTRL-V + b'\x1b': self.handle_ESC, # ESC }) @@ -328,8 +324,7 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin """ """ try: - self.terminal.write(self.fs.file_contents('/etc/motd')+'\n') - + self.terminal.write('{0}\n'.format(self.fs.file_contents('/etc/motd'))) except: pass @@ -372,7 +367,7 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin if self.mode == 'insert': self.lineBuffer.insert(self.lineBufferIndex, ch) else: - self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch] + self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex + 1] = [ch] self.lineBufferIndex += 1 if not self.password_input: self.terminal.write(ch) diff --git a/cowrie/shell/session.py b/cowrie/shell/session.py index 5a140c5a..e71e6e65 100644 --- a/cowrie/shell/session.py +++ b/cowrie/shell/session.py @@ -44,10 +44,10 @@ class SSHSessionForCowrieUser(object): 'USER': self.username, 'HOME': self.avatar.home, 'TMOUT': '1800'} - if self.uid==0: - self.environ['PATH']='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' + if self.uid == 0: + self.environ['PATH'] = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' else: - self.environ['PATH']='/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games' + self.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games' self.server.initFileSystem() diff --git a/cowrie/shell/shlex.py b/cowrie/shell/shlex.py index e4ade7ec..d7d668d0 100644 --- a/cowrie/shell/shlex.py +++ b/cowrie/shell/shlex.py @@ -67,7 +67,7 @@ class shlex: self._pushback_chars = deque() # these chars added because allowed in file names, args, wildcards self.wordchars += '@%{}~-./*?=$:+^' - #remove any punctuation chars from wordchars + # remove any punctuation chars from wordchars self.wordchars = ''.join(c for c in self.wordchars if c not in self.punctuation_chars) for c in punctuation_chars: @@ -318,7 +318,7 @@ def split(s, comments=False, posix=True): return list(lex) -#_find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search + # No ASCII in P2.x _find_unsafe = re.compile(r'[^\w@%+=:,./-]').search diff --git a/cowrie/ssh/channel.py b/cowrie/ssh/channel.py index ccfcbfbb..5ec76f04 100644 --- a/cowrie/ssh/channel.py +++ b/cowrie/ssh/channel.py @@ -78,8 +78,8 @@ class CowrieSSHChannel(channel.SSHChannel): log.msg(eventid='cowrie.log.closed', format="Closing TTY Log: %(ttylog)s after %(duration)d seconds", ttylog=self.ttylogFile, - size=self.bytesReceived+self.bytesWritten, - duration=time.time()-self.startTime) + size=self.bytesReceived + self.bytesWritten, + duration=time.time() - self.startTime) ttylog.ttylog_close(self.ttylogFile, time.time()) channel.SSHChannel.closed(self) diff --git a/cowrie/ssh/factory.py b/cowrie/ssh/factory.py index dc8d492e..671d50a0 100644 --- a/cowrie/ssh/factory.py +++ b/cowrie/ssh/factory.py @@ -36,13 +36,13 @@ class CowrieSSHFactory(factory.SSHFactory): privateKeys = None publicKeys = None primes = None - tac = None # gets set later + tac = None # gets set later def logDispatch(self, *msg, **args): """ Special delivery to the loggers to avoid scope problems """ - args['sessionno'] = 'S'+str(args['sessionno']) + args['sessionno'] = 'S{0}'.format(args['sessionno']) for dblog in self.tac.dbloggers: dblog.logDispatch(*msg, **args) for output in self.tac.output_plugins: diff --git a/cowrie/ssh/session.py b/cowrie/ssh/session.py index e9d20e7c..45a76175 100644 --- a/cowrie/ssh/session.py +++ b/cowrie/ssh/session.py @@ -19,8 +19,6 @@ class HoneyPotSSHSession(session.SSHSession): def __init__(self, *args, **kw): session.SSHSession.__init__(self, *args, **kw) - #self.__dict__['request_auth_agent_req@openssh.com'] = self.request_agent - def request_env(self, data): """ diff --git a/cowrie/ssh/transport.py b/cowrie/ssh/transport.py index b8cac011..ffa7f31e 100644 --- a/cowrie/ssh/transport.py +++ b/cowrie/ssh/transport.py @@ -52,13 +52,19 @@ class HoneyPotSSHTransport(transport.SSHServerTransport, TimeoutMixin): if ipv4_search != None: src_ip = ipv4_search.group(1) - log.msg(eventid='cowrie.session.connect', - format="New connection: %(src_ip)s:%(src_port)s (%(dst_ip)s:%(dst_port)s) [session: %(session)s]", - src_ip=src_ip, src_port=self.transport.getPeer().port, - dst_ip=self.transport.getHost().host, dst_port=self.transport.getHost().port, - session=self.transportId, sessionno='S'+str(self.transport.sessionno), protocol='ssh') + log.msg( + eventid='cowrie.session.connect', + format="New connection: %(src_ip)s:%(src_port)s (%(dst_ip)s:%(dst_port)s) [session: %(session)s]", + src_ip=src_ip, + src_port=self.transport.getPeer().port, + dst_ip=self.transport.getHost().host, + dst_port=self.transport.getHost().port, + session=self.transportId, + sessionno='S{0}'.format(self.transport.sessionno), + protocol='ssh' + ) - self.transport.write(b''+self.ourVersionString+b'\r\n') + self.transport.write(b'{0}\r\n'.format(self.ourVersionString)) self.currentEncryptions = transport.SSHCiphers(b'none', b'none', b'none', b'none') self.currentEncryptions.setKeys(b'', b'', b'', b'', b'', b'') self.setTimeout(120) @@ -93,7 +99,6 @@ class HoneyPotSSHTransport(transport.SSHServerTransport, TimeoutMixin): if not self.gotVersion: if not b'\n' in self.buf: return - #self.otherVersionString = self.buf.split(b'\n')[0].strip().encode('string-escape') self.otherVersionString = self.buf.split(b'\n')[0].strip() log.msg(eventid='cowrie.client.version', version=self.otherVersionString, format="Remote SSH version: %(version)s") @@ -104,7 +109,7 @@ class HoneyPotSSHTransport(transport.SSHServerTransport, TimeoutMixin): self._unsupportedVersionReceived(remoteVersion) return i = self.buf.index(b'\n') - self.buf = self.buf[i+1:] + self.buf = self.buf[i + 1:] self.sendKexInit() else: self.transport.write(b'Protocol mismatch.\n') diff --git a/cowrie/ssh/userauth.py b/cowrie/ssh/userauth.py index 8b3c70aa..c32e9bb6 100644 --- a/cowrie/ssh/userauth.py +++ b/cowrie/ssh/userauth.py @@ -130,9 +130,9 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): """ resp = [] for message, kind in items: - if kind == 1: # Password + if kind == 1: # Password resp.append((message, 0)) - elif kind == 2: # Text + elif kind == 2: # Text resp.append((message, 1)) elif kind in (3, 4): return defer.fail(error.ConchError( diff --git a/cowrie/telnet/session.py b/cowrie/telnet/session.py index 9b767d4f..80c72572 100644 --- a/cowrie/telnet/session.py +++ b/cowrie/telnet/session.py @@ -25,7 +25,7 @@ class HoneyPotTelnetSession(TelnetBootstrapProtocol): """ """ - id = 0 # telnet can only have 1 simultaneous session, unlike SSH + id = 0 # telnet can only have 1 simultaneous session, unlike SSH windowSize = [40, 80] def __init__(self, username, server): @@ -112,13 +112,6 @@ class TelnetSessionProcessProtocol(protocol.ProcessProtocol): self.session = sess self.lostOutOrErrFlag = False - # FIXME probably no such thing such as buffering in Telnet protocol - #def connectionMade(self): - # if self.session.buf: - # self.session.write(self.session.buf) - # self.session.buf = None - - def outReceived(self, data): self.session.write(data) diff --git a/cowrie/telnet/transport.py b/cowrie/telnet/transport.py index b970435a..3559c65e 100644 --- a/cowrie/telnet/transport.py +++ b/cowrie/telnet/transport.py @@ -33,7 +33,7 @@ class HoneyPotTelnetFactory(protocol.ServerFactory): """ Special delivery to the loggers to avoid scope problems """ - args['sessionno'] = 'T'+str(args['sessionno']) + args['sessionno'] = 'T{0}'.format(str(args['sessionno'])) for dblog in self.tac.dbloggers: dblog.logDispatch(*msg, **args) for output in self.tac.output_plugins: @@ -105,7 +105,6 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): """ self.username = line # .decode() # only send ECHO option if we are chatting with a real Telnet client - #if self.transport.options: <-- doesn't work self.transport.willChain(ECHO) # FIXME: this should be configurable or provided via filesystem self.transport.write(self.passwordPrompt) @@ -141,7 +140,7 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): def telnet_Command(self, command): """ """ - self.transport.protocol.dataReceived(command+b'\r') + self.transport.protocol.dataReceived(command + b'\r') return "Command" @@ -192,9 +191,9 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): """ if opt == ECHO: return True + # TODO: check if twisted now supports SGA (see git commit c58056b0) elif opt == SGA: return False - #return True else: return False @@ -202,10 +201,9 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol): def enableRemote(self, opt): """ """ + # TODO: check if twisted now supports LINEMODE (see git commit c58056b0) if opt == LINEMODE: return False - #self.transport.requestNegotiation(LINEMODE, MODE + chr(TRAPSIG)) - #return True elif opt == NAWS: return True elif opt == SGA: @@ -234,7 +232,7 @@ class CowrieTelnetTransport(TelnetTransport, TimeoutMixin): dst_ip=self.transport.getHost().host, dst_port=self.transport.getHost().port, session=self.transportId, - sessionno='T'+str(sessionno), + sessionno='T{0}'.format(str(sessionno)), protocol='telnet') TelnetTransport.connectionMade(self) diff --git a/cowrie/test/fake_transport.py b/cowrie/test/fake_transport.py index 4f382144..6138808c 100644 --- a/cowrie/test/fake_transport.py +++ b/cowrie/test/fake_transport.py @@ -5,7 +5,7 @@ from __future__ import division, absolute_import -from twisted.conch.insults import insults,helper +from twisted.conch.insults import insults, helper from twisted.test import proto_helpers diff --git a/cowrie/test/test_base_commands.py b/cowrie/test/test_base_commands.py index 61ade976..5e56ca25 100644 --- a/cowrie/test/test_base_commands.py +++ b/cowrie/test/test_base_commands.py @@ -21,8 +21,7 @@ class ShellBaseCommandsTests(unittest.TestCase): with open('../cowrie/test/expected_results.json') as data_file: self.data = json.load(data_file) self.cfg = config.readConfigFile("../cowrie/test/unittests.cfg") - self.proto = protocol.HoneyPotInteractiveProtocol \ - (fake_server.FakeAvatar(fake_server.FakeServer(self.cfg))) + self.proto = protocol.HoneyPotInteractiveProtocol(fake_server.FakeAvatar(fake_server.FakeServer(self.cfg))) self.tr = fake_transport.FakeTransport("1.1.1.1", "1111") self.proto.makeConnection(self.tr) self.tr.clear() @@ -30,31 +29,31 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_whoami_command(self): self.proto.lineReceived('whoami \n') - self.assertEqual(self.tr.value(),self.data['results']['whoami']) + self.assertEqual(self.tr.value(), self.data['results']['whoami']) def test_users_command(self): self.proto.lineReceived('users \n') - self.assertEqual(self.tr.value(),self.data['results']['users']) + self.assertEqual(self.tr.value(), self.data['results']['users']) def test_help_command(self): self.proto.lineReceived('help \n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['help'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['help'])) def test_w_command(self): self.proto.lineReceived('w \n') - self.assertRegexpMatches(self.tr.value(),("\n").join(self.data['results']['w'])) + self.assertRegexpMatches(self.tr.value(), ("\n").join(self.data['results']['w'])) def test_who_command(self): self.proto.lineReceived('who \n') - self.assertRegexpMatches(self.tr.value(),"\n".join(self.data['results']['who'])) + self.assertRegexpMatches(self.tr.value(), "\n".join(self.data['results']['who'])) def test_echo_command(self): self.proto.lineReceived('echo "test worked correctly" \n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['echo'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['echo'])) def test_exit_command(self): @@ -71,7 +70,7 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_hostname_command(self): self.proto.lineReceived('hostname unitChanged\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['hostname'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['hostname'])) def test_reset_command(self): @@ -80,18 +79,18 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_ps_command(self): self.proto.lineReceived('ps\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['ps'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['ps'])) def test_id_command(self): self.proto.lineReceived('id\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['id'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['id'])) def test_passwd_command(self): self.proto.lineReceived('passwd\n') self.proto.lineReceived('changeme\n') self.proto.lineReceived('changeme\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['passwd'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['passwd'])) def test_shutdown_command(self): @@ -111,7 +110,7 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_date_command(self): self.proto.lineReceived('date\n') - self.assertRegexpMatches(self.tr.value(),("\n").join(self.data['results']['date'])) + self.assertRegexpMatches(self.tr.value(), ("\n").join(self.data['results']['date'])) def test_bash_command(self): @@ -120,7 +119,7 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_sh_command(self): self.proto.lineReceived('sh -c who\n') - self.assertRegexpMatches(self.tr.value(),"\n".join(self.data['results']['who'])) + self.assertRegexpMatches(self.tr.value(), "\n".join(self.data['results']['who'])) def test_php_command(self): @@ -131,71 +130,71 @@ class ShellBaseCommandsTests(unittest.TestCase): def test_chattr_command(self): self.proto.lineReceived('chattr\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['chattr'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['chattr'])) def test_umask_command(self): self.proto.lineReceived('umask\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['umask'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['umask'])) def test_set_command(self): self.proto.lineReceived('set\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['set'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['set'])) def test_unset_command(self): self.proto.lineReceived('unset\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['unset'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['unset'])) def test_export_command(self): self.proto.lineReceived('export\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['export'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['export'])) def test_alias_command(self): self.proto.lineReceived('alias\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['alias'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['alias'])) def test_jobs_command(self): self.proto.lineReceived('jobs\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['jobs'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['jobs'])) def test_kill_command(self): self.proto.lineReceived('/bin/kill\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['kill'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['kill'])) def test_pkill_command(self): self.proto.lineReceived('/bin/pkill\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['kill'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['kill'])) def test_killall_command(self): self.proto.lineReceived('/bin/killall\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['kill'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['kill'])) def test_killall5_command(self): self.proto.lineReceived('/bin/killall5\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['kill'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['kill'])) def test_su_command(self): self.proto.lineReceived('su\n') - self.assertEquals(self.tr.value(),"\67n".join(self.data['results']['su'])) + self.assertEquals(self.tr.value(), "\67n".join(self.data['results']['su'])) def test_chown_command(self): self.proto.lineReceived('chown\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['chown'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['chown'])) def test_chgrp_command(self): self.proto.lineReceived('chgrp\n') - self.assertEquals(self.tr.value(),"\n".join(self.data['results']['chgrp'])) + self.assertEquals(self.tr.value(), "\n".join(self.data['results']['chgrp'])) def tearDown(self): diff --git a/setup.py b/setup.py index 4e9c7f2b..3a1fbbc9 100755 --- a/setup.py +++ b/setup.py @@ -2,48 +2,54 @@ from setuptools import setup, find_packages -setup ( - name = "Cowrie", - version = "1.0", - description = "Cowrie SSH/Telnet Honeypot.", - maintainer = "Michel Oosterhof", - maintainer_email = "michel@oosterhof.net", - keywords = "ssh telnet honeypot", - url = "https://github.com/micheloosterhof/cowrie", - packages = find_packages(), +setup( + name="Cowrie", + version="1.0", + description="Cowrie SSH/Telnet Honeypot.", + maintainer="Michel Oosterhof", + maintainer_email="michel@oosterhof.net", + keywords="ssh telnet honeypot", + url="https://github.com/micheloosterhof/cowrie", + packages=find_packages(), include_package_data=True, - package_data = { '': ['*.md'] }, - scripts = ["bin/fsctl", - "bin/asciinema", - "bin/cowrie", - "bin/createfs", - "bin/playlog"], - install_requires = ["twisted>=17.1.0", - "cryptography>=0.9.1", - "configparser", - "pyopenssl", - "pyparsing", - "packaging", - "appdirs>=1.4.0", - "python-pyasn1", - "python-gmpy2", - "python-mysqldb", - "klein>=15.0.0", - "treq>=15.0.0", - "python-dateutil", - "service_identity>=14.0.0"], - entry_points = {'console_scripts': - ['run-the-app = deployme:main']}, + package_data={'': ['*.md']}, + scripts=[ + "bin/fsctl", + "bin/asciinema", + "bin/cowrie", + "bin/createfs", + "bin/playlog" + ], + install_requires=[ + "twisted>=17.1.0", + "cryptography>=0.9.1", + "configparser", + "pyopenssl", + "pyparsing", + "packaging", + "appdirs>=1.4.0", + "python-pyasn1", + "python-gmpy2", + "python-mysqldb", + "klein>=15.0.0", + "treq>=15.0.0", + "python-dateutil", + "service_identity>=14.0.0" + ], + entry_points={ + 'console_scripts': ['run-the-app = deployme:main'] + }, - extras_require = { 'csirtg': ["csirtgsdk>=0.0.0a17"], - 'dshield': ["requests"], - 'elasticsearch': ["pyes"], - 'mysql': ["mysqlclient"], - 'mongodb': ["pymongo"], - 'rethinkdblog': ["rethinkdb"], - 's3': ["botocore"], - 'slack': ["slackclient"], - 'splunklegacy': ["splunk-sdk"], - 'influxdb': ["influxdb"]} + extras_require={ + 'csirtg': ["csirtgsdk>=0.0.0a17"], + 'dshield': ["requests"], + 'elasticsearch': ["pyes"], + 'mysql': ["mysqlclient"], + 'mongodb': ["pymongo"], + 'rethinkdblog': ["rethinkdb"], + 's3': ["botocore"], + 'slack': ["slackclient"], + 'splunklegacy': ["splunk-sdk"], + 'influxdb': ["influxdb"] + } ) -