diff --git a/cowrie/commands/adduser.py b/cowrie/commands/adduser.py index e8bc57c..8ee73a2 100644 --- a/cowrie/commands/adduser.py +++ b/cowrie/commands/adduser.py @@ -25,7 +25,7 @@ class command_adduser(HoneyPotCommand): self.username = arg break if self.username is None: - self.writeln('adduser: Only one or two names allowed.') + self.write('adduser: Only one or two names allowed.\n') self.exit() return @@ -95,9 +95,9 @@ class command_adduser(HoneyPotCommand): return elif self.item == 20 and line.strip() not in ('y', 'yes'): self.item = 7 - self.writeln('Ok, starting over') + self.write('Ok, starting over\n') elif not len(line) and self.output[self.item][0] == O_Q: - self.writeln('Must enter a value!') + self.write('Must enter a value!\n') else: self.item += 1 self.schedule_next() diff --git a/cowrie/commands/apt.py b/cowrie/commands/apt.py index b02cc3b..5d187af 100644 --- a/cowrie/commands/apt.py +++ b/cowrie/commands/apt.py @@ -16,7 +16,7 @@ class command_faked_package_class_factory(object): def getCommand(name): class command_faked_installation(HoneyPotCommand): def call(self): - self.writeln("%s: Segmentation fault" % name) + self.write("%s: Segmentation fault\n" % name) return command_faked_installation class command_aptget(HoneyPotCommand): @@ -45,7 +45,7 @@ class command_aptget(HoneyPotCommand): return d def do_version(self): - self.writeln('''apt 1.0.9.8.1 for amd64 compiled on Jun 10 2015 09:42:06 + self.write('''apt 1.0.9.8.1 for amd64 compiled on Jun 10 2015 09:42:06 Supported modules: *Ver: Standard .deb *Pkg: Debian dpkg interface (Priority 30) @@ -56,12 +56,12 @@ Supported modules: Idx: Debian Package Index Idx: Debian Translation Index Idx: Debian dpkg status file - Idx: EDSP scenario file''') + Idx: EDSP scenario file\n''') self.exit() return def do_help(self): - self.writeln('''apt 1.0.9.8.1 for amd64 compiled on Jun 10 2015 09:42:06 + self.write('''apt 1.0.9.8.1 for amd64 compiled on Jun 10 2015 09:42:06 Usage: apt-get [options] command apt-get [options] install|remove pkg1 [pkg2 ...] apt-get [options] source pkg1 [pkg2 ...] @@ -103,14 +103,14 @@ Options: -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp See the apt-get(8), sources.list(5) and apt.conf(5) manual pages for more information and options. - This APT has Super Cow Powers.''') + This APT has Super Cow Powers.\n''') self.exit() return @inlineCallbacks def do_install(self,*args): if len(self.args) <= 1: - self.writeln('0 upgraded, 0 newly installed, 0 to remove and %s not upgraded.' % random.randint(200,300)) + self.write('0 upgraded, 0 newly installed, 0 to remove and %s not upgraded.\n' % random.randint(200,300)) self.exit() return @@ -125,36 +125,36 @@ pages for more information and options. } totalsize = sum([packages[x]['size'] for x in packages]) - self.writeln('Reading package lists... Done') - self.writeln('Building dependency tree') - self.writeln('Reading state information... Done') - self.writeln('The following NEW packages will be installed:') - self.writeln(' %s ' % ' '.join(packages)) - self.writeln('0 upgraded, %d newly installed, 0 to remove and 259 not upgraded.' % \ + self.write('Reading package lists... Done\n') + self.write('Building dependency tree\n') + self.write('Reading state information... Done\n') + self.write('The following NEW packages will be installed:\n') + self.write(' %s ' % ' '.join(packages) + '\n') + self.write('0 upgraded, %d newly installed, 0 to remove and 259 not upgraded.\n' % \ len(packages)) - self.writeln('Need to get %s.2kB of archives.' % (totalsize)) - self.writeln('After this operation, %skB of additional disk space will be used.' % \ + self.write('Need to get %s.2kB of archives.\n' % (totalsize)) + self.write('After this operation, %skB of additional disk space will be used.\n' % \ (totalsize * 2.2,)) i = 1 for p in packages: - self.writeln('Get:%d http://ftp.debian.org stable/main %s %s [%s.2kB]' % \ + self.write('Get:%d http://ftp.debian.org stable/main %s %s [%s.2kB]\n' % \ (i, p, packages[p]['version'], packages[p]['size'])) i += 1 yield self.sleep(1, 2) - self.writeln('Fetched %s.2kB in 1s (4493B/s)''' % (totalsize)) - self.writeln('Reading package fields... Done') + self.write('Fetched %s.2kB in 1s (4493B/s)''\n' % (totalsize)) + self.write('Reading package fields... Done\n') yield self.sleep(1, 2) - self.writeln('Reading package status... Done') - self.writeln('(Reading database ... 177887 files and directories currently installed.)') + self.write('Reading package status... Done\n') + self.write('(Reading database ... 177887 files and directories currently installed.)\n') yield self.sleep(1, 2) for p in packages: - self.writeln('Unpacking %s (from .../archives/%s_%s_i386.deb) ...' % \ + self.write('Unpacking %s (from .../archives/%s_%s_i386.deb) ...\n' % \ (p, p, packages[p]['version'])) yield self.sleep(1, 2) - self.writeln('Processing triggers for man-db ...') + self.write('Processing triggers for man-db ...\n') yield self.sleep(2) for p in packages: - self.writeln('Setting up %s (%s) ...' % \ + self.write('Setting up %s (%s) ...\n' % \ (p, packages[p]['version'])) self.fs.mkfile('/usr/bin/%s' % p, 0, 0, random.randint(10000, 90000), 33188) @@ -164,18 +164,18 @@ pages for more information and options. self.exit() def do_moo(self): - self.writeln(' (__)') - self.writeln(' (oo)') - self.writeln(' /------\/') - self.writeln(' / | ||') - self.writeln(' * /\---/\ ') - self.writeln(' ~~ ~~') - self.writeln('...."Have you mooed today?"...') + self.write(' (__)\n') + self.write(' (oo)\n') + self.write(' /------\/\n') + self.write(' / | ||\n') + self.write(' * /\---/\ \n') + self.write(' ~~ ~~\n') + self.write('...."Have you mooed today?"...\n') self.exit() def do_locked(self): - self.writeln('E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)') - self.writeln('E: Unable to lock the list directory') + self.write('E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)\n') + self.write('E: Unable to lock the list directory\n') self.exit() commands['/usr/bin/apt-get'] = command_aptget diff --git a/cowrie/commands/base.py b/cowrie/commands/base.py index 3df0d4e..3875c15 100644 --- a/cowrie/commands/base.py +++ b/cowrie/commands/base.py @@ -21,7 +21,7 @@ class command_whoami(HoneyPotCommand): def call(self): """ """ - self.writeln(self.protocol.user.username) + self.write(self.protocol.user.username+'\n') commands['/usr/bin/whoami'] = command_whoami commands['/usr/bin/users'] = command_whoami @@ -36,7 +36,7 @@ class command_uptime(HoneyPotCommand): if len(self.args): secs = int(self.args[0]) self.protocol.uptime(time.time() - secs) - self.writeln(' %s up %s, 1 user, load average: 0.00, 0.00, 0.00' % \ + self.write(' %s up %s, 1 user, load average: 0.00, 0.00, 0.00\n' % \ (time.strftime('%H:%M:%S'), utils.uptime(self.protocol.uptime()))) commands['/usr/bin/uptime'] = command_uptime @@ -48,7 +48,7 @@ class command_help(HoneyPotCommand): def call(self): """ """ - self.writeln("""GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu) + self.write("""GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu) These shell commands are defined internally. Type `help' to see this list. Type `help name' to find out more about the function `name'. Use `info bash' to find out more about the shell in general. @@ -93,7 +93,7 @@ A star (*) next to a name means that the command is disabled. function name { COMMANDS ; } or name () { COMMANDS ; } variables - Names and meanings of some shell variables getopts optstring name [arg] wait [id] hash [-lr] [-p pathname] [-dt] [name ...] while COMMANDS; do COMMANDS; done - help [-dms] [pattern ...] { COMMANDS ; }""") + help [-dms] [pattern ...] { COMMANDS ; }\n""") commands['help'] = command_help @@ -104,10 +104,10 @@ class command_w(HoneyPotCommand): def call(self): """ """ - self.writeln(' %s up %s, 1 user, load average: 0.00, 0.00, 0.00' % \ + self.write(' %s up %s, 1 user, load average: 0.00, 0.00, 0.00\n' % \ (time.strftime('%H:%M:%S'), utils.uptime(self.protocol.uptime()))) - self.writeln('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT') - self.writeln('%-8s pts/0 %s %s 0.00s 0.00s 0.00s w' % \ + self.write('USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\n') + self.write('%-8s pts/0 %s %s 0.00s 0.00s 0.00s w\n' % \ (self.protocol.user.username, self.protocol.clientIP[:17].ljust(17), time.strftime('%H:%M', time.localtime(self.protocol.logintime)))) @@ -121,7 +121,7 @@ class command_who(HoneyPotCommand): def call(self): """ """ - self.writeln('%-8s pts/0 %s %s (%s)' % \ + 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('%H:%M', time.localtime(self.protocol.logintime)), @@ -136,8 +136,8 @@ class command_echo(HoneyPotCommand): def call(self): """ """ - write_fn = self.writeln escape_fn = lambda s: s + newline = True try: optlist, args = getopt.getopt(self.args, "eEn") @@ -147,11 +147,13 @@ class command_echo(HoneyPotCommand): elif opt[0] == '-E': escape_fn = lambda s: s elif opt[0] == '-n': - write_fn = self.write + newline = False except: args = self.args - write_fn(escape_fn(' '.join(args))) + self.write(escape_fn(' '.join(args))) + if newline is True: + self.write('\n') commands['/bin/echo'] = command_echo @@ -195,7 +197,7 @@ class command_hostname(HoneyPotCommand): def call(self): """ """ - self.writeln(self.protocol.hostname) + self.write(self.protocol.hostname+'\n') commands['/bin/hostname'] = command_hostname @@ -263,7 +265,7 @@ class command_ps(HoneyPotCommand): s = ''.join([output[i][x] for x in l]) if 'w' not in args: s = s[:80] - self.writeln(s) + self.write(s+'\n') commands['/bin/ps'] = command_ps @@ -275,7 +277,7 @@ class command_id(HoneyPotCommand): """ """ u = self.protocol.user - self.writeln('uid=%d(%s) gid=%d(%s) groups=%d(%s)' % \ + self.write('uid=%d(%s) gid=%d(%s) groups=%d(%s)\n' % \ (u.uid, u.username, u.gid, u.username, u.gid, u.username)) commands['/usr/bin/id'] = command_id @@ -306,14 +308,14 @@ class command_passwd(HoneyPotCommand): self.protocol.password_input = False if line != self.passwd or self.passwd == '*': - self.writeln('Sorry, passwords do not match') + self.write('Sorry, passwords do not match\n') self.exit() return userdb = UserDB(self.protocol.cfg) userdb.adduser(self.protocol.user.username, self.passwd) - self.writeln('passwd: password updated successfully') + self.write('passwd: password updated successfully\n') self.exit() @@ -351,28 +353,28 @@ class command_shutdown(HoneyPotCommand): "** the \"time\" argument is mandatory! (try \"now\") **", ) for l in output: - self.writeln(l) + self.write(l+'\n') self.exit() elif len(self.args) > 1 and self.args[0].strip().count('-h') \ and self.args[1].strip().count('now'): - self.nextLine() - self.writeln( - 'Broadcast message from root@%s (pts/0) (%s):' % \ + self.write('\n') + self.write( + 'Broadcast message from root@%s (pts/0) (%s):\n' % \ (self.protocol.hostname, time.ctime())) - self.nextLine() - self.writeln('The system is going down for maintenance NOW!') + self.write('\n') + self.write('The system is going down for maintenance NOW!\n') reactor.callLater(3, self.finish) elif len(self.args) > 1 and self.args[0].strip().count('-r') \ and self.args[1].strip().count('now'): - self.nextLine() - self.writeln( - 'Broadcast message from root@%s (pts/0) (%s):' % \ + self.write('\n') + self.write( + 'Broadcast message from root@%s (pts/0) (%s):\n' % \ (self.protocol.hostname, time.ctime())) - self.nextLine() - self.writeln('The system is going down for reboot NOW!') + self.write('\n') + self.write('The system is going down for reboot NOW!\n') reactor.callLater(3, self.finish) else: - self.writeln("Try `shutdown --help' for more information.") + self.write("Try `shutdown --help' for more information.\n") self.exit() return @@ -380,7 +382,7 @@ class command_shutdown(HoneyPotCommand): def finish(self): """ """ - self.writeln('Connection to server closed.') + self.write('Connection to server closed.\n') self.protocol.hostname = 'localhost' self.protocol.cwd = '/root' if not self.fs.exists(self.protocol.cwd): @@ -399,19 +401,18 @@ class command_reboot(HoneyPotCommand): def start(self): """ """ - self.nextLine() - self.writeln( - 'Broadcast message from root@%s (pts/0) (%s):' % \ + self.write('\n') + self.write( + 'Broadcast message from root@%s (pts/0) (%s):\n\n' % \ (self.protocol.hostname, time.ctime())) - self.nextLine() - self.writeln('The system is going down for reboot NOW!') + self.write('The system is going down for reboot NOW!\n') reactor.callLater(3, self.finish) def finish(self): """ """ - self.writeln('Connection to server closed.') + self.write('Connection to server closed.\n') self.protocol.hostname = 'localhost' self.protocol.cwd = '/root' if not self.fs.exists(self.protocol.cwd): @@ -435,7 +436,7 @@ class command_history(HoneyPotCommand): return count = 1 for l in self.protocol.historyLines: - self.writeln(' %s %s' % (str(count).rjust(4), l)) + self.write(' %s %s\n' % (str(count).rjust(4), l)) count += 1 except: # Non-interactive shell, do nothing @@ -451,7 +452,7 @@ class command_date(HoneyPotCommand): """ """ time = datetime.datetime.utcnow(); - self.writeln(time.strftime("%a %b %d %H:%M:%S UTC %Y")) + self.write(time.strftime("%a %b %d %H:%M:%S UTC %Y")+'\n') commands['/bin/date'] = command_date @@ -468,7 +469,7 @@ class command_yes(HoneyPotCommand): def y(self): """ """ - self.writeln('y') + self.write('y\n') self.scheduled = reactor.callLater(0.01, self.y) @@ -501,14 +502,14 @@ class command_chmod(HoneyPotCommand): """ """ if len(self.args) < 2: - self.writeln('chmod: missing operand') - self.writeln('Try chmod --help for more information.') + self.write('chmod: missing operand\n') + self.write('Try chmod --help for more information.\n') return for arg in self.args[1:]: path = self.fs.resolve_path(arg, self.protocol.cwd) if not self.fs.exists(path): - self.writeln( - 'chmod: cannot access %s: No such file or directory' % \ + self.write( + 'chmod: cannot access %s: No such file or directory\n' % \ (arg,)) commands['/bin/chmod'] = command_chmod @@ -538,7 +539,7 @@ class command_perl(HoneyPotCommand): '' ) for l in output: - self.writeln(l) + self.write(l+'\n') self.exit() elif self.args[0] == '-h': output = ( @@ -575,7 +576,7 @@ class command_perl(HoneyPotCommand): '' ) for l in output: - self.writeln(l) + self.write(l+'\n') self.exit() else: self.exit() @@ -611,7 +612,7 @@ class command_php(HoneyPotCommand): 'Copyright (c) 1997-2010 The PHP Group' ) for l in output: - self.writeln(l) + self.write(l+'\n') self.exit() elif self.args[0] == '-h': output = ( @@ -655,7 +656,7 @@ class command_php(HoneyPotCommand): '' ) for l in output: - self.writeln(l) + self.write(l+'\n') self.exit() else: self.exit() @@ -684,13 +685,13 @@ class command_chattr(HoneyPotCommand): """ """ if len(self.args) < 1: - self.writeln('Usage: chattr [-RVf] [-+=AacDdeijsSu] [-v version] files...') + self.write('Usage: chattr [-RVf] [-+=AacDdeijsSu] [-v version] files...\n') return elif len(self.args) < 2: - self.writeln("Must use '-v', =, - or +'") + self.write("Must use '-v', =, - or +'\n") return if not self.fs.exists(self.args[1]): - self.writeln('chattr: No such file or directory while trying to stat ' + self.args[1]) + self.write('chattr: No such file or directory while trying to stat ' + self.args[1] + '\n') return commands['/usr/bin/chattr'] = command_chattr diff --git a/cowrie/commands/busybox.py b/cowrie/commands/busybox.py index 72e2a0d..cde3123 100644 --- a/cowrie/commands/busybox.py +++ b/cowrie/commands/busybox.py @@ -55,7 +55,7 @@ class command_busybox(HoneyPotCommand): """ """ for ln in busybox_help: - self.writeln(ln) + self.write(ln+'\n') def call(self): diff --git a/cowrie/commands/curl.py b/cowrie/commands/curl.py index cf22d10..bd673c5 100644 --- a/cowrie/commands/curl.py +++ b/cowrie/commands/curl.py @@ -35,7 +35,7 @@ class command_curl(HoneyPotCommand): optlist, args = getopt.getopt(self.args, 'ho:O', [ 'help', 'manual' ] ) except getopt.GetoptError as err: - self.writeln('Unrecognized option') + self.write('Unrecognized option\n') for opt in optlist: if opt[0] == '-h' or opt[0] == '--help': @@ -46,7 +46,7 @@ class command_curl(HoneyPotCommand): if args[0] is not None: url = str(args[0]).strip() else: - self.writeln("curl: try 'curl --help' or 'curl --manual' for more information'") + self.write("curl: try 'curl --help' or 'curl --manual' for more information'\n") self.exit() return @@ -61,7 +61,7 @@ class command_curl(HoneyPotCommand): if opt[0] == '-O': outfile = urldata.path.split('/')[-1] if outfile is None or not len(outfile.strip()) or not urldata.path.count('/'): - self.writeln('curl: Remote file name has no length!') + self.write('curl: Remote file name has no length!\n') self.exit() return @@ -71,7 +71,7 @@ class command_curl(HoneyPotCommand): if not path or \ not self.fs.exists(path) or \ not self.fs.isdir(path): - self.writeln('curl: %s: Cannot open: No such file or directory' % \ + self.write('curl: %s: Cannot open: No such file or directory\n' % \ (outfile,)) self.exit() return @@ -98,7 +98,7 @@ class command_curl(HoneyPotCommand): """ """ - self.writeln("""Usage: curl [options...] + self.write("""Usage: curl [options...] Options: (H) means HTTP/HTTPS only, (F) means FTP only --anyauth Pick "any" authentication method (H) -a, --append Append to target file when uploading (F/SFTP) @@ -251,7 +251,7 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only -V, --version Show version number and quit -w, --write-out FORMAT What to output after completion --xattr Store metadata in extended file attributes - -q If used as the first parameter disables .curlrc""") + -q If used as the first parameter disables .curlrc\n""") self.exit() @@ -267,7 +267,7 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only if scheme != 'http' and scheme != 'https': raise exceptions.NotImplementedError except: - self.writeln('%s: Unsupported scheme.' % (url,)) + self.write('%s: Unsupported scheme.\n' % (url,)) self.exit() return None @@ -291,7 +291,7 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only def handle_CTRL_C(self): """ """ - self.writeln('^C') + self.write('^C\n') self.connection.transport.loseConnection() @@ -336,9 +336,9 @@ Options: (H) means HTTP/HTTPS only, (F) means FTP only """ if hasattr(error, 'getErrorMessage'): # Exceptions error = error.getErrorMessage() - self.writeln(error) + self.write(error+'\n') # Real curl also adds this: - # self.writeln('%s ERROR 404: Not Found.' % \ + # self.write('%s ERROR 404: Not Found.\n' % \ # time.strftime('%Y-%m-%d %T')) self.exit() commands['/usr/bin/curl'] = command_curl @@ -394,8 +394,8 @@ class HTTPProgressDownloader(client.HTTPDownloader): self.nomore = True if self.fakeoutfile: - self.curl.writeln(' % Total % Received % Xferd Average Speed Time Time Time Current') - self.curl.writeln(' Dload Upload Total Spent Left Speed') + self.curl.write(' % Total % Received % Xferd Average Speed Time Time Time Current\n') + self.curl.write(' Dload Upload Total Spent Left Speed\n') return client.HTTPDownloader.gotHeaders(self, headers) @@ -435,7 +435,7 @@ class HTTPProgressDownloader(client.HTTPDownloader): return client.HTTPDownloader.pageEnd(self) if self.fakeoutfile: - self.curl.writeln("\r100 %d 100 %d 0 0 %d 0 --:--:-- --:--:-- --:--:-- %d" % \ + self.curl.write("\r100 %d 100 %d 0 0 %d 0 --:--:-- --:--:-- --:--:-- %d\n" % \ (self.currentlength, self.currentlength , 63673, 65181) ) @@ -445,7 +445,7 @@ class HTTPProgressDownloader(client.HTTPDownloader): self.curl.safeoutfile) else: with open(self.curl.safeoutfile, 'r') as f: - self.curl.writeln(f.read()) + self.curl.write(f.read()+'\n') self.curl.fileName = self.fileName return client.HTTPDownloader.pageEnd(self) diff --git a/cowrie/commands/env.py b/cowrie/commands/env.py index 7310688..979671d 100644 --- a/cowrie/commands/env.py +++ b/cowrie/commands/env.py @@ -43,7 +43,7 @@ class command_env(HoneyPotCommand): """ """ for i in list(self.environ.keys()): - self.writeln("%s=%s" % (i,self.environ[i])) + self.write("%s=%s\n" % (i,self.environ[i])) self.exit() diff --git a/cowrie/commands/ethtool.py b/cowrie/commands/ethtool.py index abe9736..c70420d 100644 --- a/cowrie/commands/ethtool.py +++ b/cowrie/commands/ethtool.py @@ -20,15 +20,15 @@ class command_ethtool(HoneyPotCommand): def do_ethtool_help(self): """No real help output.""" - self.writeln("""ethtool: bad command line argument(s) -For more information run ethtool -h """) + self.write("""ethtool: bad command line argument(s) +For more information run ethtool -h\n""") def do_ethtool_lo(self): - self.writeln("""Settings for lo: - Link detected: yes""") + self.write("""Settings for lo: + Link detected: yes\n""") def do_ethtool_eth0(self): - self.writeln("""Settings for eth0: + self.write("""Settings for eth0: Supported ports: [ TP MII ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full @@ -55,15 +55,15 @@ Supports Wake-on: pumbg Wake-on: g Current message level: 0x00000033 (51) drv probe ifdown ifup -Link detected: yes""") +Link detected: yes\n""") def do_ethtool_eth1(self): - self.writeln("""Settings for eth1: + self.write("""Settings for eth1: Cannot get device settings: No such device Cannot get wake-on-lan settings: No such device Cannot get message level: No such device Cannot get link status: No such device -No data available""") +No data available\n""") commands['/sbin/ethtool'] = command_ethtool diff --git a/cowrie/commands/free.py b/cowrie/commands/free.py index ab2e343..066291e 100644 --- a/cowrie/commands/free.py +++ b/cowrie/commands/free.py @@ -56,11 +56,11 @@ class command_free(HoneyPotCommand): print free statistics """ if fmt=='bytes': - self.writeln(FREE_BYTES) + self.write(FREE_BYTES+'\n') elif fmt=='megabytes': - self.writeln(FREE_MEGA) + self.write(FREE_MEGA+'\n') elif fmt=='human': - self.writeln(FREE_HUMAN) + self.write(FREE_HUMAN+'\n') commands['/usr/bin/free'] = command_free diff --git a/cowrie/commands/fs.py b/cowrie/commands/fs.py index 8b2e596..1402830 100644 --- a/cowrie/commands/fs.py +++ b/cowrie/commands/fs.py @@ -20,12 +20,12 @@ class command_cat(HoneyPotCommand): for arg in self.args: path = self.fs.resolve_path(arg, self.protocol.cwd) if self.fs.isdir(path): - self.writeln('cat: %s: Is a directory' % (arg,)) + self.write('cat: %s: Is a directory\n' % (arg,)) continue try: self.write(self.fs.file_contents(path)) except: - self.writeln('cat: %s: No such file or directory' % (arg,)) + self.write('cat: %s: No such file or directory\n' % (arg,)) self.exit() @@ -49,7 +49,7 @@ class command_tail(HoneyPotCommand): try: optlist, args = getopt.getopt(self.args, 'n:') except getopt.GetoptError as err: - self.writeln("tail: invalid option -- '%s'" % (arg,)) + self.write("tail: invalid option -- '%s'\n" % (arg,)) self.exit() return @@ -60,7 +60,7 @@ class command_tail(HoneyPotCommand): for arg in args: path = self.fs.resolve_path(arg, self.protocol.cwd) if self.fs.isdir(path): - self.writeln("tail: error reading `%s': Is a directory" % (arg,)) + self.write("tail: error reading `%s': Is a directory\n" % (arg,)) continue try: file = self.fs.file_contents(path).split('\n') @@ -70,10 +70,10 @@ class command_tail(HoneyPotCommand): i = 0 for j in range((lines - self.n - 1), lines): if i < self.n: - self.writeln(file[j]) + self.write(file[j]+'\n') i += 1 except: - self.writeln("tail: cannot open `%s' for reading: No such file or directory" % (arg,)) + self.write("tail: cannot open `%s' for reading: No such file or directory\n" % (arg,)) self.exit() @@ -99,7 +99,7 @@ class command_head(HoneyPotCommand): try: optlist, args = getopt.getopt(self.args, 'n:') except getopt.GetoptError as err: - self.writeln("head: invalid option -- '%s'" % (arg,)) + self.write("head: invalid option -- '%s'\n" % (arg,)) self.exit() return @@ -110,17 +110,17 @@ class command_head(HoneyPotCommand): for arg in args: path = self.fs.resolve_path(arg, self.protocol.cwd) if self.fs.isdir(path): - self.writeln("head: error reading `%s': Is a directory" % (arg,)) + self.write("head: error reading `%s': Is a directory\n" % (arg,)) continue try: file = self.fs.file_contents(path).split('\n') i = 0 for line in file: if i < self.n: - self.writeln(line) + self.write(line+'\n') i += 1 except: - self.writeln("head: cannot open `%s' for reading: No such file or directory" % (arg,)) + self.write("head: cannot open `%s' for reading: No such file or directory\n" % (arg,)) self.exit() @@ -149,13 +149,13 @@ class command_cd(HoneyPotCommand): except: newdir = None if path == "-": - self.writeln('bash: cd: OLDPWD not set') + self.write('bash: cd: OLDPWD not set\n') return if inode is None or inode is False: - self.writeln('bash: cd: %s: No such file or directory' % (path,)) + self.write('bash: cd: %s: No such file or directory\n' % (path,)) return if inode[A_TYPE] != T_DIR: - self.writeln('bash: cd: %s: Not a directory' % (path,)) + self.write('bash: cd: %s: Not a directory\n' % (path,)) return self.protocol.cwd = newpath commands['cd'] = command_cd @@ -173,16 +173,16 @@ class command_rm(HoneyPotCommand): try: dir = self.fs.get_path('/'.join(path.split('/')[:-1])) except (IndexError, FileNotFound): - self.writeln( - 'rm: cannot remove `%s\': No such file or directory' % f) + self.write( + 'rm: cannot remove `%s\': No such file or directory\n' % f) continue basename = path.split('/')[-1] contents = [x for x in dir] for i in dir[:]: if i[A_NAME] == basename: if i[A_TYPE] == T_DIR and not recursive: - self.writeln( - 'rm: cannot remove `%s\': Is a directory' % \ + self.write( + 'rm: cannot remove `%s\': Is a directory\n' % \ i[A_NAME]) else: dir.remove(i) @@ -195,14 +195,14 @@ class command_cp(HoneyPotCommand): """ def call(self): if not len(self.args): - self.writeln("cp: missing file operand") - self.writeln("Try `cp --help' for more information.") + self.write("cp: missing file operand\n") + self.write("Try `cp --help' for more information.\n") return try: optlist, args = getopt.gnu_getopt(self.args, '-abdfiHlLPpRrsStTuvx') except getopt.GetoptError as err: - self.writeln('Unrecognized option') + self.write('Unrecognized option\n') return recursive = False for opt in optlist: @@ -213,19 +213,19 @@ class command_cp(HoneyPotCommand): return self.fs.resolve_path(path, self.protocol.cwd) if len(args) < 2: - self.writeln("cp: missing destination file operand after `%s'" % \ + self.write("cp: missing destination file operand after `%s'\n" % \ (self.args[0],)) - self.writeln("Try `cp --help' for more information.") + self.write("Try `cp --help' for more information.\n") return sources, dest = args[:-1], args[-1] if len(sources) > 1 and not self.fs.isdir(resolv(dest)): - self.writeln("cp: target `%s' is not a directory" % (dest,)) + self.write("cp: target `%s' is not a directory\n" % (dest,)) return if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \ not recursive: - self.writeln( - "cp: cannot create regular file `%s': Is a directory" % \ + self.write( + "cp: cannot create regular file `%s': Is a directory\n" % \ (dest,)) return @@ -235,17 +235,17 @@ class command_cp(HoneyPotCommand): isdir = False parent = os.path.dirname(resolv(dest)) if not self.fs.exists(parent): - self.writeln("cp: cannot create regular file " + \ - "`%s': No such file or directory" % (dest,)) + self.write("cp: cannot create regular file " + \ + "`%s': No such file or directory\n" % (dest,)) return for src in sources: if not self.fs.exists(resolv(src)): - self.writeln( - "cp: cannot stat `%s': No such file or directory" % (src,)) + self.write( + "cp: cannot stat `%s': No such file or directory\n" % (src,)) continue if not recursive and self.fs.isdir(resolv(src)): - self.writeln("cp: omitting directory `%s'" % (src,)) + self.write("cp: omitting directory `%s'\n" % (src,)) continue s = copy.deepcopy(self.fs.getfile(resolv(src))) if isdir: @@ -267,33 +267,33 @@ class command_mv(HoneyPotCommand): """ def call(self): if not len(self.args): - self.writeln("mv: missing file operand") - self.writeln("Try `mv --help' for more information.") + self.write("mv: missing file operand\n") + self.write("Try `mv --help' for more information.\n") return try: optlist, args = getopt.gnu_getopt(self.args, '-bfiStTuv') except getopt.GetoptError as err: - self.writeln('Unrecognized option') + self.write('Unrecognized option\n') self.exit() def resolv(path): return self.fs.resolve_path(path, self.protocol.cwd) if len(args) < 2: - self.writeln("mv: missing destination file operand after `%s'" % \ + self.write("mv: missing destination file operand after `%s'\n" % \ (self.args[0],)) - self.writeln("Try `mv --help' for more information.") + self.write("Try `mv --help' for more information.\n") return sources, dest = args[:-1], args[-1] if len(sources) > 1 and not self.fs.isdir(resolv(dest)): - self.writeln("mv: target `%s' is not a directory" % (dest,)) + self.write("mv: target `%s' is not a directory\n" % (dest,)) return if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \ len(sources) != 1: - self.writeln( - "mv: cannot create regular file `%s': Is a directory" % \ + self.write( + "mv: cannot create regular file `%s': Is a directory\n" % \ (dest,)) return @@ -303,15 +303,15 @@ class command_mv(HoneyPotCommand): isdir = False parent = os.path.dirname(resolv(dest)) if not self.fs.exists(parent): - self.writeln("mv: cannot create regular file " + \ - "`%s': No such file or directory" % \ + self.write("mv: cannot create regular file " + \ + "`%s': No such file or directory\n" % \ (dest,)) return for src in sources: if not self.fs.exists(resolv(src)): - self.writeln( - "mv: cannot stat `%s': No such file or directory" % \ + self.write( + "mv: cannot stat `%s': No such file or directory\n" % \ (src,)) continue s = self.fs.getfile(resolv(src)) @@ -339,15 +339,15 @@ class command_mkdir(HoneyPotCommand): for f in self.args: path = self.fs.resolve_path(f, self.protocol.cwd) if self.fs.exists(path): - self.writeln( - 'mkdir: cannot create directory `%s\': File exists' % f) + self.write( + 'mkdir: cannot create directory `%s\': File exists\n' % f) return try: self.fs.mkdir(path, 0, 0, 4096, 16877) except (FileNotFound) as err: - self.writeln( + self.write( 'mkdir: cannot create directory `%s\': ' % f + \ - 'No such file or directory') + 'No such file or directory\n') return commands['/bin/mkdir'] = command_mkdir @@ -361,22 +361,22 @@ class command_rmdir(HoneyPotCommand): path = self.fs.resolve_path(f, self.protocol.cwd) try: if len(self.fs.get_path(path)): - self.writeln( - 'rmdir: failed to remove `%s\': Directory not empty' % f) + self.write( + 'rmdir: failed to remove `%s\': Directory not empty\n' % f) continue dir = self.fs.get_path('/'.join(path.split('/')[:-1])) except (IndexError, FileNotFound): dir = None fname = os.path.basename(f) if not dir or fname not in [x[A_NAME] for x in dir]: - self.writeln( + self.write( 'rmdir: failed to remove `%s\': ' % f + \ - 'No such file or directory') + 'No such file or directory\n') continue for i in dir[:]: if i[A_NAME] == fname: if i[A_TYPE] != T_DIR: - self.writeln("rmdir: failed to remove '%s': Not a directory" % f) + self.write("rmdir: failed to remove '%s': Not a directory\n" % f) return dir.remove(i) break @@ -388,7 +388,7 @@ class command_pwd(HoneyPotCommand): """ """ def call(self): - self.writeln(self.protocol.cwd) + self.write(self.protocol.cwd+'\n') commands['/bin/pwd'] = command_pwd @@ -398,14 +398,14 @@ class command_touch(HoneyPotCommand): """ def call(self): if not len(self.args): - self.writeln('touch: missing file operand') - self.writeln('Try `touch --help\' for more information.') + self.write('touch: missing file operand\n') + self.write('Try `touch --help\' for more information.\n') return for f in self.args: path = self.fs.resolve_path(f, self.protocol.cwd) if not self.fs.exists(os.path.dirname(path)): - self.writeln( - 'touch: cannot touch `%s`: no such file or directory' % \ + self.write( + 'touch: cannot touch `%s`: no such file or directory\n' % \ (path,)) return if self.fs.exists(path): diff --git a/cowrie/commands/gcc.py b/cowrie/commands/gcc.py index 21596fa..836f189 100644 --- a/cowrie/commands/gcc.py +++ b/cowrie/commands/gcc.py @@ -110,7 +110,7 @@ class command_gcc(HoneyPotCommand): if self.fs.exists(sourcefile): input_files = input_files + 1 else: - self.writeln("%s: %s: No such file or directory" % (command_gcc.APP_NAME, value)) + self.write("%s: %s: No such file or directory\n" % (command_gcc.APP_NAME, value)) complete = False # To generate, or not @@ -131,8 +131,8 @@ class command_gcc(HoneyPotCommand): def no_files(self): """ Notify user there are no input files, and exit """ - self.writeln( """gcc: fatal error: no input files -compilation terminated.""" ) + self.write( """gcc: fatal error: no input files +compilation terminated.\n""" ) self.exit() @@ -158,7 +158,7 @@ Thread model: posix gcc version %s (Debian %s-5)""" % (version, version_short, version_short, version_short, version, version)) # Write - self.writeln(data) + self.write(data+'\n') self.exit() def generate_file(self, outfile): @@ -200,7 +200,7 @@ gcc version %s (Debian %s-5)""" % (version, version_short, version_short, versio def arg_missing(self, arg): """ Print missing argument message, and exit """ - self.writeln("%s: argument to '%s' is missing" % (command_gcc.APP_NAME, arg)) + self.write("%s: argument to '%s' is missing\n" % (command_gcc.APP_NAME, arg)) self.exit() def help(self): @@ -208,7 +208,7 @@ gcc version %s (Debian %s-5)""" % (version, version_short, version_short, versio version = '.'.join([ str(v) for v in command_gcc.APP_VERSION[:2] ]) - self.writeln( """Usage: gcc [options] file... + self.write( """Usage: gcc [options] file... Options: -pass-exit-codes Exit with highest error code from a phase --help Display this information @@ -267,7 +267,8 @@ Options starting with -g, -f, -m, -O, -W, or --param are automatically other options on to these processes the -W options must be used. For bug reporting instructions, please see: -.""") +. +""") self.exit() # Definitions diff --git a/cowrie/commands/ifconfig.py b/cowrie/commands/ifconfig.py index e543043..66050b7 100644 --- a/cowrie/commands/ifconfig.py +++ b/cowrie/commands/ifconfig.py @@ -29,7 +29,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.writeln(l) + self.write(l+'\n') commands['/sbin/ifconfig'] = command_ifconfig diff --git a/cowrie/commands/iptables.py b/cowrie/commands/iptables.py index 9e8288b..7bb8a12 100644 --- a/cowrie/commands/iptables.py +++ b/cowrie/commands/iptables.py @@ -199,8 +199,8 @@ class command_iptables(HoneyPotCommand): if self.user_is_root(): # Verify table existence if not table in self.tables.iterkeys(): - self.writeln( """%s: can\'t initialize iptables table \'%s\': Table does not exist (do you need to insmod?) -Perhaps iptables or your kernel needs to be upgraded.""" % (command_iptables.APP_NAME, table) ) + self.write( """%s: can\'t initialize iptables table \'%s\': Table does not exist (do you need to insmod?) +Perhaps iptables or your kernel needs to be upgraded.\n""" % (command_iptables.APP_NAME, table) ) self.exit() else: # Exists @@ -214,7 +214,7 @@ Perhaps iptables or your kernel needs to be upgraded.""" % (command_iptables.APP def is_valid_chain(self, chain): # Verify chain existence. Requires valid table first if not chain in self.current_table.iterkeys(): - self.writeln("%s: No chain/target/match by that name." % command_iptables.APP_NAME) + self.write("%s: No chain/target/match by that name.\n" % command_iptables.APP_NAME) self.exit() return False @@ -223,13 +223,13 @@ Perhaps iptables or your kernel needs to be upgraded.""" % (command_iptables.APP def show_version(self): """ Show version and exit """ - self.writeln('%s %s' % (command_iptables.APP_NAME, command_iptables.APP_VERSION)) + self.write('%s %s\n' % (command_iptables.APP_NAME, command_iptables.APP_VERSION)) self.exit() def show_help(self): """ Show help and exit """ - self.writeln( """%s %s' + self.write( """%s %s' Usage: iptables -[AD] chain rule-specification [options] iptables -I chain [rulenum] rule-specification [options] @@ -291,7 +291,7 @@ Options: [!] --fragment -f match second or further fragments only --modprobe= try to insert modules using this command --set-counters PKTS BYTES set the counter during insert/append -[!] --version -V print package version.""" % (command_iptables.APP_NAME, command_iptables.APP_VERSION)) +[!] --version -V print package version.\n""" % (command_iptables.APP_NAME, command_iptables.APP_VERSION)) self.exit() def list_rules(self, chain): @@ -315,7 +315,7 @@ Options: output.append("-P %s ACCEPT" % chain) # Done - self.writeln(output) + self.write(output+'\n') self.exit() else: self.no_permission() @@ -354,7 +354,7 @@ Options: output.append("\n".join(chain_output)) # Done - self.writeln("\n\n".join(output)) + self.write("\n\n".join(output)+'\n') self.exit() else: self.no_permission() @@ -381,32 +381,32 @@ Options: self.no_permission() def no_permission(self): - self.writeln( """%s %s: can\'t initialize iptables table \'filter\': Permission denied (you must be root) -Perhaps iptables or your kernel needs to be upgraded.""" + self.write( """%s %s: can\'t initialize iptables table \'filter\': Permission denied (you must be root) +Perhaps iptables or your kernel needs to be upgraded.\n""" % (command_iptables.APP_NAME, command_iptables.APP_VERSION) ) self.exit() def no_command(self): """ Print no command message and exit """ - self.writeln( """%s %s: no command specified' -Try `iptables -h\' or \'iptables --help\' for more information.""" + self.write( """%s %s: no command specified' +Try `iptables -h\' or \'iptables --help\' for more information.\n""" % (command_iptables.APP_NAME, command_iptables.APP_VERSION) ) self.exit() def unknown_option(self, option): """ Print unknown option message and exit """ - self.writeln( """%s %s: unknown option \'%s\'' -Try `iptables -h\' or \'iptables --help\' for more information.""" + self.write( """%s %s: unknown option \'%s\'' +Try `iptables -h\' or \'iptables --help\' for more information.\n""" % (command_iptables.APP_NAME, command_iptables.APP_VERSION, option) ) self.exit() def bad_argument(self, argument): """ Print bad argument and exit """ - self.writeln( """Bad argument \'%s\' -Try `iptables -h\' or \'iptables --help\' for more information.""" + self.write( """Bad argument \'%s\' +Try `iptables -h\' or \'iptables --help\' for more information.\n""" % argument ) self.exit() diff --git a/cowrie/commands/last.py b/cowrie/commands/last.py index 3425d8f..3fe0e57 100644 --- a/cowrie/commands/last.py +++ b/cowrie/commands/last.py @@ -23,7 +23,7 @@ class command_last(HoneyPotCommand): elif arg == '-n' and len(l) and l[0].isdigit(): numlines = int(l.pop(0)) data = utils.tail(file(fn), numlines) - self.writeln(''.join(data)) + self.write(''.join(data)+'\n') commands['/usr/bin/last'] = command_last # vim: set sw=4 et: diff --git a/cowrie/commands/ls.py b/cowrie/commands/ls.py index e977c86..3e593ec 100644 --- a/cowrie/commands/ls.py +++ b/cowrie/commands/ls.py @@ -66,8 +66,8 @@ class command_ls(HoneyPotCommand): files = self.protocol.fs.get_path(path) files.sort() except: - self.writeln( - 'ls: cannot access %s: No such file or directory' % (path,)) + self.write( + 'ls: cannot access %s: No such file or directory\n' % (path,)) return l = [x[A_NAME] for x in files \ if self.show_hidden or not x[A_NAME].startswith('.')] @@ -88,10 +88,10 @@ class command_ls(HoneyPotCommand): for f in l: if count == perline: count = 0 - self.nextLine() + self.write('\n') self.write(f.ljust(maxlen + 1)) count += 1 - self.nextLine() + self.write('\n') def do_ls_l(self, path): @@ -101,8 +101,8 @@ class command_ls(HoneyPotCommand): files = self.protocol.fs.get_path(path)[:] files.sort() except: - self.writeln( - 'ls: cannot access %s: No such file or directory' % (path,)) + self.write( + 'ls: cannot access %s: No such file or directory\n' % (path,)) return largest = 0 @@ -149,7 +149,7 @@ class command_ls(HoneyPotCommand): file[A_NAME], linktarget) - self.writeln(l) + self.write(l+'\n') commands['/bin/ls'] = command_ls commands['/bin/dir'] = command_ls diff --git a/cowrie/commands/netstat.py b/cowrie/commands/netstat.py index 89669ea..0af508c 100644 --- a/cowrie/commands/netstat.py +++ b/cowrie/commands/netstat.py @@ -9,15 +9,15 @@ commands = {} class command_netstat(HoneyPotCommand): def show_version(self): - self.writeln('net-tools 1.60') - self.writeln('netstat 1.42 (2001-04-15)') - self.writeln('Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others') - self.writeln('+NEW_ADDRT +RTF_IRTT +RTF_REJECT +FW_MASQUERADE +I18N') - self.writeln('AF: (inet) +UNIX +INET +INET6 +IPX +AX25 +NETROM +X25 +ATALK +ECONET +ROSE') - self.writeln('HW: +ETHER +ARC +SLIP +PPP +TUNNEL +TR +AX25 +NETROM +X25 +FR +ROSE +ASH +SIT +FDDI +HIPPI +HDLC/LAPB +EUI64') + self.write('net-tools 1.60\n') + self.write('netstat 1.42 (2001-04-15)\n') + self.write('Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang and others\n') + self.write('+NEW_ADDRT +RTF_IRTT +RTF_REJECT +FW_MASQUERADE +I18N\n') + self.write('AF: (inet) +UNIX +INET +INET6 +IPX +AX25 +NETROM +X25 +ATALK +ECONET +ROSE\n') + self.write('HW: +ETHER +ARC +SLIP +PPP +TUNNEL +TR +AX25 +NETROM +X25 +FR +ROSE +ASH +SIT +FDDI +HIPPI +HDLC/LAPB +EUI64\n') def show_help(self): - self.writeln(""" + self.write(""" usage: netstat [-vWeenNcCF] [] -r netstat {-V|--version|-h|--help} netstat [-vWnNcaeol] [ ...] netstat { [-vWeenNac] -i | [-cWnNe] -M | -s } @@ -50,11 +50,12 @@ usage: netstat [-vWeenNcCF] [] -r netstat {-V|--version|-h|--help} List of possible address families (which support routing): inet (DARPA Internet) inet6 (IPv6) ax25 (AMPR AX.25) netrom (AMPR NET/ROM) ipx (Novell IPX) ddp (Appletalk DDP) - x25 (CCITT X.25)""") + x25 (CCITT X.25) +""") def do_netstat_route(self): - self.writeln("""Kernel IP routing table -Destination Gateway Genmask Flags MSS Window irtt Iface""") + self.write("""Kernel IP routing table +Destination Gateway Genmask Flags MSS Window irtt Iface\n""") if self.show_numeric: default = "default" lgateway = "0.0.0.0" @@ -69,12 +70,12 @@ Destination Gateway Genmask Flags MSS Window irtt Iface"" l2 = "%s%s255.255.255.0 U 0 0 0 eth0" % \ ('{:<16}'.format(destination), '{:<16}'.format(lgateway)) - self.writeln(l1) - self.writeln(l2) + self.write(l1+'\n') + self.write(l2+'\n') def do_netstat_normal(self): - self.writeln("""Active Internet connections (w/o servers) -Proto Recv-Q Send-Q Local Address Foreign Address State""") + self.write("""Active Internet connections (w/o servers) +Proto Recv-Q Send-Q Local Address Foreign Address State\n""") s_name = self.protocol.hostname c_port = str(self.protocol.realClientPort) if self.show_numeric: @@ -85,24 +86,24 @@ Proto Recv-Q Send-Q Local Address Foreign Address State""") s_port = "ssh" c_name = socket.gethostbyaddr(self.protocol.clientIP)[0][:17] if self.show_listen or self.show_all: - self.writeln("tcp 0 0 *:ssh *:* LISTEN") + 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), "ESTABLISHED") - self.writeln(l) + self.write(l+'\n') if self.show_listen or self.show_all: - self.writeln("tcp6 0 0 [::]:ssh [::]:* LISTEN") - self.writeln("""Active UNIX domain sockets (only servers) -Proto RefCnt Flags Type State I-Node Path""") + self.write("tcp6 0 0 [::]:ssh [::]:* LISTEN\n") + self.write("""Active UNIX domain sockets (only servers) +Proto RefCnt Flags Type State I-Node Path\n""") if self.show_listen: - self.writeln("""unix 2 [ ACC ] STREAM LISTENING 8969 /var/run/acpid.socket + self.write("""unix 2 [ ACC ] STREAM LISTENING 8969 /var/run/acpid.socket unix 2 [ ACC ] STREAM LISTENING 6807 @/com/ubuntu/upstart unix 2 [ ACC ] STREAM LISTENING 7299 /var/run/dbus/system_bus_socket -unix 2 [ ACC ] SEQPACKET LISTENING 7159 /run/udev/control""") +unix 2 [ ACC ] SEQPACKET LISTENING 7159 /run/udev/control\n""") elif self.show_all: - self.writeln("""unix 2 [ ACC ] STREAM LISTENING 8969 /var/run/acpid.socket + self.write("""unix 2 [ ACC ] STREAM LISTENING 8969 /var/run/acpid.socket unix 4 [ ] DGRAM 7445 /dev/log unix 2 [ ACC ] STREAM LISTENING 6807 @/com/ubuntu/upstart unix 2 [ ACC ] STREAM LISTENING 7299 /var/run/dbus/system_bus_socket @@ -122,9 +123,9 @@ unix 3 [ ] STREAM CONNECTED 7364 @/com/ubuntu/upstart unix 3 [ ] STREAM CONNECTED 7423 unix 3 [ ] DGRAM 7198 unix 2 [ ] DGRAM 9570 -unix 3 [ ] STREAM CONNECTED 8619 @/com/ubuntu/upstart""") +unix 3 [ ] STREAM CONNECTED 8619 @/com/ubuntu/upstart\n""") else: - self.writeln("""unix 4 [ ] DGRAM 7445 /dev/log + self.write("""unix 4 [ ] DGRAM 7445 /dev/log unix 3 [ ] STREAM CONNECTED 7323 unix 3 [ ] STREAM CONNECTED 7348 /var/run/dbus/system_bus_socket unix 3 [ ] STREAM CONNECTED 7330 @@ -140,7 +141,7 @@ unix 3 [ ] STREAM CONNECTED 7364 @/com/ubuntu/upstart unix 3 [ ] STREAM CONNECTED 7423 unix 3 [ ] DGRAM 7198 unix 2 [ ] DGRAM 9570 -unix 3 [ ] STREAM CONNECTED 8619 @/com/ubuntu/upstart""") +unix 3 [ ] STREAM CONNECTED 8619 @/com/ubuntu/upstart\n""") def call(self): self.show_all = False diff --git a/cowrie/commands/nohup.py b/cowrie/commands/nohup.py index d5b8ff8..54177cb 100644 --- a/cowrie/commands/nohup.py +++ b/cowrie/commands/nohup.py @@ -13,14 +13,14 @@ commands = {} class command_nohup(HoneyPotCommand): def call(self): if not len(self.args): - self.writeln('nohup: missing operand') - self.writeln('Try `nohup --help\' for more information.') + self.write('nohup: missing operand\n') + self.write('Try `nohup --help\' for more information.\n') return path = self.fs.resolve_path("nohup.out", self.protocol.cwd) if self.fs.exists(path): return self.fs.mkfile(path, 0, 0, 0, 33188) - self.writeln("nohup: ignoring input and appending output to 'nohup.out'") + self.write("nohup: ignoring input and appending output to 'nohup.out'\n") commands['/usr/bin/nohup'] = command_nohup diff --git a/cowrie/commands/ping.py b/cowrie/commands/ping.py index 870e0bc..ec4382d 100644 --- a/cowrie/commands/ping.py +++ b/cowrie/commands/ping.py @@ -37,7 +37,7 @@ class command_ping(HoneyPotCommand): try: optlist, args = getopt.getopt(self.args, "c:") except getopt.GetoptError as err: - self.writeln('ping: %s' % (err,)) + self.write('ping: %s\n' % (err,)) self.exit() return @@ -48,7 +48,7 @@ class command_ping(HoneyPotCommand): except: self.max = 0 if self.max <= 0: - self.writeln('ping: bad number of packets to transmit.') + self.write('ping: bad number of packets to transmit.\n') self.exit() return @@ -61,7 +61,7 @@ class command_ping(HoneyPotCommand): ' [-M mtu discovery hint] [-S sndbuf]', ' [ -T timestamp option ] [ -Q tos ] [hop1 ...] destination', ): - self.writeln(l) + self.write(l+'\n') self.exit() return @@ -69,7 +69,7 @@ class command_ping(HoneyPotCommand): if self.valid_ip(self.host): self.ip = self.host else: - self.writeln('ping: unknown host %s' % (self.host,)) + self.write('ping: unknown host %s\n' % (self.host,)) self.exit() else: s = hashlib.md5(self.host).hexdigest() @@ -77,7 +77,7 @@ class command_ping(HoneyPotCommand): (s[0:2], s[2:4], s[4:6], s[6:8])]) self.running = True - self.writeln('PING %s (%s) 56(84) bytes of data.' % \ + self.write('PING %s (%s) 56(84) bytes of data.\n' % \ (self.host, self.ip)) self.scheduled = reactor.callLater(0.2, self.showreply) self.count = 0 @@ -87,13 +87,13 @@ class command_ping(HoneyPotCommand): """ """ ms = 40 + random.random() * 10 - self.writeln( - '64 bytes from %s (%s): icmp_seq=%d ttl=50 time=%.1f ms' % \ + self.write( + '64 bytes from %s (%s): icmp_seq=%d ttl=50 time=%.1f ms\n' % \ (self.host, self.ip, self.count + 1, ms)) self.count += 1 if self.count == self.max: self.running = False - self.writeln('') + self.write('\n') self.printstatistics() self.exit() else: @@ -103,10 +103,10 @@ class command_ping(HoneyPotCommand): def printstatistics(self): """ """ - self.writeln('--- %s ping statistics ---' % (self.host,)) - self.writeln('%d packets transmitted, %d received, 0%% packet loss, time 907ms' % \ + self.write('--- %s ping statistics ---\n' % (self.host,)) + self.write('%d packets transmitted, %d received, 0%% packet loss, time 907ms\n' % \ (self.count, self.count)) - self.writeln('rtt min/avg/max/mdev = 48.264/50.352/52.441/2.100 ms') + self.write('rtt min/avg/max/mdev = 48.264/50.352/52.441/2.100 ms\n') def handle_CTRL_C(self): @@ -115,7 +115,7 @@ class command_ping(HoneyPotCommand): if self.running == False: return HoneyPotCommand.handle_CTRL_C(self) else: - self.writeln('^C') + self.write('^C\n') self.scheduled.cancel() self.printstatistics() self.exit() diff --git a/cowrie/commands/scp.py b/cowrie/commands/scp.py index 092dcfd..3b59f75 100644 --- a/cowrie/commands/scp.py +++ b/cowrie/commands/scp.py @@ -39,10 +39,10 @@ class command_scp(HoneyPotCommand): def help(self): """ """ - self.writeln( + self.write( """usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-S program] - [[user@]host1:]file1 ... [[user@]host2:]file2""") + [[user@]host1:]file1 ... [[user@]host2:]file2\n""") def start(self): diff --git a/cowrie/commands/sleep.py b/cowrie/commands/sleep.py index 4d55905..56d352b 100644 --- a/cowrie/commands/sleep.py +++ b/cowrie/commands/sleep.py @@ -29,7 +29,7 @@ class command_sleep(HoneyPotCommand): _time = int( self.args[0] ) self.scheduled = reactor.callLater(_time, self.done) else: - self.writeln('usage: sleep seconds') + self.write('usage: sleep seconds\n') self.exit() diff --git a/cowrie/commands/ssh.py b/cowrie/commands/ssh.py index 79aa20c..5ae3f6a 100644 --- a/cowrie/commands/ssh.py +++ b/cowrie/commands/ssh.py @@ -38,11 +38,11 @@ class command_ssh(HoneyPotCommand): optlist, args = getopt.getopt(self.args, '-1246AaCfgKkMNnqsTtVvXxYb:c:D:e:F:i:L:l:m:O:o:p:R:S:w:') except getopt.GetoptError as err: - self.writeln('Unrecognized option') + self.write('Unrecognized option\n') self.exit() for opt in optlist: if opt[0] == '-V': - self.writeln('OpenSSH_6.7p1 Debian-5, OpenSSL 1.0.1k 8 Jan 2015') + self.write('OpenSSH_6.7p1 Debian-5, OpenSSL 1.0.1k 8 Jan 2015\n') self.exit() return if not len(args): @@ -54,7 +54,7 @@ class command_ssh(HoneyPotCommand): ' [-R [bind_address:]port:host:hostport] [-S ctl_path]', ' [-w local_tun[:remote_tun]] [user@]hostname [command]', ): - self.writeln(l) + self.write(l+'\n') self.exit() return user, host = 'root', args[0] @@ -68,7 +68,7 @@ class command_ssh(HoneyPotCommand): if self.valid_ip(host): self.ip = host else: - self.writeln('ssh: Could not resolve hostname %s: Name or service not known' % (host,)) + self.write('ssh: Could not resolve hostname %s: Name or service not known\n' % (host,)) self.exit() else: s = hashlib.md5(host).hexdigest() @@ -78,9 +78,9 @@ class command_ssh(HoneyPotCommand): self.host = host self.user = user - self.writeln('The authenticity of host \'%s (%s)\' can\'t be established.' % \ + self.write('The authenticity of host \'%s (%s)\' can\'t be established.\n' % \ (self.host, self.ip)) - self.writeln('RSA key fingerprint is 9d:30:97:8a:9e:48:0d:de:04:8d:76:3a:7b:4b:30:f8.') + self.write('RSA key fingerprint is 9d:30:97:8a:9e:48:0d:de:04:8d:76:3a:7b:4b:30:f8.\n') self.write('Are you sure you want to continue connecting (yes/no)? ') self.callbacks = [self.yesno, self.wait] @@ -88,8 +88,8 @@ class command_ssh(HoneyPotCommand): def yesno(self, line): """ """ - self.writeln( - 'Warning: Permanently added \'%s\' (RSA) to the list of known hosts.' % \ + self.write( + 'Warning: Permanently added \'%s\' (RSA) to the list of known hosts.\n' % \ self.host) self.write('%s@%s\'s password: ' % (self.user, self.host)) self.protocol.password_input = True @@ -114,10 +114,10 @@ class command_ssh(HoneyPotCommand): if not self.fs.exists(self.protocol.cwd): self.protocol.cwd = '/' self.protocol.password_input = False - self.writeln( - 'Linux %s 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686' % \ + self.write( + 'Linux %s 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686\n' % \ (self.protocol.hostname,)) - self.writeln('Last login: %s from 192.168.9.4' % \ + self.write('Last login: %s from 192.168.9.4\n' % \ (time.ctime(time.time() - 123123),)) self.exit() diff --git a/cowrie/commands/sudo.py b/cowrie/commands/sudo.py index 1091664..a1ba9b8 100644 --- a/cowrie/commands/sudo.py +++ b/cowrie/commands/sudo.py @@ -60,7 +60,7 @@ class command_sudo(HoneyPotCommand): """ """ for ln in sudo_shorthelp: - self.writeln(ln) + self.write(ln+'\n') self.exit() @@ -68,18 +68,18 @@ class command_sudo(HoneyPotCommand): """ """ for ln in sudo_longhelp: - self.writeln(ln) + self.write(ln+'\n') self.exit() def version(self): """ """ - self.writeln( + self.write( '''Sudo version 1.8.5p2 Sudoers policy plugin version 1.8.5p2 Sudoers file grammar version 41 -Sudoers I/O plugin version 1.8.5p2''') +Sudoers I/O plugin version 1.8.5p2\n''') self.exit() @@ -89,7 +89,7 @@ Sudoers I/O plugin version 1.8.5p2''') try: optlist, args = getopt.getopt(self.args, 'shV') except getopt.GetoptError as err: - self.writeln('invalid option') + self.write('invalid option\n') self.short_help() return diff --git a/cowrie/commands/tar.py b/cowrie/commands/tar.py index c6d806b..6c5af36 100644 --- a/cowrie/commands/tar.py +++ b/cowrie/commands/tar.py @@ -32,8 +32,8 @@ class command_tar(HoneyPotCommand): def call(self): if len(self.args) < 2: - self.writeln('tar: You must specify one of the `-Acdtrux\' options') - self.writeln('Try `tar --help\' or `tar --usage\' for more information.') + self.write('tar: You must specify one of the `-Acdtrux\' options\n') + self.write('Try `tar --help\' or `tar --usage\' for more information.\n') return filename = self.args[1] @@ -47,32 +47,32 @@ class command_tar(HoneyPotCommand): path = self.fs.resolve_path(filename, self.protocol.cwd) if not path or not self.protocol.fs.exists(path): - self.writeln('tar: %s: Cannot open: No such file or directory' % \ + self.write('tar: %s: Cannot open: No such file or directory\n' % \ filename) - self.writeln('tar: Error is not recoverable: exiting now') - self.writeln('tar: Child returned status 2') - self.writeln('tar: Error exit delayed from previous errors') + self.write('tar: Error is not recoverable: exiting now\n') + self.write('tar: Child returned status 2\n') + self.write('tar: Error exit delayed from previous errors\n') return f = self.fs.getfile(path) if not f[A_REALFILE]: - self.writeln('tar: this does not look like a tar archive') - self.writeln('tar: skipping to next header') - self.writeln('tar: error exit delayed from previous errors') + self.write('tar: this does not look like a tar archive\n') + self.write('tar: skipping to next header\n') + self.write('tar: error exit delayed from previous errors\n') return try: t = tarfile.open(f[A_REALFILE]) except: - self.writeln('tar: this does not look like a tar archive') - self.writeln('tar: skipping to next header') - self.writeln('tar: error exit delayed from previous errors') + self.write('tar: this does not look like a tar archive\n') + self.write('tar: skipping to next header\n') + self.write('tar: error exit delayed from previous errors\n') return for f in t: dest = self.fs.resolve_path(f.name.strip('/'), self.protocol.cwd) if verbose: - self.writeln(f.name) + self.write(f.name+'\n') if not extract or not len(dest): continue if f.isdir(): diff --git a/cowrie/commands/uname.py b/cowrie/commands/uname.py index 078d799..ea36152 100644 --- a/cowrie/commands/uname.py +++ b/cowrie/commands/uname.py @@ -7,15 +7,15 @@ commands = {} class command_uname(HoneyPotCommand): def call(self): if len(self.args) and self.args[0].strip() in ('-a', '--all'): - self.writeln( - 'Linux %s 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux' % \ + self.write( + 'Linux %s 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux\n' % \ self.protocol.hostname) elif len(self.args) and self.args[0].strip() in ('-r', '--kernel-release'): - self.writeln( '3.2.0-4-amd64' ) + self.write( '3.2.0-4-amd64\n' ) elif len(self.args) and self.args[0].strip() in ('-m', '--machine'): - self.writeln( 'amd64' ) + self.write( 'amd64\n' ) else: - self.writeln('Linux') + self.write('Linux\n') commands['/bin/uname'] = command_uname diff --git a/cowrie/commands/wget.py b/cowrie/commands/wget.py index ad3b2bb..ca013a8 100644 --- a/cowrie/commands/wget.py +++ b/cowrie/commands/wget.py @@ -51,17 +51,16 @@ class command_wget(HoneyPotCommand): try: optlist, args = getopt.getopt(self.args, 'cqO:') except getopt.GetoptError as err: - self.writeln('Unrecognized option') + self.write('Unrecognized option\n') self.exit() return if len(args): url = args[0].strip() else: - self.writeln('wget: missing URL') - self.writeln('Usage: wget [OPTION]... [URL]...') - self.nextLine() - self.writeln('Try `wget --help\' for more options.') + self.write('wget: missing URL\n') + self.write('Usage: wget [OPTION]... [URL]...\n\n') + self.write('Try `wget --help\' for more options.\n') self.exit() return @@ -88,7 +87,7 @@ class command_wget(HoneyPotCommand): if not path or \ not self.fs.exists(path) or \ not self.fs.isdir(path): - self.writeln('wget: %s: Cannot open: No such file or directory' % \ + self.write('wget: %s: Cannot open: No such file or directory\n' % \ outfile) self.exit() return @@ -120,13 +119,13 @@ class command_wget(HoneyPotCommand): if scheme != 'http' and scheme != 'https': raise exceptions.NotImplementedError except: - self.writeln('%s: Unsupported scheme.' % (url,)) + self.write('%s: Unsupported scheme.\n' % (url,)) self.exit() return None if self.quiet == False: - self.writeln('--%s-- %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), url)) - self.writeln('Connecting to %s:%d... connected.' % (host, port)) + self.write('--%s-- %s' % (time.strftime('%Y-%m-%d %H:%M:%S\n'), url)) + self.write('Connecting to %s:%d... connected.\n' % (host, port)) self.write('HTTP request sent, awaiting response... ') factory = HTTPProgressDownloader( @@ -146,7 +145,7 @@ class command_wget(HoneyPotCommand): return factory.deferred def handle_CTRL_C(self): - self.writeln('^C') + self.write('^C\n') self.connection.transport.loseConnection() def success(self, data, outfile): @@ -184,9 +183,9 @@ class command_wget(HoneyPotCommand): def error(self, error, url): if hasattr(error, 'getErrorMessage'): # exceptions error = error.getErrorMessage() - self.writeln(error) + self.write(error+'\n') # Real wget also adds this: - #self.writeln('%s ERROR 404: Not Found.' % \ + #self.write('%s ERROR 404: Not Found.\n' % \ # time.strftime('%Y-%m-%d %T')) self.exit() commands['/usr/bin/wget'] = command_wget @@ -214,7 +213,7 @@ class HTTPProgressDownloader(client.HTTPDownloader): def gotHeaders(self, headers): if self.status == '200': if self.quiet == False: - self.wget.writeln('200 OK') + self.wget.write('200 OK\n') if 'content-length' in headers: self.totallength = int(headers['content-length'][0]) else: @@ -227,13 +226,13 @@ class HTTPProgressDownloader(client.HTTPDownloader): if self.totallength > 0: if self.quiet == False: - self.wget.writeln('Length: %d (%s) [%s]' % \ + self.wget.write('Length: %d (%s) [%s]\n' % \ (self.totallength, sizeof_fmt(self.totallength), self.contenttype)) else: if self.quiet == False: - self.wget.writeln('Length: unspecified [%s]' % \ + self.wget.write('Length: unspecified [%s]\n' % \ (self.contenttype)) if self.wget.limit_size > 0 and \ self.totallength > self.wget.limit_size: @@ -242,8 +241,7 @@ class HTTPProgressDownloader(client.HTTPDownloader): self.fileName = os.path.devnull self.nomore = True if self.quiet == False: - self.wget.writeln('Saving to: `%s' % self.fakeoutfile) - self.wget.nextLine() + self.wget.write('Saving to: `%s\n\n' % self.fakeoutfile) return client.HTTPDownloader.gotHeaders(self, headers) @@ -290,10 +288,9 @@ class HTTPProgressDownloader(client.HTTPDownloader): ('%s>' % (38 * '='), splitthousands(str(int(self.totallength))).ljust(12), self.speed / 1000)) - self.wget.nextLine() - self.wget.nextLine() - self.wget.writeln( - '%s (%d KB/s) - `%s\' saved [%d/%d]' % \ + self.wget.write('\n\n') + self.wget.write( + '%s (%d KB/s) - `%s\' saved [%d/%d]\n' % \ (time.strftime('%Y-%m-%d %H:%M:%S'), self.speed / 1000, self.fakeoutfile, self.currentlength, self.totallength)) diff --git a/cowrie/commands/which.py b/cowrie/commands/which.py index 8433c8b..a921077 100644 --- a/cowrie/commands/which.py +++ b/cowrie/commands/which.py @@ -21,7 +21,7 @@ class command_which(HoneyPotCommand): resolved = self.fs.resolve_path(f, path) if self.fs.exists(resolved): - self.writeln("%s/%s" % (path, f)) + self.write("%s/%s\n" % (path, f)) continue # Definition diff --git a/cowrie/core/honeypot.py b/cowrie/core/honeypot.py index 66451e4..255846e 100644 --- a/cowrie/core/honeypot.py +++ b/cowrie/core/honeypot.py @@ -78,7 +78,7 @@ class HoneyPotCommand(object): def call(self): """ """ - self.writeln('Hello World! [%s]' % (repr(self.args),)) + self.write('Hello World! [%s]\n' % (repr(self.args),)) def exit(self): @@ -92,7 +92,7 @@ class HoneyPotCommand(object): """ """ log.msg('Received CTRL-C, exiting..') - self.writeln('^C') + self.write('^C\n') self.exit() @@ -178,8 +178,8 @@ class HoneyPotShell(object): line = line.replace('>', ' > ').replace('|', ' | ').replace('<',' < ') cmdAndArgs = shlex.split(line) except: - self.protocol.writeln( - 'bash: syntax error: unexpected end of file') + self.protocol.terminal.write( + 'bash: syntax error: unexpected end of file\n') # Could run runCommand here, but i'll just clear the list instead self.cmdpending = [] self.showPrompt() @@ -217,7 +217,7 @@ class HoneyPotShell(object): log.msg(eventid='COW0006', input=line, format='Command not found: %(input)s') if len(line): - self.protocol.writeln('bash: %s: command not found' % (cmd,)) + self.protocol.terminal.write('bash: %s: command not found\n' % (cmd,)) runOrPrompt() @@ -267,7 +267,7 @@ class HoneyPotShell(object): """ self.protocol.lineBuffer = [] self.protocol.lineBufferIndex = 0 - self.protocol.terminal.nextLine() + self.protocol.terminal.write('\n') self.showPrompt() @@ -335,17 +335,17 @@ class HoneyPotShell(object): first = l.split(' ')[:-1] newbuf = ' '.join(first + ['%s%s' % (basedir, prefix)]) if newbuf == ''.join(self.protocol.lineBuffer): - self.protocol.terminal.nextLine() + self.protocol.terminal.write('\n') maxlen = max([len(x[fs.A_NAME]) for x in files]) + 1 perline = int(self.protocol.user.windowSize[1] / (maxlen + 1)) count = 0 for file in files: if count == perline: count = 0 - self.protocol.terminal.nextLine() + self.protocol.terminal.write('\n') self.protocol.terminal.write(file[fs.A_NAME].ljust(maxlen)) count += 1 - self.protocol.terminal.nextLine() + self.protocol.terminal.write('\n') self.showPrompt() self.protocol.lineBuffer = list(newbuf) diff --git a/cowrie/core/protocol.py b/cowrie/core/protocol.py index 691ea24..aa1a4f4 100644 --- a/cowrie/core/protocol.py +++ b/cowrie/core/protocol.py @@ -91,7 +91,7 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin): """ this logs out when connection times out """ - self.writeln( 'timed out waiting for input: auto-logout' ) + self.write( 'timed out waiting for input: auto-logout\n' ) ret = failure.Failure(error.ProcessTerminated(exitCode=1)) self.terminal.transport.processEnded(ret) @@ -172,8 +172,7 @@ class HoneyPotBaseProtocol(insults.TerminalProtocol, TimeoutMixin): Sometimes still called after disconnect because of a deferred """ if self.terminal: - self.terminal.write(data) - self.terminal.nextLine() + self.terminal.write(data+'\n') def call_command(self, cmd, *args): @@ -257,7 +256,7 @@ class HoneyPotInteractiveProtocol(HoneyPotBaseProtocol, recvline.HistoricRecvLin """ """ try: - self.writeln(self.fs.file_contents('/etc/motd')) + self.write(self.fs.file_contents('/etc/motd')+'\n') except: pass