Network Scanning refere-se a um conjunto de procedimentos que investigam um host "ativo", o tipo de host, portas abertas e o tipo de serviços em execução no host. A varredura(Scanning) é uma parte da coleta de informações por meio da qual um ataque pode criar um perfil da organização alvo.
Nesse capítulo, veremos os seguintes tópicos:
- Como checar sistemas ativos
- Ping sweep
- TCP scanner
- Como criar um scanner IP eficiente
- Serviços rodando na máquina alvo
- O conceito de um scanner de portas
- Como criar um scanner de portas eficiente
Antes de prosseguir adiante você deve ter conhecimento básico da camada TCP/IP e o conceito de Protocol Data Unit (PDU) deve estar claro. PDU é uma unidade de dados especificada no protocolo. É o termo genérico para dados em cada camada.
- Para a camada de aplicação, PDU indica dados
- Para a camada de transporte, PDU indica um segmento
- Para a Internet ou a camada de rede, PDU indica um pacote
- Para a camada de enlace ou camada de acesso à rede, PDU indica um frame(quadro)
- Para a camada física, isto é, transmissão física, PDU indica bits
Uma varredura do tipo Ping Scan envolve o envio de uma solicitação(request) ICMP ECHO Request para um host. Se o host estiver ativo, ele retornará uma resposta(reply) ICMP ECHO Reply, como mostrado na imagem a seguir:
Os sistemas operacionais forcenem o comando ping
que é uma mão na roda quando precisamos checar se o host está ativo ou não. Considere uma situação onde você tem que testar uma lista enorme de endereços IP. Nessa situação, se você testar IP por IP, será preciso muito tempo e esforço. Para lidar com esta situação, usamos ping sweep.
Ping Sweep é usado para identificar um host ativo em uma lista de endereços IP enviando um ICMP ECHO request e recebendo ICMP ECHO reply. A partir de uma sub-rede e um endereço de rede, um invasor ou pentester pode calcular o intervalo de rede. Nesta seção, vou demonstrar como obter vantagem com o comando ping
dos sistemas operacionais.
Primeiro, escreverei um pequeno e simples trecho de código, da seguinte forma:
import os
# -c para linux
response = os.popen('ping -c 1 192.230.79.133')
# -n pra windows - response = os.popen('ping -c 1 192.230.79.133')
for line in response.readlines():
print(line)
No código anterior, import os
importa o módulo OS para que possamos executar o comando OS. A próxima linha os.popen('ping -n 1 10.0.0.1')
recebe um comando DOS que é passado como uma string e retorna um objeto file-like que interage com comandos padrões de entrada/saída(I/O) do sistema operacional. O comando ping -c 1 192.230.79.133
é um comando Linux/windus(-n para windus e -c para Linux) que envia um pacote ICMP ECHO. Ao ler a função os.psopen (), você pode interceptar a saída do comando. A saída é armazenada na variável response
. Na próxima linha, a função readlines()
é usada para ler a saida de um objeto file-like.
A saída do programa vai ser algo do tipo:
A saída mostra reply(64 bytes from 192.230.79.133)
, icmp_seq
, time
, e valores do TTL
, idicando que o host está ativo. Considere outra saida do programa para o IP 192.230.199.133
:
A saída anterior mostra que o host não está ativo.
O código anterior é muito importante para o bom funcionamento, e é semelhante ao motor de um carro. Para torná-lo totalmente funcional, precisamos modificar o código para que ele seja independente de sistema operacional e produza uma saída de fácil leitura.
Agora eu quero que meu código trabalhe com um intervalo de IPs:
import os
net = input("Entre com o endereço de rede -> ")
net = net.split('.');
print(net)
a = '.'
net = net[0]+a+net[1]+a+net[2]+a
print(net)
st1 = int(input("Entre com o primeiro numero -> "))
en1 = int(input("Entre com ultimo numero -> "))
O código anterior solicita o endereço de rede com a subnet, mas você pode entrar com uma faixa da subnet posteriormente. A próxima linha net.split('.')
divide o endereço IP em quatro partes. A instrução net = net[0]+a+net[1]+a+net[2]+a
forma o endereço de rede. As duas últimas linhas perguntam o inicio e o fim do intervalo para os endereços IP.
Para deixá-lo independente de plataforma, use o seguinte código:
import os
import platform
systemOp = platform.system()
if(systemOp == "Windows"):
ping1 = "ping -n 1 "
elif(systemOp == "Linux"):
ping1 = "ping -c 1 "
else:
ping1 = "ping -c 1 "
O código anterior determina se o código está sendo executado no Linux ou no windus. A instrução systemOp = platform.system()
informa para o sistema em execução que o comando ping
possui diferença entre windus e Linux. O windus usa ping -n 1
para enviar um pacote do tipo ICMP ECHO request, enquanto que o Linux usa ping -c 1
.
Agora, dê uma olhada no código completo:
import os
import platform
from datetime import datetime
# Obtem o endereco do usuario
net = input("Entre com o endereço da rede λ ")
# divide o endereco em 4 partes(utiliza o . como divisor)
net = net.split('.')
# forma o endereco ignorando a ultima parte que sera o intervalo
net = net[0]+'.'+net[1]+'.'+net[2]+'.'
# obtem os valores necessarios para o intervalo da subnet
start = int(input("Entre com o numero inicial λ "))
end = int(input("Entre com o numero final λ "))
end = end+1
# seta a opcao do ping a ser usada de acordo com o sistema em execucao
systemOp = platform.system()
if(systemOp == "Windows"):
ping1 = "ping -n 1 "
elif(systemOp == "Linux"):
ping1 = "ping -c 1 "
else:
ping1 = "ping -c 1 "
timeInit = datetime.now() # armazena o time de inicio
print("Varredura em progresso...")
for ip in range(start, end):
addr = net+str(ip)
command = ping1+addr
response = os.popen(command)
for line in response.readlines():
if(line.count("ttl")):
print("%s --> Ativo" % addr)
timeEnd = datetime.now()
timeTotal = timeEnd - timeInit
print("A varredura foi executada em -> ", timeTotal)