
Scanner de portas TCP, emite pacotes SYN de forma assíncrona, escaneando toda a Internet em menos de 5 minutos.
Este é um scanner de portas em escala de Internet. Ele pode escanear toda a Internet em menos de 5 minutos, transmitindo 10 milhões de pacotes por segundo, a partir de uma única máquina.
Seu uso (parâmetros, saída) é semelhante ao nmap, o scanner de portas mais famoso.
Em caso de dúvida, experimente um desses recursos – funcionalidades que suportam
varredura generalizada de muitas máquinas são suportadas, enquanto a varredura aprofundada
de máquinas individuais não.
Internamente, ele usa transmissão assíncrona, semelhante a scanners de portas
como scanrand, unicornscan e ZMap. É mais flexível, permitindo
faixas arbitrárias de portas e endereços.
NOTA: o masscan usa sua própria pilha TCP/IP ad hoc. Qualquer coisa além de
varreduras de portas simples pode causar conflito com a pilha TCP/IP local. Isso significa que você
precisa usar a opção --src-ip para executar a partir de um endereço IP diferente, ou
usar --src-port para configurar quais portas de origem o masscan usa, e então também
configurar o firewall interno (como pf ou iptables) para firewalling essas portas
do resto do sistema operacional.
Esta ferramenta é gratuita, mas considere contribuir com dinheiro para seu desenvolvimento: Endereço da carteira Bitcoin: 1MASSCANaHUiyTtR3bJ2sLGuMw5kDBaj4T
No Debian/Ubuntu, é algo como o seguinte. Na verdade, não
tem dependências além de um compilador C (como gcc
ou clang).
sudo apt-get --assume-yes install git make gcc
git clone https://github.com/robertdavidgraham/masscan
cd masscan
make
Isso coloca o programa no subdiretório masscan/bin.
Para instalá-lo (no Linux) execute:
make install
O código fonte consiste em muitos arquivos pequenos, então a compilação fica muito mais rápida
usando a compilação com vários threads. Isso requer mais de 2 GB em um
Raspberry Pi (e quebra), então você pode usar um número menor, como -j4 em vez de
todos os threads possíveis.
make -j
Embora o Linux seja a plataforma alvo principal, o código roda bem em muitos outros sistemas (Windows, macOS, etc.). Aqui estão algumas informações adicionais de compilação:
makemakegmakecc src/*.c -o bin/masscanNo macOS, os binários x86 parecem funcionar tão rápido sob emulação ARM.
O uso é semelhante ao nmap. Para escanear um segmento de rede para algumas portas:
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112
Isso irá:
10.x.x.x e as sub-redes 2603:3001:2d00:da00::x<stdout> que pode ser redirecionada para um arquivoPara ver a lista completa de opções, use o recurso --echo. Isso
despeja a configuração atual e sai. Esta saída pode ser usada como entrada de volta
no programa:
# masscan -p80,8000-8100 10.0.0.0/8 2603:3001:2d00:da00::/112 --echo > xxx.conf
# masscan -c xxx.conf --rate 1000
O Masscan pode fazer mais do que apenas detectar se as portas estão abertas. Ele também pode completar a conexão TCP e a interação com o aplicativo naquela porta para capturar informações simples de "banner".
O Masscan suporta verificação de banner nos seguintes protocolos:
O problema com isso é que o masscan contém sua própria pilha TCP/IP separada do sistema no qual você o executa. Quando o sistema local recebe um SYN-ACK do alvo sondado, ele responde com um pacote RST que interrompe a conexão antes que o masscan possa capturar o banner.
A maneira mais fácil de evitar isso é atribuir ao masscan um endereço IP separado. Isso seria algo como um dos seguintes exemplos:
# masscan 10.0.0.0/8 -p80 --banners --source-ip 192.168.1.200
# masscan 2a00:1450:4007:810::/112 -p80 --banners --source-ip 2603:3001:2d00:da00:91d7:b54:b498:859d
O endereço que você escolher deve estar na sub-rede local e não deve estar sendo usado por outro sistema. O Masscan avisará que você cometeu um erro, mas você pode ter bagunçado as comunicações da outra máquina por vários minutos, então tome cuidado.
Em alguns casos, como WiFi, isso não é possível. Nesses casos, você pode firewallar a porta que o masscan usa. Isso impede que a pilha TCP/IP local veja o pacote, mas o masscan ainda o vê, pois ele contorna a pilha local. Para Linux, seria algo como:
# iptables -A INPUT -p tcp --dport 61000 -j DROP
# masscan 10.0.0.0/8 -p80 --banners --source-port 61000
Você provavelmente deseja escolher portas que não conflitem com portas que o Linux possa escolher para portas de origem. Você pode ver a faixa que o Linux usa e reconfigurar essa faixa, olhando no arquivo:
/proc/sys/net/ipv4/ip_local_port_range
Na versão mais recente do Kali Linux (agosto de 2018), essa faixa é 32768 a 60999, então você deve escolher portas abaixo de 32768 ou acima de 61000.
Definir uma regra iptables só dura até a próxima reinicialização. Você precisa descobrir como
salvar a configuração dependendo da sua distribuição, como usar iptables-save
e/ou iptables-persistent.
No Mac OS X e BSD, existem etapas semelhantes. Para descobrir as faixas a evitar, use um comando como o seguinte:
# sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
No FreeBSD e MacOS mais antigo, use um comando ipfw:
# sudo ipfw add 1 deny tcp from any to any 40000 in
# masscan 10.0.0.0/8 -p80 --banners --source-port 40000
No MacOS mais novo e OpenBSD, use o utilitário de filtro de pacotes pf.
Edite o arquivo /etc/pf.conf para adicionar uma linha como a seguinte:
block in proto tcp from any to any port 40000:40015
Em seguida, para ativar o firewall, execute o comando:
# pfctl -E
Se o firewall já estiver em execução, reinicie ou recarregue as regras com o seguinte comando:
# pfctl -f /etc/pf.conf
O Windows não responde com pacotes RST, então nenhuma dessas técnicas é necessária. No entanto, o masscan ainda é projetado para funcionar melhor usando seu próprio endereço IP, portanto, você deve executá-lo dessa forma quando possível, mesmo quando não for estritamente necessário.
O mesmo é necessário para outras verificações, como a verificação --heartbleed,
que é apenas uma forma de verificação de banner.
Embora útil para redes internas menores, o programa é realmente projetado com toda a Internet em mente. Pode ser algo assim:
# masscan 0.0.0.0/0 -p0-65535
Escaneamento da Internet é ruim. Por um lado, partes da Internet reagem mal a serem escaneadas. Por outro lado, alguns sites rastreiam escaneamentos e adicionam você a uma lista de banimento, o que fará com que você seja firewalled de partes úteis da Internet. Portanto, você deseja excluir muitos intervalos. Para colocar na lista negra ou excluir intervalos, você deseja usar a seguinte sintaxe:
# masscan 0.0.0.0/0 -p0-65535 --excludefile exclude.txt
Isso apenas imprime os resultados na linha de comando. Você provavelmente deseja que eles sejam salvos em um arquivo. Portanto, você deseja algo como:
# masscan 0.0.0.0/0 -p0-65535 -oX scan.xml
Isso salva os resultados em um arquivo XML, permitindo que você facilmente despeje os resultados em um banco de dados ou algo do tipo.
Mas isso vai apenas na taxa padrão de 100 pacotes/segundo, o que levará uma eternidade para escanear a Internet. Você precisa acelerar assim:
# masscan 0.0.0.0/0 -p0-65535 --max-rate 100000
Isso aumenta a taxa para 100.000 pacotes/segundo, o que escaneará a Internet inteira (menos exclusões) em cerca de 10 horas por porta (ou 655.360 horas se escanear todas as portas).
A coisa a notar sobre esta linha de comando é que estas são todas opções
compatíveis com nmap. Além disso, opções "invisíveis" compatíveis com nmap
também são definidas para você: -sS -Pn -n --randomize-hosts --send-eth. Da mesma forma,
o formato do arquivo XML é inspirado pelo nmap. Existem, é claro, muitas
diferenças, porque a natureza assíncrona do programa
leva a uma abordagem fundamentalmente diferente do problema.
A linha de comando acima é um pouco complicada. Em vez de colocar tudo na linha de comando, pode ser armazenado em um arquivo. As configurações acima seriam assim:
# My Scan
rate = 100000.00
output-format = xml
output-status = all
output-filename = scan.xml
ports = 0-65535
range = 0.0.0.0-255.255.255.255
excludefile = exclude.txt
Para usar este arquivo de configuração, use o -c:
# masscan -c myscan.conf
Isso também facilita quando você repete um escaneamento.
Por padrão, o masscan primeiro carrega o arquivo de configuração
/etc/masscan/masscan.conf. Quaisquer parâmetros de configuração posteriores substituem o que
está neste arquivo de configuração padrão. É aí que coloco meu parâmetro "excludefile"
para que nunca o esqueça. Funciona automaticamente.
Por padrão, o masscan produz arquivos de texto bastante grandes, mas é fácil convertê-los em qualquer outro formato. Existem cinco formatos de saída suportados:
xml: Basta usar o parâmetro -oX <filename>.
Ou use os parâmetros --output-format xml e --output-filename <filename>.
binary: Este é o formato nativo do masscan. Produz arquivos muito menores para que
quando escaneio a Internet meu disco não encha. Eles precisam ser analisados,
no entanto. A opção de linha de comando --readscan lerá arquivos de escaneamento binários.
Usar --readscan com a opção -oX produzirá uma versão XML do
arquivo de resultados.
grepable: Esta é uma implementação da saída -oG do Nmap
que pode ser facilmente analisada por ferramentas de linha de comando. Basta usar o
parâmetro -oG <filename>. Ou use os parâmetros --output-format grepable e
--output-filename <filename>.
json: Isso salva os resultados no formato JSON. Basta usar o
parâmetro -oJ <filename>. Ou use os parâmetros --output-format json e
.
Onde for razoável, todo esforço foi feito para tornar o programa familiar
aos usuários de nmap, mesmo que seja fundamentalmente diferente. O Masscan é ajustado
para varredura de amplo alcance de muitas máquinas, enquanto o nmap é projetado para
varredura intensiva de uma única máquina ou de um pequeno intervalo.
Duas diferenças importantes são:
-p <ports>nmap pode usar (como 10.0.0-255.0-255).Você pode pensar que o masscan tem as seguintes configurações permanentemente
ativadas:
-sS: faz apenas varredura SYN (atualmente, mudará no futuro)-Pn: não faz ping nos hosts primeiro, o que é fundamental para a operação assíncrona-n: nenhuma resolução DNS acontece--randomize-hosts: varredura completamente aleatória, sempre, você não pode mudar isso--send-eth: envia usando libpcap brutoSe você quiser uma lista de configurações adicionais compatíveis com nmap, use o seguinte
comando:
# masscan --nmap
Este programa expele pacotes muito rapidamente. No Windows, ou de VMs, pode fazer 300.000 pacotes/segundo. No Linux (sem virtualização) fará 1,6 milhão de pacotes por segundo. Isso é rápido o suficiente para derreter a maioria das redes.
Observe que ele derreterá apenas sua própria rede. Ele randomiza os endereços IP alvo para que não sobrecarregue nenhuma rede distante.
Por padrão, a taxa é definida como 100 pacotes/segundo. Para aumentar a taxa para
um milhão, use algo como --rate 1000000.
Ao escanear a Internet IPv4, você estará escaneando muitas sub-redes, então, mesmo que haja uma alta taxa de pacotes saindo, cada sub-rede alvo receberá uma pequena taxa de pacotes recebidos.
No entanto, com a varredura IPv6, você tenderá a focar em uma única sub-rede alvo com bilhões de endereços. Assim, seu comportamento padrão sobrecarregará a rede alvo. As redes muitas vezes travam sob a carga que o masscan pode gerar.
Esta seção descreve os principais problemas de projeto do programa.
O arquivo main.c contém a função main(), como você esperaria. Também contém
as funções transmit_thread() e receive_thread(). Estas funções
foram deliberadamente simplificadas e amplamente comentadas para que você
possa ler o projeto do programa simplesmente percorrendo linha por linha cada
uma delas.
Este é um projeto assíncrono. Em outras palavras, é para o nmap o que
o servidor web nginx é para o Apache. Possui threads de transmissão e recepção
separados que são amplamente independentes entre si. É o mesmo tipo de projeto
encontrado em scanrand, unicornscan e ZMap.
Por ser assíncrono, roda tão rápido quanto a transmissão de pacotes subjacente permite.
Uma diferença chave entre o Masscan e outros scanners é a maneira como ele randomiza os alvos.
O princípio fundamental é ter uma única variável de índice que começa em zero e é incrementada por um para cada sonda. Em código C, isso é expresso como:
for (i = 0; i < range; i++) {
scan(i);
}
Temos que traduzir o índice em um endereço IP. Digamos que você queira escanear todos os endereços IP "privados". Isso seria a tabela de intervalos como:
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
Neste exemplo, os primeiros 64k índices são anexados a 192.168.x.x para formar o endereço alvo. Então, os próximos 16 milhões são anexados a 10.x.x.x. Os índices restantes no intervalo são aplicados a 172.16.x.x.
Neste exemplo, temos apenas três intervalos. Ao escanear toda a Internet, temos na prática mais de 100 intervalos. Isso porque você precisa colocar na lista negra ou excluir muitos sub-intervalos. Isso divide o intervalo desejado em centenas de intervalos menores.
Isso leva a uma das partes mais lentas do código. Transmitimos 10 milhões de pacotes por segundo e temos que converter uma variável de índice em um endereço IP para cada sonda. Resolvemos isso fazendo uma "busca binária" em uma pequena quantidade de memória. Nesta taxa de pacotes, as eficiências de cache começam a dominar sobre as eficiências de algoritmo. Existem muitas técnicas mais eficientes em teoria, mas todas exigem tanta memória que se tornam mais lentas na prática.
Chamamos a função que traduz de um índice para um endereço IP
de função pick(). Em uso, parece:
for (i = 0; i < range; i++) {
ip = pick(addresses, i);
scan(ip);
}
O Masscan suporta não apenas intervalos de endereços IP, mas também intervalos de portas. Isso significa que precisamos selecionar a partir da variável de índice tanto um endereço IP quanto uma porta. Isso é bastante direto:
range = ip_count * port_count;
for (i = 0; i < range; i++) {
ip = pick(addresses, i / port_count);
port = pick(ports, i % port_count);
scan(ip, port);
}
Isso leva a outra parte cara do código. As instruções de divisão/módulo são cerca de 90 ciclos de clock, ou 30 nanossegundos, em CPUs x86. Quando transmitindo a uma taxa de 10 milhões de pacotes/segundo, temos apenas 100 nanossegundos por pacote. Não vejo como otimizar isso melhor. Felizmente, porém, duas dessas operações podem ser executadas simultaneamente, então fazer duas delas, como mostrado acima, não é mais caro do que fazer uma.
Na verdade, existem algumas otimizações fáceis para os problemas de desempenho acima,
mas todas elas dependem de i++, o fato de que a variável de índice aumenta uma
por uma durante a varredura. Na verdade, precisamos randomizar esta variável.
Precisamos randomizar a ordem dos endereços IP que escaneamos ou vamos bombardear
as redes alvo que não são construídas para este nível de velocidade.
Precisamos espalhar nosso tráfego uniformemente sobre o alvo.
A maneira como randomizamos é simplesmente criptografando a variável de índice. Por definição, a criptografia é aleatória e cria um mapeamento 1 para 1 entre a variável de índice original e a saída. Isso significa que enquanto percorremos linearmente o intervalo, os endereços IP de saída são completamente aleatórios. Em código, isso se parece com:
range = ip_count * port_count;
for (i = 0; i < range; i++) {
x = encrypt(i);
ip = pick(addresses, x / port_count);
port = pick(ports, x % port_count);
scan(ip, port);
}
Isso também tem um custo importante. Como o intervalo é um tamanho imprevisível em vez de uma potência de 2 uniforme, não podemos usar técnicas binárias baratas como AND (&) e XOR (^). Em vez disso, temos que usar operações caras como MÓDULO (%). Em meus benchmarks atuais, está levando 40 nanossegundos para criptografar a variável.
Esta arquitetura permite muitos recursos interessantes. Por exemplo, suporta
"shards". Você pode configurar 5 máquinas cada uma fazendo um quinto da varredura ou
range / shard_count. Shards podem ser várias máquinas, ou simplesmente vários
adaptadores de rede na mesma máquina, ou mesmo (se você quiser) vários endereços IP
de origem no mesmo adaptador de rede.
Ou você pode usar uma 'semente' ou 'chave' para a função de criptografia, para obter uma
ordem diferente cada vez que escanear, como x = encrypt(seed, i).
Também podemos pausar a varredura saindo do programa e simplesmente
lembrar o valor atual de i, e reiniciá-la mais tarde. Faço isso bastante
durante o desenvolvimento. Vejo algo dando errado com minha varredura na Internet, então
aperto <ctrl-c> para parar a varredura e reinicio após corrigir o bug.
Outro recurso são retransmissões/repetições. Pacotes às vezes são perdidos na
Internet, então você pode enviar dois pacotes consecutivamente. No entanto, algo que
descartar um pacote pode descartar o pacote imediatamente seguinte. Portanto, você
deseja enviar a cópia com cerca de 1 segundo de intervalo. Isso é simples. Já temos
uma variável 'rate', que é a taxa de pacotes por segundo que estamos
transmitindo, então a função de retransmissão é simplesmente usar i + rate
como o índice. Um dia desses vou fazer um estudo da Internet
e diferenciar "consecutivo", "1 segundo", "10 segundos" e "1 minuto"
de retransmissões desta forma para ver se há alguma diferença no que
é descartado.
A técnica assíncrona é conhecida como uma solução para o "problema c10k". O Masscan é projetado para o próximo nível de escalabilidade, o "problema C10M".
A solução C10M é contornar o kernel. Existem três principais contornos de kernel no Masscan:
O Masscan pode usar o driver PF_RING DNA. Este driver faz DMA de pacotes diretamente da memória do modo de usuário para o driver de rede com zero envolvimento do kernel. Isso permite que o software, mesmo com uma CPU lenta, transmita pacotes na taxa máxima que o hardware permite. Se você colocar 8 placas de rede de 10 Gbps em um computador, isso significa que ele poderia transmitir a 100 milhões de pacotes/segundo.
O Masscan tem sua própria pilha TCP embutida para capturar banners de conexões TCP. Isso significa que pode suportar facilmente 10 milhões de conexões TCP simultâneas, assumindo, é claro, que o computador tenha memória suficiente.
O Masscan não tem "mutex". Mutexes modernos (também conhecidos como futexes) são principalmente em modo de usuário, mas eles têm dois problemas. O primeiro problema é que eles fazem as linhas de cache saltarem rapidamente entre CPUs. O segundo é que quando há contenção, eles fazem uma chamada de sistema para o kernel, o que mata o desempenho. Um mutex no caminho rápido de um programa limita severamente a escalabilidade. Em vez disso, o Masscan usa "anéis" para sincronizar as coisas, como quando a pilha TCP em modo de usuário no thread de recepção precisa transmitir um pacote sem interferir com o thread de transmissão.
Windows e Macs não são otimizados para transmissão de pacotes, e conseguem apenas cerca de 300.000 pacotes por segundo, enquanto o Linux pode atingir 1.500.000 pacotes/segundo. Isso é provavelmente mais rápido do que você quer de qualquer forma.
Uma recompensa é oferecida por vulnerabilidades, veja o arquivo VULNINFO.md para mais informações.
Este projeto usa funções seguras como safe_strcpy() em vez de funções inseguras como strcpy().
Este projeto possui testes automatizados de regressão unitária (make regress).
Muito esforço foi feito para fazer a entrada/saída se parecer com o nmap, com o qual todos que fazem varreduras de portas estão (ou deveriam estar) familiarizados.
Masscan suporta IPv6, mas não há um modo especial, ambos são suportados ao mesmo tempo. (Não há opção -6 -- ela está sempre disponível).
Em qualquer exemplo de uso do masscan que você veja, simplesmente coloque um endereço IPv6 onde você vê um endereço IPv4. Você pode incluir endereços IPv4 e IPv6 simultaneamente na mesma varredura. A saída inclui o endereço apropriado na mesma localização, sem marcação especial.
Lembre-se apenas que o espaço de endereços IPv6 é realmente grande. Você provavelmente não vai querer varrer grandes intervalos, exceto talvez os primeiros 64 mil endereços de uma sub-rede que foram atribuídos via DHCPv6.
Em vez disso, você provavelmente vai querer varrer grandes listas de endereços armazenadas em um arquivo (--include-file filename.txt) que você obteve de outras fontes. Como em qualquer outro lugar, este arquivo pode conter listas de endereços IPv4 e IPv6. O arquivo de teste que uso contém 8 milhões de endereços. Arquivos desse tamanho precisam de alguns segundos extras para serem lidos na inicialização (masscan ordena os endereços e remove duplicatas antes de escanear).
Lembre-se que o masscan contém sua própria pilha de rede. Portanto, a máquina local a partir da qual você executa o masscan não precisa ter IPv6 habilitado -- embora a rede local precise ser capaz de rotear pacotes IPv6.
Para ultrapassar 2 milhões de pacotes por segundo, você precisa de um adaptador Ethernet Intel de 10 Gbps e um driver especial conhecido como "PF_RING ZC" da ntop. O Masscan não precisa ser reconstruído para usar o PF_RING. Para usar o PF_RING, você precisa construir os seguintes componentes:
libpfring.so (instalado em /usr/lib/libpfring.so)pf_ring.ko (o driver de kernel deles)ixgbe.ko (a versão deles do driver Ethernet Intel de 10 Gbps)Você não precisa construir a versão deles do libpcap.so.
Quando o Masscan detecta que um adaptador é nomeado algo como zc:enp1s0 em vez de algo como enp1s0, ele automaticamente muda para o modo PF_RING ZC.
Uma discussão mais detalhada pode ser encontrada no PoC||GTFO 0x15.
O projeto contém um teste unitário embutido:
$ make test
bin/masscan --selftest
selftest: success!
Isso testa muitas partes complicadas do código. Você deve fazer isso após a compilação.
Para testar o desempenho, execute algo como o seguinte para um endereço descartável, para evitar sobrecarregar seu roteador local:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --router-mac 66-55-44-33-22-11
O --router-mac falso mantém os pacotes nos segmentos de rede local para que não saiam para a Internet.
Você também pode testar no modo "offline", que é a rapidez com que o programa é executado sem a sobrecarga de transmissão:
$ bin/masscan 0.0.0.0/4 -p80 --rate 100000000 --offline
Este segundo benchmark mostra aproximadamente a rapidez com que o programa seria executado se estivesse usando PF_RING, que tem sobrecarga quase zero.
A propósito, o algoritmo de randomização faz uso intenso de "aritmética de inteiros", uma operação cronicamente lenta nas CPUs. As CPUs modernas dobraram a velocidade com que realizam esse cálculo, tornando o masscan muito mais rápido.
Esta ferramenta foi criada por Robert Graham: email: [email protected] twitter: @ErrataRob
Copyright (c) 2013 Robert David Graham
Este programa é software livre: você pode redistribuí-lo e/ou modificá-lo sob os termos da GNU Affero General Public License conforme publicada pela Free Software Foundation, versão 3 da Licença.
Este programa é distribuído na esperança de que seja útil, mas SEM NENHUMA GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou ADEQUAÇÃO A UM DETERMINADO FIM. Veja a GNU Affero General Public License para mais detalhes.
Você deve ter recebido uma cópia da GNU Affero General Public License junto com este programa. Caso contrário, veja https://www.gnu.org/licenses/.
--output-filename <filename>list: Esta é uma lista simples com um par de host e porta
por linha. Basta usar o parâmetro -oL <filename>. Ou use os parâmetros
--output-format list e --output-filename <filename>. O formato é:
<port state> <protocol> <port number> <IP address> <POSIX timestamp>
open tcp 80 XXX.XXX.XXX.XXX 1390380064