コード例 #1
0
    def findHttpServices(self, address):

        h = Helper()

        if ((h.ip_validate(address) is None)
                and (h.hostname_validate(address) is None)):
            return {}

        th = []

        for tn in range(1, 100):
            t = threading.Thread(target=self.check,
                                 kwargs={'address': address})
            t.setDaemon(True)
            th.append(t)

        for t in th:
            t.start()
            t.join()

        result = {
            'hostname': address,
            'addresses': h.resolve_dns(address),
            'webservices': self.webservices
        }

        return result
コード例 #2
0
def run_method(langbuf, param):
    h = Helper()
    Logging.log(h.formatter(h.getlang(langbuf, 'running', None), [hostname]),
                LogLevel.CLI)
    print(' ')
    if param is not None:
        for p in param:
            if (p == '0'):
                render_tree(request_method(MethodAxfr(), 'AXFR'))
            elif (p == '1'):
                render_tree(request_method(MethodDnsQueries(), 'DNS Queries'))
            elif (p == '2'):
                render_tree(request_method(MethodVirusTotal(), 'VirusTotal'))
            elif (p == '3'):
                render_tree(request_method(MethodRobtex(), 'Robtex'))
            elif (p == '4'):
                render_tree(request_method(MethodCrtSh(), 'CRTSH'))
            elif (p == '5'):
                render_tree(
                    request_method(MethodCertificateDetails(),
                                   'CertificateDetails'))
            elif (p == '6'):
                render_tree(request_method(MethodGoogle(), 'Google CSE'))
            elif (p == '7'):
                render_tree(request_method(MethodBing(), 'Bing'))
            elif (p == '8'):
                render_tree(request_method(MethodDnsDumpster(),
                                           'DNS Dumpster'))
コード例 #3
0
    def filter(self, address):
        h = Helper()
        # Direcciones IP que se está buscando actualmente, para recibir desde el
        # sniffer.
        self.remoteIpAddressStack = h.resolve_dns(address)

        # Corre el sniffer en busca de los paquetes de respuesta de puertos
        threadHandler = threading.Thread(target=self.sniffer)

        # Previene la impresión de mensajes de error al final del hilo
        # principal cuando se cancela el progreso con Conrol+C.
        threadHandler.setDaemon(True)

        # Ejecuta el hilo de proceso
        threadHandler.start()

        for ip in self.remoteIpAddressStack:

            # Realiza la búsqueda de puertos
            self.findPorts(address)

            # Iteración cada x segundos
            time.sleep(10)

        self.canContinue = False
        self.socketHandlerBind.close()

        # Espera a que finalice el hilo de proceso del sniffer.
        threadHandler.join()

        return self.result
コード例 #4
0
    def findPorts(self, address):
        h = Helper()
        # Omite los rangos locales
        # TODO: Puede ser requerido para pentesting.
        if h.ip_validate(address) is not None:
            if (IP(address).iptype() in ['PRIVATE', 'LOOPBACK']):
                return

        interface = Interface()
        tcpHelper = TCPHelper()

        # Dirección IP local donde llegarán los paquetes
        localIpAddress = interface.getSourceAddress()

        # Rango de puertos a revisar
        for port in range(1, 65535):
            # Envía un paquete syn a modo de señuelo mientras que el hilo de
            # proceso del socket a escucha está listo para recibir las
            # respuestas.
            try:
                tcpHelper.sendSyn(sourceIp=localIpAddress,
                                  toAddress=address,
                                  dstPort=port)
            except Exception as e:
                # Ok, puede suceder, es normal.
                # Por alguna extraña razón el socket en cierto punto arroja un
                # acceso denegado indicando que no tengo permisos para la
                # operación a pesar de tener privilegios elevados, pero de todas
                # maneras el paquete se envía sin problemas.
                pass
コード例 #5
0
def define_host(langbuf, param):
    global hostname
    h = Helper()
    if h.hostname_validate(param) is None:
        Logging.log(h.getlang(langbuf, 'errors', 'invalid-hostname'),
                    LogLevel.DANGER)
        exit(-1)
    else:
        hostname = param
