
Script NSE do Nmap que consulta a API do Vulners para identificar vulnerabilidades conhecidas (CVEs) em serviços de rede detectados, aprimorando a varredura de portas padrão com busca automatizada de CVEs e pontuação CVSS.
Transforme uma varredura de serviços do nmap em uma lista classificada de CVEs, exploits e o que está sendo atacado na natureza.
Um script NSE que pega o software que o nmap já identificou, consulta o banco de dados Vulners sobre o que é conhecido a respeito dele e imprime a resposta dentro do relatório da varredura — do pior para o melhor, com base no que é realmente explorável.
Varreduras reais de hosts publicados para escaneamento. Sem chave, depois com chave e, em seguida, uma porta web: o do nmap relata um banner Coyote e a varredura identifica o Tomcat e o jQuery por trás dele.
-sVPara cada porta aberta, ele consulta o software que o nmap identificou — os CPEs que o -sV produziu — e imprime o que o Vulners sabe sobre ele: do pior para o melhor, com base no que está sendo explorado em vez de apenas pela pontuação, e cada linha é um link para a página correspondente.
Em uma porta HTTP, ele também faz a impressão digital da própria pilha web, o que identifica softwares que o -sV não consegue ver — um framework de aplicação, um CMS, a versão do PHP por trás de um proxy reverso. 721 regras leem as partes de uma resposta que carregam uma versão: o cabeçalho Server, X-Powered-By, cookies, o título da página, tags <meta>, nomes de arquivos <script src> e o corpo. Essas identidades também são consultadas e publicadas na porta para que o restante da varredura possa usá-las.
Duas coisas que ele faz além da varredura:
-sV não consegue nomear um serviço, o banner bruto é comparado com regras para FTP, SMTP, SSH, MySQL, DNS, NTP, LDAP e outros. Isso não custa nenhuma solicitação extra, e é o caso em que uma porta não reportaria nada de outra forma./CHANGELOG.txt para Drupal, /administrator/manifests/files/joomla.xml para Joomla. Um host que não executa nenhum dos seis produtos sondados não recebe nada extra.```sh
nmap -sV --script vulners Essa é a interface completa. Ela funciona sem uma chave de API; com uma, ela te informa
mais. Não há alternância de modo.```
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
| vulners: cpe:/a:apache:http_server:2.4.7 272 findings, 56 exploitable
| SEVERITY CVSS AI FLAGS LINK
| ======== ==== ==== ======= ==============================================================
| CRITICAL 10.0 8.8 EXP https://vulners.com/gitee/3E6BA608-776F-5B1F-9BA5-589CD2A5A351
| CRITICAL 9.8 9.9 EXP https://vulners.com/zdt/1337DAY-ID-39214
| CRITICAL 9.8 9.6 EXP https://vulners.com/packetstorm/PACKETSTORM:171631
| CRITICAL 9.8 9.9 https://vulners.com/cve/CVE-2021-44790
| CRITICAL 9.8 9.8 https://vulners.com/cve/CVE-2023-25690
|_ 262 more not shown; -v shows all, -vv adds where each was found
Com uma chave, a mesma varredura do mesmo host responde de forma diferente - KEV significa que a CISA registrou a vulnerabilidade como explorada na natureza, e EPSS é a probabilidade publicada de que ela será:```
| vulners: cpe:/a:apache:http_server:2.4.7 272 findings, 78 exploitable
| SEVERITY CVSS EPSS FLAGS LINK
| ======== ==== ==== ======= ==============================================================
| CRITICAL 9.1 >99% KEV EXP https://vulners.com/cve/CVE-2024-38475
| CRITICAL 9.0 >99% KEV EXP https://vulners.com/cve/CVE-2021-40438
| CRITICAL 9.1 >99% KEV https://vulners.com/cnvd/CNVD-2024-36387
| CRITICAL 10.0 71% EXP https://vulners.com/gitee/3E6BA608-776F-5B1F-9BA5-589CD2A5A351
| CRITICAL 9.8 97% EXP https://vulners.com/cve/CVE-2021-44790
|_ 262 more not shown; -v shows all, -vv adds where each was found
Mesmas 272 descobertas, uma ordem diferente, uma linha superior diferente — e 22 delas a mais
conhecidas como exploráveis, porque uma chave liga cada exploit aos CVEs que ele
explora. Ambas são respostas reais do vulners.com, capturadas contra um
servidor local que apresenta esse banner.
## Classificação
Fatos superam previsões. As descobertas são ordenadas:
1. **CISA KEV** — registrado como explorado na natureza
2. **SSVC `active`** — o julgamento de um coordenador de que a exploração está ocorrendo
3. **existe um exploit** — o código está publicado, para este ou para um CVE que ele nomeia
4. **EPSS alto** — um modelo espera exploração
5. todo o resto
O CVSS desempata dentro de uma faixa, não entre elas: um 7.5 explorado é um
problema pior do que um 9.8 não explorado, e esta é a ordem que diz isso.
As colunas seguem os dados. Um sinal que a resposta não carregou perde sua
coluna em vez de mostrar uma célula vazia, porque um EPSS em branco é lido como
"silencioso", e isso é uma afirmação que um campo ausente não pode sustentar.
## O que uma chave de API adiciona
| | |
|---|---|
| **Sem chave** | Cada CPE que o nmap encontrou é consultado no endpoint gratuito. Descobertas, pontuações, sinalizadores de exploit e a própria pontuação de IA do Vulners. Sem créditos, sem conta |
| **Uma chave, sem créditos** | Cada descoberta ganha o que o endpoint de id sabe: títulos, datas, a página upstream de aviso ou exploit, a ligação exploit-para-CVE, CISA KEV e — dependendo da licença — EPSS e SSVC |
| **Uma chave, um crédito** | Software que o caminho gratuito não conseguiu nomear é identificado a partir do seu banner bruto. Esta é a única coisa aqui que custa algo, e apenas para um serviço sem CPE |
Uma porta que já carrega um CPE nunca custa um crédito: medido em quatro
produtos, a consulta gratuita retorna os **mesmos CVEs** que a paga para um CPE.
O que um crédito compra é identificação, não mais vulnerabilidades.
Chaves gratuitas estão em [vulners.com/userinfo](https://vulners.com/userinfo).
## Instalação
**macOS, Linux, Kali, WSL** — uma linha, sem argumentos:```sh
curl -fsSL https://raw.githubusercontent.com/vulnersCom/nmap-vulners/master/install.sh | sh
Windows - PowerShell como Administrador:```powershell irm https://raw.githubusercontent.com/vulnersCom/nmap-vulners/master/install.ps1 | iex
O instalador pergunta ao nmap onde ele guarda os seus dados, copia os scripts e os seus
ficheiros de dados para lá, reconstrói a base de dados de scripts e, em seguida, verifica se
`--script vulners` realmente resolve para o que acabou de instalar - o nmap inclui um
`vulners.nse` próprio, e este substitui-o.
<details>
<summary><b>Sem root e outras opções</b></summary>```sh
# into ~/.nmap, no sudo; the installer prints the NMAPDIR line to add to your profile
curl -fsSL https://raw.githubusercontent.com/vulnersCom/nmap-vulners/master/install.sh | sh -s -- --user
# a specific directory
./install.sh --prefix /usr/local/share/nmap
# a specific release
./install.sh --ref v2.0
# remove everything it installed
./install.sh --uninstall
PowerShell aceita as mesmas opções: -User, -Prefix, -Ref, -Uninstall.
Um arquivo: copie vulners.nse para <nmap data dir>/scripts/ e execute
sudo nmap --script-updatedb. Não há mais nada para colocar — o script
baixa seus dicionários no momento da varredura e não grava nada no disco — e,
portanto, nada para esquecer, o que costumava produzir um script que rodava, não
encontrava nada e não dizia nada sobre o porquê.
Se você estiver atualizando a partir da versão 1.x, exclua também vulners_enterprise.nse e
http-vulners-regex.nse desse diretório. Um http-vulners-regex.nse
remanescente ainda carrega a categoria default e continua varrendo
alvos sob um simples -sC. O instalador faz isso por você.
O diretório de dados do nmap geralmente é /usr/share/nmap (Debian, Ubuntu, Kali),
/usr/local/share/nmap (compilado a partir do código-fonte), /opt/homebrew/share/nmap
(Homebrew) ou C:\Program Files (x86)\Nmap (Windows). Para ter certeza, pergunte ao nmap:```sh
nmap -d2 --script-help probe 2>&1 | grep nse_main.lua
O diretório que contém `nse_main.lua` é o que este nmap usa.
</details>
## Argumentos do script
| Argumento | Padrão | Significado |
|---|---|---|
| `vulners.mincvss` | `0` | Oculta resultados abaixo desta pontuação. Boletins sem pontuação e qualquer coisa com exploit conhecido são exibidos independentemente do limite |
| `vulners.paths` | os 939 caminhos publicados | Caminhos para a varredura web: uma lista Lua, uma string nomeando um arquivo com um caminho por linha, ou `none` para desativar a varredura. Um arquivo que você nomear e que não puder ser lido interrompe a varredura e informa isso, em vez de recorrer à lista publicada |
| `vulners.width` | `80` | Largura do terminal para a qual a tabela é formatada |
| `vulners.max_items` | `32` | Teto de itens cobrados para toda a varredura |
| `vulners.api_key` | - | Token da API. Vazado: o nmap copia sua própria linha de comando para `-oX` |
| `vulners.api_key_file` | - | Caminho absoluto para um arquivo cuja primeira linha é o token |
| `vulners.api_host` | `vulners.com` | Nome do host da API |
| `vulners.api_port` | `443` | Porta em `api_host` |
Um nome simples também funciona, então `--script-args mincvss=7` é suficiente.
Os prefixos de argumento da versão 1.x - `vulners_enterprise.*` e
`http-vulners-regex.paths` - são aceitos por uma versão e exibem um aviso de
depreciação.
## Onde manter a chave da API
Em ordem de preferência:
1. `~/.nmap/vulners.key`, uma linha, modo 600 - o instalador se oferece para escrevê-la
2. `VULNERS_API_KEY` no ambiente
3. `--script-args vulners.api_key_file=/absolute/path`
4. `--script-args vulners.api_key=<token>`
A última é conveniente e vazada: o nmap copia sua própria linha de comando para
cada relatório, então o token acaba no atributo `args` da saída `-oX` e no seu
histórico do shell. O script em si nunca escreve o token em lugar algum,
incluindo sua saída de depuração - há um teste de regressão que afirma isso.
Um arquivo de chave que você nomear explicitamente e que não puder ser lido
interrompe a execução em vez de recorrer silenciosamente - um operador que
nomeia um arquivo quer dizer aquele arquivo - e o relatório informa qual arquivo
foi. Um caminho digitado errado não pode parecer uma varredura limpa.
## De onde vêm as impressões digitais
O script não as carrega. Ele baixa três dicionários uma vez por varredura,
antes de o primeiro host ser tocado:```
https://raw.githubusercontent.com/vulnersCom/nmap-vulners/catalog/
index.json what exists, at which serial
fingerprints.json 721 product and version rules
paths.json 939 paths the sweep requests
probes.json targeted version probes
Isso são quatro solicitações por varredura — uma por arquivo, não por host e não por porta — para 40 KB compactados de 250 KB de JSON, na fase de pré-varredura do nmap. Medido em relação ao branch publicado. Um script instalado, portanto, capta novas impressões digitais sem ser atualizado.
Ele não grava nada no seu sistema de arquivos. Os dicionários são mantidos durante a duração da varredura e descartados, que é como todo script que o nmap acompanha se comporta: dos 611 deles, 26 abrem um arquivo para gravação e cada um grava apenas onde um argumento de script lhe disse. Nenhum mantém um cache, e este também não.
Se eles não puderem ser baixados, a varredura ainda é executada. Os dicionários alimentam a identificação de impressões digitais da web e nada mais, então uma máquina sem rota para o GitHub perde isso e mantém todo o resto: o software que o próprio nmap identificou ainda é consultado, e o relatório diz qual capacidade estava ausente, em vez de deixar você ler um resultado vazio como uma rede limpa.
| argumento | o que faz |
|---|---|
vulners.catalog_url=<url> | buscar de um espelho em vez disso — para uma rede isolada. Um nome de host ou um endereço IPv6 entre colchetes, http://[fd00::1]/catalog/ |
vulners.catalog=none | não buscar de forma alguma; consultar apenas o que o nmap nomeou |
Em uma porta HTTP, o script solicita cada caminho que o catálogo publica — 939
caminhos — e compara todas as 721 regras contra cada resposta. Os caminhos vêm do
WhatWeb, nuclei e FingerprintHub: lugares onde um produto é reconhecido, em vez de
suposições. Até um caminho pertencente a software que você não está executando vale a
solicitação, porque a resposta ainda carrega Server, X-Powered-By, um cookie e
um título, e são esses que as regras usam para encontrar a pilha à sua frente.
O quão rápido isso vai é o seu -T, não uma configuração nossa. A lista nunca
diminui; a taxa diminui:
Todos os seis medidos em uma única execução contra o mesmo servidor local. Somente -sV contra
ele é 6,1 s, então a varredura custa um segundo e meio no padrão. As duas linhas
lentas são -T0 e -T1 fazendo seu trabalho: 188 e 94 lotes, com uma espera
deliberada entre cada um.
As solicitações são canalizadas por 34–48 conexões com no máximo quatro abertas por
vez, que é o pipeline_go do nselib — a mesma maquinaria que o próprio
http-enum do nmap usa, respeitando o Keep-Alive: max= do servidor e
--script-args http.max-pipeline=N.
--script-args vulners.paths=none desliga a varredura completamente.
nmap -sV | +-- service fingerprint --> port.version.cpe --------------+ | | +-- vulners.nse | reads nmap's banner for services -sV could not name | on an HTTP port: requests the path list in one | pipeline, matches 721 rules against the header, the | title, the meta tags, the scripts and the body | probes for a version when a product hid it | publishes everything it recognised ------------------+ | v GET /api/v3/burp/software/ per identity free, no key, CDN-cached | POST /api/v3/search/id/ per 100 findings free, needs a key: enrichment | POST /api/v4/audit/smart only for a service with no CPE: 1 credit | ranked, filtered, printed
As respostas são armazenadas em cache para toda a verificação, indexadas por identidade, então cem servidores idênticos custam uma única consulta. O enriquecimento é armazenado em cache por ID de descoberta, então duas portas web executando software sobreposto buscam cada documento apenas uma vez.
## Saída legível por máquina
Tudo o que é impresso também é estruturado, então `-oX` pode ser analisado sem tocar no texto legível por humanos. O ID do script, os dois níveis de tabela e as cinco chaves originais dos elementos permanecem inalterados desde a versão 1.x, que é o que DefectDojo, Faraday, nmap2csv e raven leem:```xml
<script id="vulners">
<elem key="schema">2.0</elem>
<elem key="mode">keyed</elem>
<table key="cpe:/a:apache:http_server:2.4.7">
<table>
<elem key="id">CVE-2021-40438</elem>
<elem key="type">cve</elem>
<elem key="severity">CRITICAL</elem>
<elem key="cvss">9.0</elem>
<elem key="cvss_type">cvss3.1</elem>
<elem key="is_exploit">false</elem>
<elem key="exploit_known">true</elem>
<elem key="kev">true</elem>
<elem key="epss">0.99612</elem>
<elem key="exploitation">active</elem>
<elem key="title">Apache HTTP Server SSRF in mod_proxy</elem>
<elem key="href">https://vulners.com/cve/CVE-2021-40438</elem>
<elem key="source_href">https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-40438</elem>
</table>
</table>
</script>
Novidades na versão 2.0: schema, mode, severity, exploit_known, kev, epss,
epss_percentile, exploitation, ai_score, title, published, href,
source_href e found_on. Cada um está presente ou ausente, nunca vazio.
Nada está aninhado mais profundamente do que antes, porque um terceiro nível de
tabela é invisível para todos os importadores examinados.
href é sempre a página do vulners.com para a descoberta, em ambos os modos. O
próprio href do endpoint é o endereço upstream - nvd.nist.gov para um CVE,
github.com para um exploit raspado - e esse viaja separadamente, como
source_href, de modo que o significado de nenhum campo depende de qual modo o
produziu.
A saída estruturada sempre carrega todas as descobertas que passaram em mincvss,
até mesmo aquelas que a escada de verbosidade esconde do texto - então nenhuma
automação perde descobertas por não passar -v.
O texto renderizado é uma quebra. Os tokens *EXPLOIT* e *HAS EXPLOIT*
e o layout separado por tabulações desapareceram, substituídos pela tabela
alinhada acima. O link do vulners.com por linha permaneceu: é a última coluna, e
é a única célula que o layout não encurtará, porque metade de uma URL não é uma
URL. Consumidores que fazem raspagem de texto precisam de atualização; os
consumidores de -oX não.
Uma varredura de uma rede faz muito menos perguntas à API do que parece:
Os testes, o portão de higiene e o CONTRIBUTING.md estão apenas no repositório
git; o arquivo de lançamento inclui os scripts e seus dados. Oito portões, todos
offline exceto onde indicado, e o CI executa exatamente estes:```sh
nmap -sn -Pn --script ./tests/run.nse --script-args testdir=tests,root=. 127.0.0.1
python3 tests/e2e/run_e2e.py
python3 tools/check.py
python3 tools/catalog.py --check
python3 tools/xml_contract.py --selftest
python3 tools/fingerprints/selftest.py
python3 tools/catalog_diff.py --selftest
python3 tools/nmap_style.py
270 casos de unidade executados dentro do nmap contra as bibliotecas NSE reais; 64 casos de ponta a ponta
acionam o binário real do nmap contra um servidor web local e uma API Vulners substituta
que impõe o que a real impõe; o portão de higiene mantém segredos, saída de varredura e lixo do editor
fora da árvore e recusa uma leitura global que o NSE transformaria em um resultado perdido; e os últimos quatro guardam os dados e
as ferramentas que os publicam - a forma do catálogo, o contrato XML que todo
importador lê, o tradutor de padrões e o portão que decide se uma reconstrução é
segura para publicar. O último guarda todo o repositório conforme os
[Padrões de Código do próprio Nmap](https://secwiki.org/w/Nmap/Code_Standards), que
o `HACKING` nomeia como a autoridade para um script que queira viver na árvore do
nmap: sem tabs, sem espaços em branco no fim das linhas, linhas com menos de 80 colunas, sem ponto e vírgula,
documentação NSEdoc privada começando com `--;`, PEP 8 para o Python.
`python3 tests/e2e/run_e2e.py --live` adiciona verificações contra o serviço real.
Consulte [CONTRIBUTING.md](https://github.com/vulnerscom/nmap-vulners/blob/master/CONTRIBUTING.md).
## FAQ
**Ele explora algo?** Não. Ele lê banners e páginas e consulta um
banco de dados - não envia payload e não tenta credencial. Ele é categorizado
como `discovery, intrusive, vuln, external` em vez de `safe`, por um motivo: a
varredura de caminhos solicita 939 caminhos de uma porta web, e a definição de `safe` do nmap
exclui scripts que usam grandes quantidades de largura de banda. O próprio `http-enum` do nmap
solicita 2 204 e carrega o mesmo rótulo. Seu `-T` define a velocidade com que eles saem
e nunca quantos, e `--script-args vulners.paths=none` desativa a varredura
por completo.
**Funciona sem uma chave de API?** Sim, totalmente. Sem uma, ele usa o endpoint
gratuito, que retorna as mesmas vulnerabilidades para um CPE que o pago. Uma
chave adiciona detalhes por descoberta e pode nomear software que o caminho gratuito não pode.
**Por que o `-sC` parou de encontrar software web?** Porque `vulners` não está mais na
categoria `default` do nmap, e nem a varredura de impressão digital que costumava
viver em `http-vulners-regex.nse`. Enviar a identidade do software de um alvo para
um terceiro deve ser algo que você pediu: execute `--script vulners`.
**Por que uma vulnerabilidade mostra `cvss2.0` enquanto outra mostra `cvss3.1`?** O
rótulo nomeia a escala em que a pontuação está. O Vulners retorna a que a fonte
publicou; uma pontuação v2 de 9.3 não é uma pontuação v3 de 9.3.
**Por que uma entrada de baixa pontuação é exibida quando defino `mincvss`?** Porque ela tem um
exploit conhecido, ou porque a fonte nunca a pontuou. Ambos são intencionais.
**O relatório diz que o catálogo não pôde ser baixado.** Então a impressão digital
web não foi executada e todo o resto foi: o software que o próprio nmap
nomeou ainda foi consultado. É dito em voz alta por esse motivo - uma capacidade
que não foi executada parece uma capacidade que não encontrou nada. As duas causas têm
redação separada: "could not be downloaded" é a rede, e "answered, but
one of its dictionaries could not be read" é o espelho para o qual você a apontou.
**Não encontrou nada em um host que sei que é vulnerável.** Execute com `-d2`: ele registra
cada identidade sobre a qual perguntou. Normalmente o nmap nomeou o serviço, mas não sua
versão, e não há versão para consultar.
## Licença
Os scripts são licenciados da mesma forma que o próprio Nmap - consulte [LICENSE](https://github.com/vulnerscom/nmap-vulners/blob/master/LICENSE) para a
Nmap Public Source License, e
[nmap.org/npsl](https://nmap.org/npsl/) para saber o que ela significa.
Os dados de vulnerabilidade vêm do [Vulners](https://vulners.com) e estão sujeitos aos
seus termos.
## Relacionados
* [vulners.com](https://vulners.com) - o banco de dados por trás destes scripts
* [vulnersCom/api](https://github.com/vulnersCom/api) - o cliente Python
* [vulnersCom/burp-vulners-scanner](https://github.com/vulnersCom/burp-vulners-scanner) - os mesmos dados dentro do Burp Suite
* [nmap.org/book/nse.html](https://nmap.org/book/nse.html) - como os scripts NSE funcionam
---
<div align="center">
Mantido pela Equipe Vulners <[email protected]>
`#nmap` `#nse` `#vulnerability-scanner` `#cve` `#cvss` `#cpe` `#vulners`
`#security-tools` `#pentest` `#infosec` `#network-scanner` `#exploit-database`
`#lua` `#vulnerability-detection` `#security-automation`
</div>
| lotes | espera entre eles | medido, uma porta web |
|---|
-T0 paranóico | 188 x 5 | 2 s | 11 m 22 s |
-T1 sorrateiro | 94 x 10 | 1 s | 1 m 56 s |
-T2 educado | 38 x 25 | 0,5 s | 26,2 s |
-T3 normal | 10 x 100 | 0,1 s | 7,6 s |
-T4 agressivo | 4 x 250 | nenhum | 6,7 s |
-T5 insano | 1 | nenhum | 6,6 s |