Red de conocimiento informático - Material del sitio web - Cómo escribir un escáner de puertos usando Scapy

Cómo escribir un escáner de puertos usando Scapy

Los tipos de escaneo de puertos comunes son:

1. Escaneo de conexión TCP

2. Escaneo TCP SYN (también llamado escaneo semiabierto o escaneo sigiloso)

p>

3. Escaneo del árbol de Navidad de TCP

4. Escaneo de TCP FIN

5. Escaneo de TCP nulo

6. >

7. Escaneo de ventana TCP

8. Escaneo UDP

A continuación se explicará primero el principio de cada escaneo y luego se proporcionará el código de implementación específico.

Escaneo de conexión TCP

Para establecer una conexión TCP entre el cliente y el servidor, se requiere un protocolo de enlace de tres vías. Si se realiza un protocolo de enlace de tres vías exitoso, el puerto es. abierto.

Cuando el cliente quiera conectarse al puerto 80 del servidor, primero enviará un paquete TCP con un identificador SYN y un número de puerto al servidor (puerto 80 en este ejemplo). Si el puerto está abierto, el servidor aceptará la conexión y devolverá un paquete con los identificadores SYN y ACK al cliente. Luego, el cliente devuelve un paquete con identificadores ACK y RST, y el cliente establece una conexión con el servidor. Si se completa un protocolo de enlace de tres vías, el puerto correspondiente en el servidor debe estar abierto.

Cuando el cliente envía un paquete TCP con el identificador SYN y el número de puerto al servidor, si el servidor devuelve un paquete con el identificador RST, significa que el puerto está cerrado.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port, dport=dst_port, flags="S"), timeout=10)

if(str(type(tcp_connect_scan_resp))=="lt;type 'NoneType'gt;"):

print "Cerrado"

elif(tcp_connect_scan_resp.haslayer(TCP )):

if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):

send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport =dst_port, flags="AR"), timeout=10)

imprimir "Abrir"

elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):

imprimir "Cerrado"

TCP SYN Scan

Esta tecnología es muy similar al escaneo de conexiones TCP.

El cliente también envía un paquete con un identificador SYN y un número de puerto al servidor. Si se desarrolla el puerto de destino, se devolverá un paquete TCP con un identificador SYN y ACK. Sin embargo, en este momento el cliente no devolverá un RST ACK sino que devolverá un paquete con solo el identificador RST. Esta técnica se utiliza principalmente para evitar la detección del firewall.

Si el puerto de destino está cerrado, el servidor devolverá un paquete RST como antes.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port, dport=dst_port, flags="S"), timeout=10)

if(str(type(stealth_scan_resp))=="lt;type 'NoneType'gt;"):

print "Filtrado"

elif(stealth_scan_resp.haslayer(TCP )):

if(stealth_scan_resp.getlayer(TCP).flags == 0x12):

send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport =dst_port, flags="R"), timeout=10)

imprimir "Abrir"

elif (stealth_scan_resp.getlayer(TCP).flags == 0x14):

imprimir "Cerrado"

elif(stealth_scan_resp.haslayer(ICMP)):

if(int(stealth_scan_resp.getlayer(ICMP).type)==3 and int (stealth_scan_resp.getlayer(ICMP).code) in ):

imprimir "Filtrado"

Escaneo TCP del árbol de Navidad

En el escaneo del árbol de Navidad, el cliente envía un paquete de datos con identificación PSH, FIN, URG y número de puerto al servidor. Si el puerto de destino está abierto, no habrá respuesta del servidor.

Si el servidor devuelve un paquete TCP con el indicador RST, el puerto está cerrado.

Pero si el servidor devuelve un paquete ICMP que contiene un error de destino ICMP inalcanzable tipo 3 y un código de estado ICMP de 1, 2, 3, 9, 10 o 13, el puerto de destino se filtra No se puede determinar. si esta abierto.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port, flags="FPU"), tiempo de espera=10)

if ( str(type(xmas_scan_resp))=="lt;type 'NoneType'gt;"):

print "Abierto|Filtrado"

elif(xmas_scan_resp.haslayer(TCP)) :

if(xmas_scan_resp.getlayer(TCP).flags == 0x14):

imprimir "Cerrado"

elif(xmas_scan_resp.haslayer(ICMP)) :

if(int(xmas_scan_resp.getlayer(ICMP).type)==3 and int(xmas_scan_resp.getlayer(ICMP).code) in ):

print "Filtrado"

Escaneo TCP FIN

El escaneo FIN envía un paquete TCP con un identificador FIN y un número de puerto al servidor. Si no hay respuesta del servidor, el puerto está abierto.

Si el servidor devuelve un paquete RST, el puerto de destino está cerrado.

Si el servidor devuelve un paquete ICMP que contiene un error de destino ICMP inalcanzable tipo 3 y un código ICMP de 1, 2, 3, 9, 10 o 13, el puerto de destino se filtra y no se puede determinar. estado.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

fin_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port, flags="F"), tiempo de espera=10)

if ( str(type(fin_scan_resp))=="lt;type 'NoneType'gt;"):

print "Abierto|Filtrado"

elif(fin_scan_resp.haslayer(TCP)) :

if(fin_scan_resp.getlayer(TCP).flags == 0x14):

imprimir "Cerrado"

elif(fin_scan_resp.haslayer(ICMP)) :

if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in ):

print "Filtrado"

TCP Null Scan (Null)

En Null Scan, el paquete TCP enviado por el cliente solo contiene el número de puerto sin ninguna otra información de identificación. Si el puerto de destino está abierto, no se devolverá ningún mensaje.