コード例 #6
0
ファイル: dnsqueries.py プロジェクト: blacknode/wss
    def find(self, hostname):
        h = Helper()
        # Pila local de subdominios encontrados que evita al duplicidad
        hostnames = []
        # Procesa cada tipo de registro DNS
        for recordType in ['MX', 'TXT', 'SPF', 'NS']:

            # ¿Hubo respuesta?
            answer = None
            try:
                answer = dns.resolver.query(
                    hostname,
                    recordType,
                    tcp=True  # Mejora el resultado, evita la pérdida de paquetes
                )

            except Exception as e:
                # No fue posible realizar la consulta DNS
                continue

            for rdata in answer:

                # Registro en texto plano y en bruto
                plainRecord = rdata.to_text().strip('"')

                # Busca todos los posibles subdominios en la respuesta plana
                matches = re.findall(
                    r'([a-zA-Z0-9\.\-\_\$]+?\.' + re.escape(hostname) + r')',
                    plainRecord)

                # ¿Hay resultados?
                if (len(matches) == 0):
                    continue

                # Procesa cada subdominio encontrado
                for item in matches:

                    if (
                            # Es un subdominio válido?
                        (not item.endswith(h.formatter('.{}', [hostname]))) or
                            # ¿El subdominio existe en la pila local? (evita la
                            # duplicidad de resultados).
                        (item in hostnames)):
                        continue
                    # Agrega el subdominio encontrado a la pila local
                    hostnames.append({
                        'subdomain': item,
                        'recordType': recordType
                    })

        # ¿Hubo resultados finalmente?
        if len(hostnames):
            return hostnames
        else:
            return []
コード例 #7
0
    def check(self, address):

        self.webservices = []
        while (len(self.stack)):
            port = self.stack.pop()
            for protocol in ['http', 'https']:

                # Omite conflictos
                if (((protocol == 'http') and (port == 443))
                        or ((protocol == 'https') and (port == 80))):
                    continue
                h = Helper()
                if (((protocol == 'http') and (port == 80))
                        or ((protocol == 'https') and (port == 443))):
                    continue
                url = h.formatter(
                    '{}://{}:{}/',
                    [protocol, address, str(port)])
                # Uso del crawler
                crawler = WCrawler()

                result = None
                try:
                    result = crawler.httpRequest(url)
                    crawler.clearContext()

                except Exception as e:
                    pass

                if (
                        # No fue posible conectar con el servidor
                    (result is None) or

                        # Puerto abierto pero no es un servicio HTTP
                    (result['status-code'] == 0)):
                    continue

                # Obtiene el contenido de la etiqueta HTML <title>
                matches = re.search(br'<title>(.+?)<\/title>',
                                    result['response-content'], re.I | re.M)

                title = None
                if (matches):
                    title = str(matches.group(1))[2:][:-1]

                sm = result.get('status-message', '-').decode()
                sc = result.get('status-code')
                t = title if title else ''

                self.webservices.append({
                    'url': url,
                    'title': t,
                    'status-code': sc,
                    'status-message': sm
                })
コード例 #8
0
ファイル: virustotal.py プロジェクト: blacknode/wss
    def find(self, hostname, url=None):
        h = Helper()
        # Uso del crawler
        crawler = WCrawler()

        # El resultado es de tipo json
        result = None
        if url is None:
            req = h.formatter(
                'https://www.virustotal.com/ui/domains/{}/subdomains?limit=40',
                [hostname])
        else:
            req = url
        try:

            result = crawler.httpRequest(req)
            # Libera la memoria (no es necesario un contexto de navegación)
            crawler.clearContext()

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        try:
            # Convierte el resultado en un objeto de tipo json
            result = json.loads(result['response-content'])

        except Exception as e:
            return []

        # ¿Hay contenido de la respuesta HTTP?
        if (len(result['data']) == 0):
            return []

        # Procesa todos los subdominios encontrados en la página actual
        for item in result['data']:

            # Evita los resultados duplicados utilizando la pila local
            if (str(item['id']) in self.hostnames):
                continue

            # Agrega el subdominio encontrado a la pila local
            self.hostnames.append(str(item['id']))

        # ¿Necesita continuar paginando resultados?
        if (('links' in result) and ('next' in result['links'])
                and (result['links'])):
            self.find(hostname=hostname, url=str(result['links']['next']))

        return self.hostnames
