From f5783e6cda06bc2de2d710141c6b5af18419b7bf Mon Sep 17 00:00:00 2001 From: davegermiquet Date: Sun, 22 May 2016 01:50:24 -0400 Subject: [PATCH] Separated perl from BASE Added additional error checking. Added checking for files Added a new command python --- cowrie/commands/__init__.py | 4 +- cowrie/commands/base.py | 92 +------------------------ cowrie/commands/perl.py | 121 ++++++++++++++++++++++++++++++++ cowrie/commands/python.py | 133 ++++++++++++++++++++++++++++++++++++ 4 files changed, 259 insertions(+), 91 deletions(-) create mode 100644 cowrie/commands/perl.py create mode 100644 cowrie/commands/python.py diff --git a/cowrie/commands/__init__.py b/cowrie/commands/__init__.py index 1555bb0..9c3af0b 100644 --- a/cowrie/commands/__init__.py +++ b/cowrie/commands/__init__.py @@ -26,5 +26,7 @@ __all__ = [ 'tar', 'uname', 'wget', - 'which' + 'which', + 'perl', + 'python' ] diff --git a/cowrie/commands/base.py b/cowrie/commands/base.py index 614be8c..a49792a 100644 --- a/cowrie/commands/base.py +++ b/cowrie/commands/base.py @@ -7,6 +7,7 @@ import functools import getopt from twisted.python import failure, log + from twisted.internet import error, reactor from cowrie.core.honeypot import HoneyPotCommand @@ -459,12 +460,10 @@ class command_date(HoneyPotCommand): def call(self): """ """ - time = datetime.datetime.utcnow(); + time = datetime.datetime.utcnow() self.write(time.strftime("%a %b %d %H:%M:%S UTC %Y")+'\n') commands['/bin/date'] = command_date - - class command_yes(HoneyPotCommand): """ """ @@ -524,93 +523,6 @@ class command_chmod(HoneyPotCommand): (arg,)) commands['/bin/chmod'] = command_chmod - - -class command_perl(HoneyPotCommand): - """ - """ - def start(self): - """ - """ - if not len(self.args): - pass - elif self.args[0] == '-v': - output = ( - '', - 'This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-thread-multi', - '', - 'Copyright 1987-2014, Larry Wall', - '', - 'Perl may be copied only under the terms of either the Artistic License or the', - 'GNU General Public License, which may be found in the Perl 5 source kit.', - '', - 'Complete documentation for Perl, including FAQ lists, should be found on', - 'this system using "man perl" or "perldoc perl". If you have access to the', - 'Internet, point your browser at http://www.perl.org/, the Perl Home Page.', - '' - ) - for l in output: - self.write(l+'\n') - self.exit() - elif self.args[0] == '-h': - output = ( - '', - 'Usage: perl [switches] [--] [programfile] [arguments]', - ' -0[octal] specify record separator (\0, if no argument)', - ' -a autosplit mode with -n or -p (splits $_ into @F)', - ' -C[number/list] enables the listed Unicode features', - ' -c check syntax only (runs BEGIN and CHECK blocks)', - ' -d[:debugger] run program under debugger', - ' -D[number/list] set debugging flags (argument is a bit mask or alphabets)', - " -e program one line of program (several -e's allowed, omit programfile)", - ' -E program like -e, but enables all optional features', - " -f don't do $sitelib/sitecustomize.pl at startup", - " -F/pattern/ split() pattern for -a switch (//'s are optional)", - ' -i[extension] edit <> files in place (makes backup if extension supplied)', - " -Idirectory specify @INC/#include directory (several -I's allowed)", - ' -l[octal] enable line ending processing, specifies line terminator', - ' -[mM][-]module execute "use/no module..." before executing program', - ' -n assume "while (<>) { ... }" loop around program', - ' -p assume loop like -n but print line also, like sed', - ' -s enable rudimentary parsing for switches after programfile', - ' -S look for programfile using PATH environment variable', - ' -t enable tainting warnings', - ' -T enable tainting checks', - ' -u dump core after parsing program', - ' -U allow unsafe operations', - ' -v print version, subversion (includes VERY IMPORTANT perl info)', - ' -V[:variable] print configuration summary (or a single Config.pm variable)', - ' -w enable many useful warnings (RECOMMENDED)', - ' -W enable all warnings', - ' -x[directory] strip off text before #!perl line and perhaps cd to directory', - ' -X disable all warnings', - '' - ) - for l in output: - self.write(l+'\n') - self.exit() - else: - self.exit() - - - def lineReceived(self, line): - """ - """ - log.msg(eventid='cowrie.session.file_download', - realm='perl', - input=line, - format='INPUT (%(realm)s): %(input)s') - - - def handle_CTRL_D(self): - """ - """ - self.exit() - -commands['/usr/bin/perl'] = command_perl - - - class command_php(HoneyPotCommand): """ """ diff --git a/cowrie/commands/perl.py b/cowrie/commands/perl.py new file mode 100644 index 0000000..7a7477b --- /dev/null +++ b/cowrie/commands/perl.py @@ -0,0 +1,121 @@ +# Copyright (c) 2015 Michel Oosterhof +# All rights reserved. + +""" +This module contains the perl command +""" + +from twisted.python import log +import getopt +from cowrie.core.honeypot import HoneyPotCommand + +commands = {} + + +class command_perl(HoneyPotCommand): + """ + """ + def version(self): + output = ( + '', + 'This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-thread-multi', + '', + 'Copyright 1987-2014, Larry Wall', + '', + 'Perl may be copied only under the terms of either the Artistic License or the', + 'GNU General Public License, which may be found in the Perl 5 source kit.', + '', + 'Complete documentation for Perl, including FAQ lists, should be found on', + 'this system using "man perl" or "perldoc perl". If you have access to the', + 'Internet, point your browser at http://www.perl.org/, the Perl Home Page.', + '' + ) + for l in output: + self.write(l + '\n') + self.exit() + + def help(self): + output = ( + '', + 'Usage: perl [switches] [--] [programfile] [arguments]', + ' -0[octal] specify record separator (\0, if no argument)', + ' -a autosplit mode with -n or -p (splits $_ into @F)', + ' -C[number/list] enables the listed Unicode features', + ' -c check syntax only (runs BEGIN and CHECK blocks)', + ' -d[:debugger] run program under debugger', + ' -D[number/list] set debugging flags (argument is a bit mask or alphabets)', + " -e program one line of program (several -e's allowed, omit programfile)", + ' -E program like -e, but enables all optional features', + " -f don't do $sitelib/sitecustomize.pl at startup", + " -F/pattern/ split() pattern for -a switch (//'s are optional)", + ' -i[extension] edit <> files in place (makes backup if extension supplied)', + " -Idirectory specify @INC/#include directory (several -I's allowed)", + ' -l[octal] enable line ending processing, specifies line terminator', + ' -[mM][-]module execute "use/no module..." before executing program', + ' -n assume "while (<>) { ... }" loop around program', + ' -p assume loop like -n but print line also, like sed', + ' -s enable rudimentary parsing for switches after programfile', + ' -S look for programfile using PATH environment variable', + ' -t enable tainting warnings', + ' -T enable tainting checks', + ' -u dump core after parsing program', + ' -U allow unsafe operations', + ' -v print version, subversion (includes VERY IMPORTANT perl info)', + ' -V[:variable] print configuration summary (or a single Config.pm variable)', + ' -w enable many useful warnings (RECOMMENDED)', + ' -W enable all warnings', + ' -x[directory] strip off text before #!perl line and perhaps cd to directory', + ' -X disable all warnings', + '' + ) + for l in output: + self.write(l + '\n') + + def start(self): + """ + """ + try: + opts, args = getopt.gnu_getopt(self.args, 'acfnpsStTuUvwWXC:D:e:E:F:i:I:l:m:M:V:X:') + except getopt.GetoptError as err: + self.write("Unrecognized switch: -" + err.opt + " (-h will show valid options).\n") + self.exit() + return + + # Parse options + for o, a in opts: + if o in ("-v"): + self.version() + self.exit() + return + elif o in ("-h"): + self.help() + self.exit() + return + + for value in args: + sourcefile = self.fs.resolve_path(value, self.protocol.cwd) + + if self.fs.exists(sourcefile): + self.exit() + else: + self.write("Can't open perl script \"%s\": No such file or directory\n" % (value)) + self.exit() + + if not len(self.args): + pass + + def lineReceived(self, line): + """ + """ + log.msg(eventid='cowrie.session.file_download', + realm='perl', + input=line, + format='INPUT (%(realm)s): %(input)s') + + def handle_CTRL_D(self): + """ + """ + self.exit() + + +commands['/usr/bin/perl'] = command_perl diff --git a/cowrie/commands/python.py b/cowrie/commands/python.py new file mode 100644 index 0000000..8eed097 --- /dev/null +++ b/cowrie/commands/python.py @@ -0,0 +1,133 @@ +# Copyright (c) 2015 Michel Oosterhof +# All rights reserved. + +""" +This module contains the python commnad +""" + +from cowrie.core.honeypot import HoneyPotCommand +import getopt +from twisted.python import log + +commands = {} + + +class command_python(HoneyPotCommand): + """ + """ + def version(self): + output = ( + 'Python 2.7.11+' + ) + for l in output: + self.write(l + '\n') + self.exit() + + def help(self): + output = ( + 'usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...', + 'Options and arguments (and corresponding environment variables):', + '-B : don\'t write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x', + '-c cmd : program passed in as string (terminates option list)', + '-d : debug output from parser; also PYTHONDEBUG=x', + '-E : ignore PYTHON* environment variables (such as PYTHONPATH)', + '-h : print this help message and exit (also --help)', + '-i : inspect interactively after running script; forces a prompt even', + ' if stdin does not appear to be a terminal; also PYTHONINSPECT=x', + '-m mod : run library module as a script (terminates option list)', + '-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x', + '-OO : remove doc-strings in addition to the -O optimizations', + '-R : use a pseudo-random salt to make hash() values of various types be', + ' unpredictable between separate invocations of the interpreter, as', + ' a defense against denial-of-service attacks', + '-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew', + '-s : don\'t add user site directory to sys.path; also PYTHONNOUSERSITE', + '-S : don\'t imply \'import site\' on initialization', + '-t : issue warnings about inconsistent tab usage (-tt: issue errors)', + '-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x', + ' see man page for details on internal buffering relating to \'-u\'', + '-v : verbose (trace import statements); also PYTHONVERBOSE=x', + ' can be supplied multiple times to increase verbosity', + '-V : print the Python version number and exit (also --version)', + '-W arg : warning control; arg is action:message:category:module:lineno', + ' also PYTHONWARNINGS=arg', + '-x : skip first line of source, allowing use of non-Unix forms of #!cmd', + '-3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix', + 'file : program read from script file', + '- : program read from stdin (default; interactive mode if a tty)', + 'arg ...: arguments passed to program in sys.argv[1:]', + '', + 'Other environment variables:', + 'PYTHONSTARTUP: file executed on interactive startup (no default)', + 'PYTHONPATH : \':\'-separated list of directories prefixed to the', + ' default module search path. The result is sys.path.', + 'PYTHONHOME : alternate directory (or :).', + ' The default module search path uses /pythonX.X.', + 'PYTHONCASEOK : ignore case in \'import\' statements (Windows).', + 'PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.', + 'PYTHONHASHSEED: if this variable is set to \'random\', the effect is the same', + ' as specifying the -R option: a random value is used to seed the hashes of', + ' str, bytes and datetime objects. It can also be set to an integer', + ' in the range [0,4294967295] to get hash values with a predictable seed.' + ) + for l in output: + self.write(l + '\n') + + def start(self): + """ + """ + 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("usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... \n") + self.write("Try `python -h' for more information.\n") + self.exit() + return + + # Parse options + for o, a in opts: + if o in ("-v"): + self.version() + self.exit() + return + elif o in ("--help"): + self.help() + self.exit() + return + elif o in ('-h'): + self.help() + self.exit() + elif o in ('--version'): + self.version() + + for value in args: + sourcefile = self.fs.resolve_path(value, self.protocol.cwd) + + if self.fs.exists(sourcefile): + self.exit() + else: + + self.write("python: can't open file '%s': [Errno 2] No such file or directory\n" % (value)) + self.exit() + + if not len(self.args): + pass + + def lineReceived(self, line): + """ + """ + log.msg(eventid='cowrie.session.file_download', + realm='python', + input=line, + format='INPUT (%(realm)s): %(input)s') + + def handle_CTRL_D(self): + """ + """ + self.exit() + + +commands['/usr/bin/python'] = command_python + +# vim: set sw=4 et tw=0: