# Web Finder (PT-BR)
Esta é uma ferramenta para busca de endereços IP que respondam por uma URL específica.
## Instalação
> :information_source: Recomendamos a utilização do `pipx` ao invés do `pip` para instalação no sistema.
```
python3 -m pipx install wafwebfinder
```
> :information_source: Verifique a necessidade de executar também o comando `python3 -m pipx ensurepath`
## Conceito técnico
Ao realizar uma requisição HTTP/S para um host a primeira fase a ser realizada pelo cliente é a resolução de nome para IP e posteriormente conexão direta para este IP. Este procedimento se refere até a camada de Transporte do modelo OSI (camada 4) onde temos apenas IP e porta. Após a conexão TCP ocorrer com sucesso o cliente monta um cabeçalho de requisição HTTP e envia ao servidor, veja o exemplo a seguir:
Supondo que em um navegador seja digitado https://www.helviojunior.com.br (conforme o comando curl abaixo), primeiramente o cliente resolverá o nome DNS para o IP (cujo resultado será 54.244.151.52) e posteriormente enviará o cabeçalho conforme abaixo:
```bash
curl -k https://www.helviojunior.com.br
```
Cabeçalho:
```
GET / HTTP/1.1
Host: www.helviojunior.com.br
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Te: trailers
Connection: close
```
Como podemos observar no cabeçalho `Host` temos o nome completo do servidor. Com o advento do HTTP 1.1 em diante o servidor leva em consideração este campo para rotear internamente em qual site deve responder, sendo que se o servidor estiver preparado para responder por este host (www.helviojunior.com.br) o mesmo o fará.
Porém, nós podemos realizar o mesmo processo de forma diferente, onde direcionamos o cliente em qual endereço IP o mesmo deve conectar e forçamos o host no cabeçalho do HTTP conforme o comando abaixo:
```bash
curl -k -H 'Host: www.helviojunior.com.br' https://54.244.151.52
```
Deste modo obrigatoriamente a conexão TCP ocorrerá para o IP 54.244.151.52 independente da resolução DNS, porém no cabeçalho http será enviado o host www.helviojunior.com.br. Desta forma iremos obter o mesmo resultado como resposta.
Deste modo podemos alterar o endereço IP para qualquer outro, como por exemplo 10.10.10.10 que de o servidor deste IP existir e tiver preparado para responder ao site www.helviojunior.com.br a resposta (HTTP Status code e tamanho) será a mesma.
```bash
curl -k -H 'Host: www.helviojunior.com.br' https://10.10.10.10
```
> :information_source: Porém, no cenário acima o `Subject Name` informado via `SNI` será o IP ao invés do `host`, sendo assim em cenários onde o TLS exige SNI o comando acima não irá funcionar, desta forma precisaremos utilizar outra estratégia.
Para isso utilizaremos o parâmetro `--resolve [DOMAIN]:[PORT]:[IP]` do CURL
```bash
curl -k --resolve www.helviojunior.com.br:443:54.244.151.52 https://www.helviojunior.com.br
```
Deste modo, igualmente no cenário anterior, obrigatoriamente a conexão TCP ocorrerá para o IP 54.244.151.52 pois o parâmetro `--resolve` ignora a resolução de nome via DNS. Adicionalmente desta forma o cabeçalho `host` e o `Subject Name` do `SNI` serão definidos corretamente.
Sendo assim podemos utilizar essa técnica para passar uma lista de IPs e verificar se eles estão configurados para responder por um determinado site.
## Utilização
Recomendamos a utilização dessa ferramenta seguindo os seguintes passos:
- Busca de todos os endereços IP atrelados ao cliente
- Criação de um arquivo TXT com todos os IPs
- Utilização do `WebFinder` para identificar em quais endereços IP o site é acessível
### Endereços IP
Supondo que em processo de enumeração encontrei para o cliente (dono do site helviojunior.com.br) os seguintes endereços IP:
```
13.77.161.179
104.215.148.63
40.76.4.15
54.244.151.52
172.217.1.99
```
### Executando o WebFinder
Ao executar o `WebFinder` temos o resultado abaixo, onde podemos observar que somente o servidor no IP 54.244.151.52 é capaz de responder pela URL www.helviojunior.com.br
```
#webfinder -t https://www.helviojunior.com.br/ -ip /tmp/ips.txt --check-both
Web Finder v0.1.2 by Helvio Junior
automated web server finder
https://github.com/helviojunior/webfinder
[+] Startup parameters
command line: /usr/local/bin/webfinder -t https://www.helviojunior.com.br/ -ip /tmp/ips.txt --check-both
target: https://www.helviojunior.com.br
host: www.helviojunior.com.br
tasks: 16
request method: GET
ip address list: /tmp/ips.txt
start time 2021-06-16 10:31:16
[+] Conectivity checker
[+] Connection test againt https://www.helviojunior.com.br OK! (IP:54.244.151.52|CODE:200|SIZE:72826)
[+] Scanning IP address for https://www.helviojunior.com.br
+ https://54.244.151.52 (CODE:200|SIZE:72826)
+ http://54.244.151.52 (CODE:200|SIZE:72826)
[+] End time 2021-06-16 10:31:24
[+] Finished tests against https://www.helviojunior.com.br, exiting
```
### Utilização com outras ferramentas
#### Enumeração DNS
Download da wordlist e script de recon DNS
```
git clone https://github.com/danielmiessler/SecLists
wget https://raw.githubusercontent.com/helviojunior/libs/master/python/enumdns.py
```
Enumeração
```
python3 enumdns.py -d helviojunior.com.br -w ./SecLists/Discovery/DNS/subdomains-top1million-110000.txt -o dns_enum.txt
```
#### Filtrando endereços IP
Agora vamos extrair somente os endereços IPs (v4) únicos da enumeração do DNS
```
cat dns_enum.txt | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u > ips.txt
```
#### Localizando servidores web
Utilize o `WebFinder` nos endereços IP listados para verificar quais detém a capacidade de responder pelo site desejado
```
webfinder -t https://www.helviojunior.com.br/ -ip ips.txt --check-both
```
Raw data
{
"_id": null,
"home_page": null,
"name": "WafWebFinder",
"maintainer": null,
"docs_url": null,
"requires_python": "<4,>=3.9",
"maintainer_email": "\"Helvio Junior (M4v3r1ck)\" <helvio_junior@hotmail.com>",
"keywords": "web finder, WAF Bypass, development, red team",
"author": null,
"author_email": "\"Helvio Junior (M4v3r1ck)\" <helvio_junior@hotmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b5/f7/aa4a0e4e1e0930fc4b9809c9166996392c28d76094de06aa7a0c90eccb2d/wafwebfinder-0.1.11.tar.gz",
"platform": null,
"description": "# Web Finder (PT-BR)\n\nEsta \u00e9 uma ferramenta para busca de endere\u00e7os IP que respondam por uma URL espec\u00edfica.\n\n## Instala\u00e7\u00e3o\n\n> :information_source: Recomendamos a utiliza\u00e7\u00e3o do `pipx` ao inv\u00e9s do `pip` para instala\u00e7\u00e3o no sistema.\n\n```\npython3 -m pipx install wafwebfinder\n```\n\n> :information_source: Verifique a necessidade de executar tamb\u00e9m o comando `python3 -m pipx ensurepath`\n\n## Conceito t\u00e9cnico\n\nAo realizar uma requisi\u00e7\u00e3o HTTP/S para um host a primeira fase a ser realizada pelo cliente \u00e9 a resolu\u00e7\u00e3o de nome para IP e posteriormente conex\u00e3o direta para este IP. Este procedimento se refere at\u00e9 a camada de Transporte do modelo OSI (camada 4) onde temos apenas IP e porta. Ap\u00f3s a conex\u00e3o TCP ocorrer com sucesso o cliente monta um cabe\u00e7alho de requisi\u00e7\u00e3o HTTP e envia ao servidor, veja o exemplo a seguir:\n\nSupondo que em um navegador seja digitado https://www.helviojunior.com.br (conforme o comando curl abaixo), primeiramente o cliente resolver\u00e1 o nome DNS para o IP (cujo resultado ser\u00e1 54.244.151.52) e posteriormente enviar\u00e1 o cabe\u00e7alho conforme abaixo:\n\n```bash\ncurl -k https://www.helviojunior.com.br\n```\n\nCabe\u00e7alho:\n```\nGET / HTTP/1.1\nHost: www.helviojunior.com.br\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\nAccept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3\nAccept-Encoding: gzip, deflate\nUpgrade-Insecure-Requests: 1\nTe: trailers\nConnection: close\n```\n\nComo podemos observar no cabe\u00e7alho `Host` temos o nome completo do servidor. Com o advento do HTTP 1.1 em diante o servidor leva em considera\u00e7\u00e3o este campo para rotear internamente em qual site deve responder, sendo que se o servidor estiver preparado para responder por este host (www.helviojunior.com.br) o mesmo o far\u00e1.\n\nPor\u00e9m, n\u00f3s podemos realizar o mesmo processo de forma diferente, onde direcionamos o cliente em qual endere\u00e7o IP o mesmo deve conectar e for\u00e7amos o host no cabe\u00e7alho do HTTP conforme o comando abaixo:\n\n```bash\ncurl -k -H 'Host: www.helviojunior.com.br' https://54.244.151.52\n```\n\nDeste modo obrigatoriamente a conex\u00e3o TCP ocorrer\u00e1 para o IP 54.244.151.52 independente da resolu\u00e7\u00e3o DNS, por\u00e9m no cabe\u00e7alho http ser\u00e1 enviado o host www.helviojunior.com.br. Desta forma iremos obter o mesmo resultado como resposta.\n\nDeste modo podemos alterar o endere\u00e7o IP para qualquer outro, como por exemplo 10.10.10.10 que de o servidor deste IP existir e tiver preparado para responder ao site www.helviojunior.com.br a resposta (HTTP Status code e tamanho) ser\u00e1 a mesma.\n\n```bash\ncurl -k -H 'Host: www.helviojunior.com.br' https://10.10.10.10\n```\n\n> :information_source: Por\u00e9m, no cen\u00e1rio acima o `Subject Name` informado via `SNI` ser\u00e1 o IP ao inv\u00e9s do `host`, sendo assim em cen\u00e1rios onde o TLS exige SNI o comando acima n\u00e3o ir\u00e1 funcionar, desta forma precisaremos utilizar outra estrat\u00e9gia.\n\nPara isso utilizaremos o par\u00e2metro `--resolve [DOMAIN]:[PORT]:[IP]` do CURL\n\n```bash\ncurl -k --resolve www.helviojunior.com.br:443:54.244.151.52 https://www.helviojunior.com.br\n```\n\nDeste modo, igualmente no cen\u00e1rio anterior, obrigatoriamente a conex\u00e3o TCP ocorrer\u00e1 para o IP 54.244.151.52 pois o par\u00e2metro `--resolve` ignora a resolu\u00e7\u00e3o de nome via DNS. Adicionalmente desta forma o cabe\u00e7alho `host` e o `Subject Name` do `SNI` ser\u00e3o definidos corretamente.\n\nSendo assim podemos utilizar essa t\u00e9cnica para passar uma lista de IPs e verificar se eles est\u00e3o configurados para responder por um determinado site.\n\n\n## Utiliza\u00e7\u00e3o\n\nRecomendamos a utiliza\u00e7\u00e3o dessa ferramenta seguindo os seguintes passos:\n- Busca de todos os endere\u00e7os IP atrelados ao cliente\n- Cria\u00e7\u00e3o de um arquivo TXT com todos os IPs\n- Utiliza\u00e7\u00e3o do `WebFinder` para identificar em quais endere\u00e7os IP o site \u00e9 acess\u00edvel\n\n### Endere\u00e7os IP\n\nSupondo que em processo de enumera\u00e7\u00e3o encontrei para o cliente (dono do site helviojunior.com.br) os seguintes endere\u00e7os IP:\n\n```\n13.77.161.179\n104.215.148.63\n40.76.4.15\n54.244.151.52\n172.217.1.99\n```\n\n### Executando o WebFinder\n\nAo executar o `WebFinder` temos o resultado abaixo, onde podemos observar que somente o servidor no IP 54.244.151.52 \u00e9 capaz de responder pela URL www.helviojunior.com.br\n\n```\n#webfinder -t https://www.helviojunior.com.br/ -ip /tmp/ips.txt --check-both\n\n Web Finder v0.1.2 by Helvio Junior\n automated web server finder\n https://github.com/helviojunior/webfinder\n\n\n [+] Startup parameters\n command line: /usr/local/bin/webfinder -t https://www.helviojunior.com.br/ -ip /tmp/ips.txt --check-both\n target: https://www.helviojunior.com.br\n host: www.helviojunior.com.br\n tasks: 16\n request method: GET\n ip address list: /tmp/ips.txt\n start time 2021-06-16 10:31:16\n\n [+] Conectivity checker\n [+] Connection test againt https://www.helviojunior.com.br OK! (IP:54.244.151.52|CODE:200|SIZE:72826)\n\n [+] Scanning IP address for https://www.helviojunior.com.br\n+ https://54.244.151.52 (CODE:200|SIZE:72826)\n+ http://54.244.151.52 (CODE:200|SIZE:72826)\n\n [+] End time 2021-06-16 10:31:24\n [+] Finished tests against https://www.helviojunior.com.br, exiting\n```\n\n### Utiliza\u00e7\u00e3o com outras ferramentas\n\n#### Enumera\u00e7\u00e3o DNS\n\nDownload da wordlist e script de recon DNS\n```\ngit clone https://github.com/danielmiessler/SecLists\nwget https://raw.githubusercontent.com/helviojunior/libs/master/python/enumdns.py\n```\n\nEnumera\u00e7\u00e3o\n```\npython3 enumdns.py -d helviojunior.com.br -w ./SecLists/Discovery/DNS/subdomains-top1million-110000.txt -o dns_enum.txt\n```\n\n#### Filtrando endere\u00e7os IP\n\nAgora vamos extrair somente os endere\u00e7os IPs (v4) \u00fanicos da enumera\u00e7\u00e3o do DNS\n\n```\ncat dns_enum.txt | grep -oE '[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}' | sort -u > ips.txt\n```\n\n#### Localizando servidores web\n\nUtilize o `WebFinder` nos endere\u00e7os IP listados para verificar quais det\u00e9m a capacidade de responder pelo site desejado\n\n```\nwebfinder -t https://www.helviojunior.com.br/ -ip ips.txt --check-both\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "Automated web server (behind WAF) finder.",
"version": "0.1.11",
"project_urls": {
"Author": "https://github.com/helviojunior",
"Documentation": "https://github.com/helviojunior/webfinder",
"Source": "https://github.com/helviojunior/webfinder",
"Tracker": "https://github.com/helviojunior/webfinder"
},
"split_keywords": [
"web finder",
" waf bypass",
" development",
" red team"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b5f7aa4a0e4e1e0930fc4b9809c9166996392c28d76094de06aa7a0c90eccb2d",
"md5": "d436830e483a477b6a4de0cff77cd3ed",
"sha256": "89abffd3a72ea07ad20728c8cea5ae2f917a4f6fa056973c614f8c41cf160a9e"
},
"downloads": -1,
"filename": "wafwebfinder-0.1.11.tar.gz",
"has_sig": false,
"md5_digest": "d436830e483a477b6a4de0cff77cd3ed",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.9",
"size": 33604,
"upload_time": "2025-01-02T21:26:09",
"upload_time_iso_8601": "2025-01-02T21:26:09.943692Z",
"url": "https://files.pythonhosted.org/packages/b5/f7/aa4a0e4e1e0930fc4b9809c9166996392c28d76094de06aa7a0c90eccb2d/wafwebfinder-0.1.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-02 21:26:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "helviojunior",
"github_project": "webfinder",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "colorama",
"specs": []
},
{
"name": "requests",
"specs": [
[
">=",
"2.23.0"
]
]
},
{
"name": "cryptography",
"specs": [
[
"==",
"41.0.4"
]
]
},
{
"name": "pyOpenSSL",
"specs": [
[
"==",
"23.2.0"
]
]
},
{
"name": "setuptools",
"specs": [
[
">=",
"75.2.0"
]
]
},
{
"name": "cffi",
"specs": [
[
">=",
"1.17.1"
]
]
}
],
"lcname": "wafwebfinder"
}