コード例 #9
0
    def find(self, hostname):
        h = Helper()

        nameServers = []
        try:
            ans = dns.resolver.query(hostname, 'NS', tcp=True)
            nameServers = [a.to_text().strip('.') for a in ans]
            nameServers = set(nameServers)  # Valores únicos
            nameServers = sorted(nameServers)  # Valores ordenados

        except Exception as e:
            pass

        except dns.exception.DNSException as e:
            pass

        if (len(nameServers) == 0):
            return {}

        # Procesa cada registro
        for ns in nameServers:
            self.ns.append(ns)
            axfr = None
            try:
                # Crea la consulta AXFR
                axfr = dns.query.xfr(where=ns, zone=hostname, lifetime=5.0)

            except Exception as e:
                continue

            zone = None
            try:
                # Intenta obtener los resultados de la consulta
                zone = dns.zone.from_xfr(axfr)

            except Exception as e:
                continue

            if zone is None:
                continue
            # Procesa cada resultado
            for name, node in zone.nodes.items():
                rdatasets = node.rdatasets

                for rdataset in rdatasets:

                    if (str(name) == '@'):
                        continue
                    r = h.formatter('{}.{}', [str(name), hostname])
                    self.subdomains.append(r)

        return {'nameservers': self.ns, 'domains': self.subdomains}
コード例 #10
0
def render_dict(d, tree):
    h = Helper()
    t = ''
    for o in d:
        m = d.get(o)
        if isinstance(m, list):
            t += h.formatter('{}: {} ', [o, ', '.join(m)])
        elif isinstance(m, dict):
            for p in m:
                s = m.get(p)
                t += h.formatter('{}: {} ', [p, s])
        else:
            t += h.formatter('{}: {} ', [o, m])
    q = Node(t, parent=tree)
コード例 #11
0
    def find(self, hostname):

        h = Helper()
        # Uso del crawler
        crawler = WCrawler()

        # El resultado es de tipo json
        result = None

        mp = 15
        q = h.formatter('domain:{}', [hostname])

        for p in range(1, 16):
            req = h.formatter('https://www.bing.com/search?q={}&first={}',
                              [q, p])
            try:
                result = crawler.httpRequest(req)
                # Libera la memoria (no es necesario un contexto de navegación)
                crawler.clearContext()
            except Exception as e:
                return []

            # ¿La respuesta HTTP es OK?
            if (result['status-code'] != 200):
                return []
            # Busca cada nombre de dominio
            # Ejemplo de resultados: <cite>https://foo<strong>ejemplo.com</strong>
            matches = re.findall(
                br'>([\w\.\-\_\$]+?\.' + re.escape(hostname).encode() + br')',
                result['response-content'].replace(
                    b'<strong>' + hostname.encode(), b'.' + hostname.encode()))

            if (len(matches) == 0):
                return []

            # Procesa cada nombre de dominio encontrado
            for item in matches:
                # ¿El resultado es un subdominio inválido?
                if (not item.decode().endswith('.' + hostname)):
                    continue

                # Evita los resultados duplicados utilizando la pila local
                if (item.decode() in self.hostnames):
                    continue

                # Agrega el subdominio encontrado a la pila local
                self.hostnames.append(item.decode())

        return self.hostnames
コード例 #12
0
 def parse_args(self, args):
     h = Helper()
     for flag in args.keys():
         cmd = self.found_command(flag)
         if not cmd is None:
             runtime = cmd.get('runtime')
             runtime(self.langbuf, args[flag])
