Ataque por falseo de checksum
Fecha: 26 al 28 de
febrero del 2023
Escenario
Este laboratorio nació cuando me encontré con un
interesante informe sobre ataques DoS por consumo de CPU debido
a los cálculos masivos por checksum falseados a
realizar en el host objetivo.
Si bien el tema está bueno para analizar la
lógica de las cabececera de layer 3, 3 ½ y 4, el ataque evidentemente ya no
es posible, por un lado por los (supuestamente)
sobrados recursos de hardware de los equipos de hoy día, y por otro lado
por lo que plantearemos en estos escenarios.
Dejamos de lado la manipulación de checksum de
layer 2 (CRC/FCS) ya que la trama/paquete moriría en la placa de red.
Básicamente lo que se intenta es generar tráfico
con el checksum erróneo en la (o las) cabecera(s) a la que corresponda
el ataque, y el host objetivo debería colapsar
debido al cálculo excesivo de checksums, que es uno por cada paquete IP,
ICMP o segmento TCP o UDP según corresponda, y que de
todas maneras deberá hacerlo, para descartarlo o no.
Asumimos que este tipo de ataque no es dañino
pero vale la pena para refrescar un poco algunos temas de CCNA 1.
Allá vamos…
1.- Ataque LAN de cabecera
ICMP:
Este tipo de ataque es el único viable ya que al
no haber dispositivos intermedios (al menos de layer 3 o 4) puede que la
Cabecera IP, ICMP o TCP/UDP no se analice en
tránsito.
Usamos un router como objetivo para hcer debug y
capturar algún log de interés.
1.1.- Generamos tráfico:
C:\>frameip -interface 1
-ip_source 192.168.0.100 -ip_destination 192.168.0.1 -icmp_checksum 39763 (en vez de 39762)
FrameIP - Create some IP frame - Version
5.10.3.13
Create on December 21, 2002, Last compilation on
June 02, 2009
Created by Sebastien FONTAINE -
http://www.frameip.com
The frame was sent from 192.168.0.100 to
192.168.0.1 with 57 Bytes
1.2.- Verificamos en el
origen:
Las tramas/paquetes 1 y 2 son de envío y
respuesta de un ping normal, la trama/paquete 3 puede verse con el checksum
falseado y no tiene respuesta
por parte del objetivo (en este caso el router).
1.3.- Verificamos en el
objetivo:
Router#debug ip packet
Router#debug ip icmp
Router#debug ip error detail
IP packet errors debugging is on (detailed)
Router#
Feb 26 15:30:44.679: IP: tableid=0,
s=192.168.0.100 (FastEthernet0/0), d=192.168.0.1 (FastEthernet0/0), routed via
RIB
Feb 26 15:30:44.679: IP: s=192.168.0.100
(FastEthernet0/0), d=192.168.0.1 (FastEthernet0/0), len 44, rcvd 3
Feb 26 15:30:44.679: IP: s=192.168.0.100
(FastEthernet0/0), d=192.168.0.1, len 44, dispose
icmp.checksumerr
Feb 26 15:30:44.679: ICMP type=8, code=0
Router#
1.4.- Caso de un dispositivo
intermedio de layer 2:
1.5.- Caso de un dispositivo
intermedio de layer 2 con inspección de QoS (calidad de servicio):
En este caso el único posible ataque es mediante
ICMP ya que las cabeceras IP, TCP o UDP suelen analizarse
para la toma de decisiones de QoS.
2.- Ataque remoto con
checksum IP manipulado:
Este ataque no es posible ya que el router
descartará el paquete luego de analizarle la cabecera IP (incluído
el checksum) para leer la IP destino (para luego
enrutar el paquete) y el TTL, que deberá decrementar, y esto
hará volver a calcular un nuevo checksum de la
cabecera IP antes de transmitirlo.
Por algún motivo, de haber pasado el router
(supongamos que es el gateway del atacante y de alguna manera
omite el checksum) no hubiese pasado el control
del firewall statefull como veremos más adelante.
2.1.- Detalle de la cabecera
IP:
3.- Ataque remoto con
checksum TCP manipulado:
Este ataque no es posible ya que firewall
statefull (debría) descartar el paquete luego de analizarle la cabecera
TCP (incluído el checksum) para leer los puertos
TCP origen y destino (para generar una sesión TCP statefull)
y calcular un nuevo checksum de la cabecera TCP
en caso de cambiar algún parámetro antes de transmitirlo
(por ejemplo el puerto destino en caso de un port
forwarding o generar un número de secuencia TCP random
para enmascarar el original y evitar un posible
spoofing).
3.1.- Detalle de la cabecera
TCP:
Inicialmente preparamos el firewall para natear
(en realidad “patear” por Port Address Translation) el destination port 8080 al
80,
esto (supuestamente) debería forzar al firewall a
analizar la cabecera TCP para leer el port destino (y no estaría de más leer el
checksum) y trasladarlo al port donde escucha el
host final.
Firewall# sh runn | inc static
static (inside,outside) tcp interface 8080
192.168.0.10 www netmask 255.255.255.255
Firewall# |
190.0.0.1
3.2.- Generamos tráfico:
C:\>frameip -interface 1
-mac_destination 00-17-95-c0-ac-a2 -ip_source 200.0.0.100 -ip_destination
190.0.0.1 //
// -ip_type 6
-tcp_port_destination 8080 -tcp_checksum 1234
FrameIP - Create some IP frame - Version
5.10.3.13
Create on December 21, 2002, Last compilation on
June 02, 2009
Created by Sebastien FONTAINE -
http://www.frameip.com
The frame was sent from 200.0.0.100 to 190.0.0.1
with 60 Bytes
3.3.- Análisis del envío:
3.4.- ¿ Qué es UDP checksum
offload ? https://wiki.wireshark.org/CaptureSetup/Offloading
3.5.- Logs en el firewall:
%ASA-6-302013: Built inbound TCP connection 95
for outside:200.0.0.100/21347 (200.0.0.100/21347) to inside:192.168.0.10/8080
(190.0.0.1/80)
%ASA-6-302014: Teardown TCP connection 95 for
outside:200.0.0.100/21347 to inside:192.168.0.10/8080 duration 0:00:30 bytes 15
SYN Timeout
El SYN timeout se debe a que el host final
descarta el SYN y el firewall se queda esperando respuesta, que vence por
timeout y no se avanza en el saludo de 3 vias
(handshake) TCP.
3.6.- Ajustes en el
firewall:
Como podemos ver, el paquete/segmento TCP pasó
sin problemas, esto en un firewall (supuestamente) es inadmisible,
Por lo que procedemos a “tunear” la inspección
del mismo.
Firewall# conf t
Firewall(config)# tcp-map Inspect-TCP
Firewall(config-tcp-map)# ?
TCP-map configuration commands:
check-retransmission Check
retransmit data, disabled by default
checksum-verification Verify
TCP checksum, disabled by default
default
Set a command to its defaults
exceed-mss
Packet that exceed the Maximum Segment Size set by
peer, default is to allow packet
invalid-ack
Packets with invalid ACK, default is to drop packet
no Negate a
command or set its defaults
reserved-bits
Reserved bits in TCP header are set, default is to
allow packet
seq-past-window
Packets that have past-window seq numbers, default is
to
drop packet
syn-data
TCP SYN packets that contain data, default is to
allow packet
synack-data
TCP SYN-ACK packets that contain data, default is to
drop
packet
tcp-options
Options in TCP header
ttl-evasion-protection
Protection against time to live (TTL) attacks,
enabled by default
urgent-flag
Urgent flag and urgent offset set, default is to
clear
flag and offset
window-variation
Unexpected window size variation, default is to allow
connection
Firewall(config-tcp-map)#
Firewall(config-tcp-map)# checksum-verification
Firewall(config-tcp-map)# exit
Firewall(config)#
Firewall(config)# policy-map global_policy
Firewall(config-pmap)# class TCP
Firewall(config-pmap-c)# set connection advanced-options Inspect-TCP
Firewall(config-pmap-c)#end
Firewall#
3.7.- Volvemos a generar
tráfico:
C:\>frameip -interface 1
-mac_destination 00-17-95-c0-ac-a2 -ip_source 200.0.0.100 -ip_destination
190.0.0.1 //
// -ip_type 6
-tcp_port_destination 8080 -tcp_checksum 1234
FrameIP - Create some IP frame - Version
5.10.3.13
Create on December 21, 2002, Last compilation on
June 02, 2009
Created by Sebastien FONTAINE -
http://www.frameip.com
The frame was sent from 200.0.0.100 to 190.0.0.1
with 69 Bytes
3.8.- Logs en el firewall:
%PIX-6-302013: Built inbound TCP connection 128
for outside:200.0.0.100/39474 (200.0.0.100/39474) to inside:192.168.0.10/80
(190.0.0.1/8080)
%PIX-6-302014: Teardown TCP connection 128 for
outside:200.0.0.100/39474 to inside:192.168.0.10/80 duration 0:00:00 bytes 0 TCP invalid SYN
3.9.- Detalle en la página
de Cisco:
Explanation A TCP connection between two hosts
was deleted. The following list describes the message values:
Se asume
que es un SYN con un checksum inválido, no da más detalles.
4.- Ataque remoto con
checksum UDP manipulado:
El mismo criterio se aplicaría para el tráfico
UDP, este ataque no es posible ya que firewall statefull descartará
el paquete luego de analizarle la cabecera UDP
(incluído el checksum, que en UDP es opcional) para leer los
puertos UDP origen (que en UDP es opcional
pudiendo ser 0) y destino (para generar una sesión UDP pseudo
statefull) y calcular un nuevo checksum
(opcional) si se cambia el puerto destino en caso de un port forwarding.
4.1.- Detalle de la cabecera
UDP:
4.2.- Generamos tráfico:
Inicialmente preparamos el firewall para natear
(en realidad “patear” por Port Address Translation) el port 1000 al 2000,
esto (supuestamente) debería forzar al firewall a
analizar la cabecera UDP para leer el port destino (y no estaría de más
leer el checksum) y trasladarlo al port donde
escucha el host final.
Estos ports son para simular tráfico dummy de
alguna aplicación custom, pero podría ser NTP, UDP, etc…
Firewall# sh runn | inc static
static (inside,outside) udp interface 1000 192.168.0.10 2000 netmask 255.255.255.255
Firewall# |
190.0.0.1
C:\> frameip -interface 1
-mac_destination 00-17-95-c0-ac-a2 -ip_source 200.0.0.100 -ip_destination
190.0.0.1 //
// -ip_type 17
-udp_port_destination 1000 -udp_checksum 123
FrameIP - Create some IP frame - Version
5.10.3.13
Create on December 21, 2002, Last compilation on
June 02, 2009
Created by Sebastien FONTAINE -
http://www.frameip.com
The frame was sent from 200.0.0.100 to 190.0.0.1
with 60 Bytes
4.3.- Análisis del envío:
4.4.- ¿ Qué es UDP checksum
offload ? https://wiki.wireshark.org/CaptureSetup/Offloading
4.5.- Logs en el firewall:
Podemos ver que el tráfico pasa sin problemas por
el firewall, no hay respuesta porque no hay aplicación escuchando.
%ASA-6-302015: Built inbound UDP connection 75
for outside:200.0.0.100/28728 (200.0.0.100/28728) to inside:192.168.0.10/2000
(190.0.0.1/1000)
%ASA-6-302015: Built inbound UDP connection 76
for outside:200.0.0.100/5665 (200.0.0.100/5665) to inside:192.168.0.10/2000
(190.0.0.1/1000)
%ASA-6-302015: Built inbound UDP connection 77
for outside:200.0.0.100/41858 (200.0.0.100/41858) to inside:192.168.0.10/2000
(190.0.0.1/1000)
4.6.- Detalle del uso (o no)
del checksum UDP:
Nota: Al final se
muestran los libros utilizados, esto es de la versión en español de TCP/IP de
Douglas E. Comer
5.- Ataque remoto con
checksum ICMP manipulado:
Este ataque es el único posible ya que la
cabecera ICMP no se analizará en tránsito, sino que sólo lo hará el receptor
final del paquete y en consecuencia lo
descartará.
El firewall statefull no analizará la cabecera
ICMP sino que sólo se limita a analizar la cabecera IP propiamente dicha,
esto es necesario para realizar el NAT de la IP
de destino (DST NAT), y por este motivo tiene que volver a calcular un
nuevo checksum de la cabecera IP.
5.1.- Detalle de la cabecera
ICMP:
Se pueden ver ambas cabeceras (IP e ICMP) para
diferenciar una de otra ya que siempre se asume a ICMP como layer 3
y existe la confusión con IP que también es layer
3. Personalmente considero a ICMP como layer 3 ½.
5.2.- Generamos tráfico:
C:\>frameip -interface 1
-ip_source 200.0.0.100 -ip_destination 190.0.0.1 -icmp_checksum 39763 (en vez de 39762)
FrameIP - Create some IP frame - Version
5.10.3.13
Create on December 21, 2002, Last compilation on
June 02, 2009
Created by Sebastien FONTAINE -
http://www.frameip.com
The frame was sent from 200.0.0.100 to 190.0.0.1
with 57 Bytes
5.3.- Análisis del envío:
Aparte del error de checksum ICMP, podemos ver
que el paquete se transmite con IP públicas de origen y destino, y un TTL de
128.
5.4.- Análisis de la
recepción:
Aparte del error de checksum ICMP, podemos ver
que la IP destino ya está traducida (nateada) y que el paquete recibido tiene
un TTL
de 127 (salió con 128, el router le resta 1 y el
firewall al natearlo 1 a 1 no le resta, sino que sólo se limita a traducir
(natear) la IP destino.
La solicitud de eco se descarta y no tiene
respuesta, no genera gasto de CPU como cualquier otro tráfico salvo que es
tráfico descartado,
que podría ser cualquier otro motivo y generaría
(posiblemente) el mismo impacto.
5.5.- Logs en el firewall:
%ASA-6-302020: Built inbound ICMP connection for
faddr 190.0.0.6/0 gaddr 190.0.0.1/0 laddr 192.168.0.10/0 (ping normal)
%ASA-6-302021: Teardown ICMP connection for faddr
190.0.0.6/0 gaddr 190.0.0.1/0 laddr 192.168.0.10/0 (respuesta ping normal)
%ASA-6-302020: Built inbound ICMP connection for
faddr 190.0.0.6/0 gaddr 190.0.0.1/0 laddr 192.168.0.10/0 (ping falseado, sin retorno)
5.6.- Debug del ICMP:
Firewall#
Firewall# debug icmp trace
ICMP echo request from outside:190.0.0.6 to
inside:190.0.0.1 ID=0 seq=0 len=16 (ping entrante)
ICMP echo request untranslating outside:190.0.0.1
to inside:192.168.0.10 (ping
reenviado y sin retorno)
Firewall#
6.- Resumen:
Este tipo de ataque no tiene impacto de CPU con
el hardware actual, pero si se considera que a todo paquete
recibido, sea IP, ICMP, TCP o UDP se le deberá
calcular el checksum de todas maneras, sea para descartarse
o para procesarse por las capas superiores, no es
un gasto adicional diferente a la recepción de otro tipo de
tráfico dummy o basura, tal como broadcasts o
multicasts de aplicaciones mal configuradas.
También consideramos que hay algunos tipos de
“filtros” en los dispositivos intermedios que pueden hacer que
este ataque no se lleve a cabo contra un objetivo
en particular, tal como se vió en los puntos anteriores.
Se debe considerar que hay ataques mas peligrosos
y efectivos en caso de que los paquetes tuviesen correcto
el checksum y tengan como objetivo las
aplicaciones y sus (posibles) bugs.
7.- Configuración del
firewall:
Firewall# sh runn (sólo lo más relevante)
!
interface Ethernet0
nameif
inside
security-level 100
ip address
192.168.0.1 255.255.255.0
!
interface Ethernet1
nameif
outside
security-level 0
ip address
190.0.0.1 255.255.255.248
!
!
tcp-map Inspect-TCP (asociado a class TCP del policy-map global_policy)
checksum-verification
!
access-list outside extended permit ip any host
192.168.0.10 (permite el
tráfico entrante)
!
static (inside,outside) interface 192.168.0.10
netmask 255.255.255.255 (el
NAT pública-privada pruebas ICMP)
!
o variantes layer 4 (pruebas
port forwarding TCP y UDP)
!
static (inside,outside) tcp interface 8080 192.168.0.10
80 netmask 255.255.255.255
static (inside,outside) udp interface 1000 192.168.0.10
2000 netmask 255.255.255.255
!
access-group outside in interface outside
route outside 0.0.0.0 0.0.0.0 190.0.0.2 1
!
class-map inspection_default
match
default-inspection-traffic (para
protocolos predefinidos)
!
!
policy-map global_policy
class
inspection_default (para
protocolos preestablecidos)
---resumido---
inspect
icmp (analizan el tráfico
ICMP, y más que nada habilita las respuestas del traceroute)
inspect
icmp error
---resumido---
class TCP (se crean para para otros protocolos
“custom”)
set
connection advanced-options Inspect-TCP (el tcp-map antes configurado)
!
service-policy global_policy global (asociado a todas las interfaces)
: end
Firewall#
8.- Fuentes:
https://www.frameip.com/saturation-du-processeur
(la página original es en
francés, esta fue mi inspiración)
https://en.wikipedia.org/wiki/Internet_checksum
https://es.wikipedia.org/wiki/Protocolo_de_control_de_mensajes_de_Internet
https://es.wikipedia.org/wiki/Complemento_a_uno
Para analizar los checksums y me llevó a sacar a
la luz algunos de mis libros favoritos, todos de Douglas Comer,
Los libros de TCP/IP son los mismos, en español y
en inglés para cuando las cosas se ponen difíciles.
El libro Network Systems Design escarba en
lo más profundo del networking (algo como el Infierno de Dante).
(2024) My mind has
a bad checkum, I’m sure
Rosario, Argentina