Si el servidor devuelve un paquete RST, el puerto de destino está cerrado.

Si se devuelve un paquete con error ICMP tipo 3 y código 1, 2, 3, 9, 10 o 13, el puerto es filtrado por el servidor.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

null_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port, flags=""), timeout=10)

if (str (type(null_scan_resp))=="lt;type 'NoneType'gt;"):

print "Abierto|Filtrado"

elif(null_scan_resp.haslayer(TCP)):

if(null_scan_resp.getlayer(TCP).flags == 0x14):

print "Cerrado"

elif(null_scan_resp.haslayer(ICMP)):

if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in ):

print "Filtrado"

Escaneo TCP ACK

El escaneo ACK no se utiliza para descubrir si el puerto está abierto o cerrado, sino para descubrir si hay un firewall con estado en el servidor. Su resultado sólo puede indicar si el puerto está filtrado. Nuevamente, el escaneo ACK no puede descubrir si un puerto está activo o inactivo.

El cliente enviará un paquete de datos con un identificador ACK y un número de puerto al servidor. Si el servidor devuelve un paquete TCP con el indicador RST, el puerto no se filtra y no hay un firewall con estado.

Si el servidor de destino no responde o devuelve un paquete de error ICMP tipo 3 con código 1, 2, 3, 9, 10 o 13, el puerto se filtra y existe un firewall con estado.

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime").setLevel(logging.ERROR) p>

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

ack_flag_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port, flags="A"), tiempo de espera=10)

if (str(type(ack_flag_scan_resp)) == "lt;type 'NoneType'gt;"):

print "Firewall con estado presente (filtrado)"

elif(ack_flag_scan_resp.haslayer(TCP)):

if(ack_flag_scan_resp.getlayer(TCP).flags == 0x4):

print "Sin firewalln(Sin filtrar)"

elif(ack_flag_scan_resp.haslayer(ICMP)) :

if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in ):

print "Firewall con estado presentn(Filtered)"

Escaneo de ventana TCP

El proceso de escaneo de ventana TCP es similar al escaneo ACK. El cliente también envía un paquete TCP con un identificador ACK y un número de puerto al servidor, pero este análisis se puede utilizar para descubrir el estado del puerto del servidor de destino. Devolver RST en un escaneo ACK indica que no está filtrado, pero en un escaneo de ventana, cuando se recibe el paquete RST devuelto, verifica el valor del tamaño de la ventana. Si el valor del tamaño de la ventana no es cero, el puerto de destino está abierto.

Si el tamaño de la ventana en el paquete RST devuelto es 0, el puerto de destino está cerrado.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

window_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port, flags="A"), tiempo de espera=10)

if ( str(type(window_scan_resp))=="lt;type 'NoneType'gt;"):

print "Sin respuesta"

elif(window_scan_resp.haslayer(TCP)):

if(window_scan_resp.getlayer(TCP).window == 0):

imprimir "Cerrado"

elif(window_scan_resp.getlayer(TCP).window gt; 0):

print "Abrir"

Escaneo UDP

TCP es un protocolo orientado a conexión, mientras que UDP es un protocolo sin conexión.

Los protocolos orientados a la conexión primero establecen un canal de comunicación entre el cliente y el servidor antes de comenzar a transmitir datos. Si no se establece ningún canal de comunicación entre el cliente y el servidor, no se generarán datos de comunicación.

El protocolo sin conexión no establece un canal de comunicación entre el cliente y el servidor de antemano. Siempre que haya un canal disponible del cliente al servidor, asumirá que el objetivo es accesible y luego. enviar datos a la otra parte.

El cliente envía un paquete UDP con un número de puerto al servidor. Si el servidor responde con un paquete UDP, el puerto de destino está abierto.

Si el servidor devuelve un error de destino ICMP inalcanzable con código 3, significa que el puerto de destino está cerrado.

Si el servidor devuelve un paquete de error ICMP tipo 3 con código 1, 2, 3, 9, 10 o 13, el servidor filtra el puerto de destino.

Pero si el servidor no recibe ninguna solicitud UDP del cliente correspondiente, se puede concluir que el puerto de destino puede estar abierto o filtrado, y no se puede determinar el estado final del puerto.

Código:

#! /usr/bin/python

importar registro

logging.getLogger("scapy.runtime") .setLevel(logging.ERROR)

de scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=53

dst_timeout=10

def udp_scan(dst_ip, dst_port, dst_timeout):

udp_scan_resp = sr1(IP(dst=dst_ip) /UDP(dport=dst_port), timeout=dst_timeout)

if (str(type(udp_scan_resp))=="lt;type 'NoneType'gt;"):

retransmisiones = ):

return "Filtrado"

print udp_scan(dst_ip, dst_port, dst_timeout)

A continuación se explican algunas funciones y variables del código anterior:

RandShort(): Generar números aleatorios

type(): Obtener tipo de datos

sport: Número de puerto de origen

dport: Puerto de destino No.

timeout: espera el tiempo correspondiente

haslayer(): encuentra la capa especificada: TCP o UDP o ICMP

getlayer(): obtiene el capa especificada: TCP o UDP o ICMP

El concepto de escaneo anterior se puede utilizar para "escaneo multipuerto", el código fuente se puede encontrar aquí: /interference-security/Multiport

Scapy es una herramienta muy fácil de usar, puede usarla para crear sus propios paquetes de datos de manera muy simple y también puede manejar fácilmente el envío y la respuesta de paquetes de datos.

/p>