コード例 #13
0
def run_server(langbuf, param):
    h = Helper()
    c = param.split(':')
    ip = '127.0.0.1'
    port = 3000
    debug = 'on'
    if len(c):
        for v in c:
            if h.ip_validate(v) is not None:
                ip = v
            elif h.port_validate(v) is not None:
                port = v
            else:
                if v in ['on', 'off']:
                    debug = v
    http = HttpServer(ip, port, debug)
    http.start()
コード例 #14
0
    def __init__(self):
        #Helper instance
        h = Helper()
        #Print banner
        Logging.log(h.ftext('WHK Subdomains Scanner', 'speed'), LogLevel.CLI)
        #Parse arguments from cli
        args = self.build_args()
        argc = len(args)
        #Check if arguments was passed
        if not argc > 0:
            Logging.log(
                '- No CLI arguments found, try --help command for more info',
                LogLevel.DANGER)
            exit(-1)

        self.load_lang(self.define_lang(args))
        self.parse_args(args)
コード例 #15
0
ファイル: crtsh.py プロジェクト: blacknode/wss
    def find(self, hostname):
        h = Helper()
        # Uso del crawler
        crawler = WCrawler()
        crawler.defaultTimeout = 60

        # El resultado es de tipo json
        result = None

        req = h.formatter('https://crt.sh/?q=%.{}&output=json', [hostname])

        try:
            result = crawler.httpRequest(req)

            # Libera la memoria (no es necesario un contexto de navegación)
            crawler.clearContext()

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        try:
            # Convierte el resultado en un objeto de tipo json
            result = json.loads(result['response-content'])

        except Exception as e:
            return []

        if ((not isinstance(result, list)) or (len(result) == 0)):
            return []

        hostnames = []
        # Procesa cada nombre de dominio encontrado
        for item in result:

            # Evita los resultados duplicados utilizando la pila local
            if (item['name_value'] in hostnames):
                continue

            # Agrega el subdominio encontrado a la pila local
            hostnames.append(item['name_value'])

        return hostnames
コード例 #16
0
    def findPorts(self, ipaddress):
        h = Helper()
        # Omite los rangos locales
        # TODO: Puede ser requerido para pentesting.
        if h.ip_validate(ipaddress) is not None:
            if (IP(ipaddress).iptype() in ['PRIVATE', 'LOOPBACK']):
                return {'ports': []}

        self.ips = h.resolve_dns(ipaddress)
        response = []

        for ip in self.ips:
            if ip == ipaddress:
                continue
            result = {'record': {'ip': []}}
            self.stack = list(reversed(range(1, 65535)))

            result['record']['ip'] = ip
            result['record']['ports'] = []
            # Punteros de los hilos de proceso
            threadsHandlers = []

            # Linux por defecto soporta 1024 threads a menos que se modifique
            # los límites en /etc/security/limits.conf
            # 500 hilos por defecto
            for threadNumber in range(1, 500):
                # Puntero del hilo de proceso
                threadHandler = threading.Thread(target=self.threadCheck,
                                                 kwargs={'ipaddress': ip})
                # Previene la impresión de mensajes de error al final del hilo
                # principal cuando se cancela el progreso con Conrol+C.
                threadHandler.setDaemon(True)
                # Obtiene el identificador único del hilo de proceso
                threadsHandlers.append(threadHandler)
                # Ejecuta el hilo de proceso
                threadHandler.start()

            for threadHandler in threadsHandlers:
                # Espera a que finalice el hilo de proceso
                threadHandler.join()

            result['record']['ports'] = sorted(self.ports)
            response.append(result)
            self.ports = []

        return response
コード例 #17
0
 def define_lang(self, args):
     h = Helper()
     #Trying found by long flag
     lang = args.get('lang')
     if lang is None:
         #Trying found by short flag
         lang = args.get('l')
         if lang is None:
             langpath = h.formatter('resources/lang/{}.json',
                                    [get_locale()])
             return langpath
         else:
             langpath = h.formatter('resources/lang/{}.json',
                                    [lang.lower()])
             return langpath
     else:
         langpath = h.formatter('resources/lang/{}.json', [lang.lower()])
         return langpath
コード例 #18
0
ファイル: robtex.py プロジェクト: blacknode/wss
    def find(self, hostname):
        h = Helper()
        # Uso del crawler
        crawler = WCrawler()
        crawler.defaultTimeout = 30

        # Resultado de tipo HTML
        result = None
        req = h.formatter('https://www.robtex.com/dns-lookup/{}', [hostname])
        try:
            result = crawler.httpRequest(req)

            # Libera la memoria (no es necesario un contexto de navegación)
            crawler.clearContext()

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        # Elimina las etiquetas de negritas del resultado: foo.<b>domain.com</b>
        result['response-content'] = result['response-content'].replace(
            b'<b>', b'').replace(b'</b>', b'')

        # Busca todos los posibles subdominios
        matches = re.findall(
            br'>([\w\.\-\_\$]+?\.' + re.escape(hostname).encode() + br')<',
            result['response-content'])

        # ¿Hay resultados?
        if (len(matches) == 0):
            return []

        result = []
        # Procesa todos los resultados
        for item in matches:
            result.append(item.decode())

        return result
コード例 #19
0
def run_filter(langbuf, param):
    h = Helper()
    if param is not None:
        res = []
        for p in param:
            if (p == '0'):
                if ((os.geteuid() == 0)
                        or (os.getenv('SUDO_USER') is not None)):
                    f = FilterRawPorts()
                    render_tree(request_filter(f.filter(hostname),
                                               'Raw Ports'))
                else:
                    Logging.log(h.getlang(langbuf, 'errors', 'root-required'),
                                LogLevel.DANGER)
            elif (p == '1'):
                f = FilterPorts()
                render_tree(request_filter(f.findPorts(hostname), 'Ports'))
            elif (p == '2'):
                f = FilterHttpServices()
                render_tree(
                    request_filter(f.findHttpServices(hostname),
                                   'Http Services'))
コード例 #20
0
    def load_lang(self, langpath):
        h = Helper()

        if not h.langexists(langpath):
            Logging.log('Can\'t define language to show, exiting...',
                        LogLevel.DANGER)
            exit(-1)
        else:
            self.langbuf = lang_from_path(langpath)
            if not isinstance(self.langbuf, dict):
                Logging.log('- Error loading language file', LogLevel.DANGER)
                exit(-1)

        Logging.log(
            h.formatter(h.getlang(self.langbuf, 'header', None),
                        [h.version(), h.gettime()]), LogLevel.CLI)
コード例 #21
0
    def find(self, hostname):
        h = Helper()
        # ¿La llave de la API de Google existe?
        if (not self.googleApiKey.strip()):
            return []

        q = h.formatter('site:{}', [hostname])
        hostnames = []

        for i in range(1, 16):
            # ¿Hay resultados del método actual?
            if (hostnames):
                # Excluye los subdominios ya conocidos
                q += h.formatter('-site:{}', [' -site:'.join(hostnames)])
            # Uso del crawler
            crawler = WCrawler()

            # El resultado es de tipo json
            result = None
            req = h.formatter(
                'https://www.googleapis.com/customsearch/v1?cx={}&key={}&q={}&start={}&filter=1&safe=off&num={}',
                [self.googleCx, self.googleApiKey, q, i, 10])
            try:
                # Navega
                result = crawler.httpRequest(req)

                # Libera la memoria (no es necesario un contexto de navegación)
                crawler.clearContext()

            except Exception as e:
                break

            # Los estados 403 y 400 indican que no hay más resultados o que la API
            # está saturada con solicitudes.
            if (result['status-code'] in [403, 400]):
                break

            # ¿La respuesta HTTP es OK?
            if (result['status-code'] != 200):
                break

            try:
                # Convierte el resultado en un objeto de tipo json
                result = json.loads(result['response-content'])
            except Exception as e:
                break

            # ¿Hay resultados procesables?
            if ((not 'items' in result) or (len(result['items']) == 0)):
                break

            # Procesa cada resultado
            for item in result['items']:

                f = h.formatter('.{}', [hostname])
                # ¿El resultado es un subdominio inválido?
                if (not item['displayLink'].endswith(f)):
                    continue

                # Evita los resultados duplicados utilizando la pila local
                if (item['displayLink'] in hostnames):
                    continue

                # Agrega el subdominio encontrado a la pila local
                hostnames.append(item['displayLink'])

        return hostnames
コード例 #22
0
def render_tree(tree):
    h = Helper()
    for pre, fill, node in RenderTree(tree):
        Logging.log(h.formatter("{}{}", [pre, node.name]), LogLevel.CLI)
コード例 #23
0
def show_help(langbuf, param):
    h = Helper()
    Logging.log(h.getlang(langbuf, 'usage', None), LogLevel.CLI)
コード例 #24
0
ファイル: server.py プロジェクト: blacknode/wss
 def dashboard():
     h = Helper()
     return render_template('dashboard.html', version=h.version())
コード例 #25
0
ファイル: dnsdumpster.py プロジェクト: blacknode/wss
    def find(self, hostname):
        h = Helper()
        # Uso del crawler, por defecto guardará la cookie de sesión manteniendo
        # el contexto del flujo de la navegación.
        crawler = WCrawler()

        # El resultado es de tipo HTML
        result = None

        try:
            result = crawler.httpRequest(url='https://dnsdumpster.com/')

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        # Busca el token XSRF
        matches = re.search(
            br'name=["\']csrfmiddlewaretoken["\']\s+value=["\'](.+?)["\']',
            result['response-content'], re.I | re.M)

        if (not matches):
            return []

        # Guarda el roken XSRF en la variable local para reutilizar la variable
        # 'matches'.
        tokenXsrf = matches.group(1)

        # El resultado es de tipo HTML
        result = None

        try:
            result = crawler.httpRequest(url='https://dnsdumpster.com/',
                                         postData={
                                             'csrfmiddlewaretoken': tokenXsrf,
                                             'targetip': hostname
                                         })

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        # Busca todos los resultados
        matches = re.findall(
            br'>([\w\.\-\_\$]+?\.' + re.escape(hostname).encode() + br')<',
            result['response-content'])

        # ¿Hay resultados?
        if (len(matches) == 0):
            return []

        hostnames = []
        # Procesa todos los subdominios encontrados
        for item in matches:
            hostnames.append(item.decode())

        return hostnames
コード例 #26
0
ファイル: certificatedetails.py プロジェクト: blacknode/wss
    def find(self, hostname):

        h = Helper()

        # Uso del crawler
        crawler = WCrawler()

        # El resultado es de tipo json
        result = None
        req = h.formatter('https://certificatedetails.com/api/list/{}',
                          [hostname])
        try:
            result = crawler.httpRequest(req)
            # Libera la memoria (no es necesario un contexto de navegación)
            crawler.clearContext()

        except Exception as e:
            return []

        # ¿La respuesta HTTP es OK?
        if (result['status-code'] != 200):
            return []

        try:
            # Convierte el resultado en un objeto de tipo json
            result = json.loads(result['response-content'])

        except Exception as e:
            return []

        if ((not isinstance(result, list)) or (len(result) == 0)):
            return []

        # Procesa cada nombre de dominio encontrado
        items = []
        for item in result:
            subdomain = h.formatter('.{}', [hostname])
            # ¿Es un subdominio válido?
            if (not item['CommonName'].endswith(subdomain)):
                continue

            # Evita los resultados duplicados utilizando la pila local
            if (item['CommonName'] in items):
                continue

            # Agrega el subdominio encontrado a la pila local
            items.append(item['CommonName'])

        self.hostnames.append({'subdomains': list(set(items))})

        # Identificador actual del enlace
        linkId = 0

        # Procesa cada enlace
        # Precaución: Un mismo nombre de dominio repetido puede contener uno o
        #             más certificados diferentes.
        linkres = []
        for item in result:

            linkId += 1
            req = h.formatter('https://certificatedetails.com{}',
                              [item['Link']])
            linkres += self.findInLink(url=req,
                                       linkId=linkId,
                                       totalLinks=len(result),
                                       hostname=hostname)
        self.hostnames.append({'links': list(set(linkres))})
        return self.hostnames