Alterando los números de secuencia TCP

Fecha: 26 y 27 de mayo del 2020 (durante la cuarentena)

 

Escenario

 

Este laboratorio viene inspirado de un problema de tráfico entre dos servers separados por un firewall Cisco ASA, y en la

documentación del sistema operativo de uno de los servers se menciona un issue de TCP y NFS4 que puede deberse a la

alteración aleatoria de los números de secuencia TCP por parte del firewall.

 

                              

Esto me llevó a dos cosas:

 

1.- Meditar si hay algun aviso por parte del firewall al origen sobre el número de secuencia a utilizar, porque de cambiarlo

“on the fly” el origen debe saberlo para numerar los siguientes segmentos. Pero esto deberia haberlo visto al menos una

vez en mi vida, o en algún libro. Quedó descartado.

 

2.- Que el firewall lleve una tabla de cada (y todas) sesión TCP con los valores inside y outside. Casi probable, falta probarlo.

 

Para verificar esto armé una maqueta con lo que tenía en casa: un PIX 501 (épico, con una marca de bala) y verificar si el

número de secuencia inside es diferente al outside. Y a los fierros me remití, no con NFS4 pero si con RDP.

 

Detalle de una sesión TCP ideal:

 

Decimos “ideal” por los números se secuencia y ACK fáciles de leer e interpretar, muy lejos de la realidad.

 

Fuente: madpackets.com

 

Explicación de la randomización del número de secuencia incial:

 

TCP sequence randomization—Each TCP connection has two initial sequence numbers (ISN): one generated by the client

and one generated by the server. By default, the ASA randomizes the ISN of the TCP SYN passing in both the inbound and

outbound directions. Randomization prevents an attacker from predicting the next ISN for a new connection and potentially

hijacking the new session. You can disable randomization per traffic class if desired

 

Fuente: cisco.com

 

Aunque dice que genera números aleatorios en inbound and outbound directions sólo pudimos demostrar random en una sola

dirección, tal vez se refiera a una sesión entrante y no a la de tráfico de retorno (ver punto 3.-)(el traffic-class que menciona al

final es el punto 4.1.-).

 

1.- Pruebas realizadas:

 

Se generó una conexión de escritorio remoto (RDP) entre la PC 192.168.0.10 (cliente) y 192.168.1.10 (servidor RDP) y con el

firewall en el medio, realizando NAT entre 192.168.0.10 y 192.168.1.20 y “randomizando” los números de secuencia TCP.

 

 

                        

 

 

2.- Capturas de tráfico:

 

2.1.- Captura inside (pre firewall):

 

 

2.2- Captura outside (post firewall):

 

En esta captura vemos que el valor es el mismo, lo que da a sospecha de que Wiresahrk está mostrando números

“mas para humanos” que los reales.

 

 

Frame 1: 66 bytes on wire (528 bits), 66 bytes captured (528 bits) on interface 0

Ethernet II, Src: 00:16:9d:da:82:13, Dst: 00:1b:38:7e:f1:71

Internet Protocol Version 4, Src: 192.168.1.20, Dst: 192.168.1.10

Transmission Control Protocol, Src Port: 58382, Dst Port: 3389, Seq: 0, Len: 0

    Source Port: 58382

    Destination Port: 3389

    [Stream index: 0]

    [TCP Segment Len: 0]

    Sequence number: 0    (relative sequence number) (esto es lo que hay que analizar)

    [Next sequence number: 0    (relative sequence number)]

    Acknowledgment number: 0

    1000 .... = Header Length: 32 bytes (8)

    Flags: 0x002 (SYN)

    Window size value: 64240

    [Calculated window size: 64240]

    Checksum: 0xbe37 [unverified]

    [Checksum Status: Unverified]

    Urgent pointer: 0

    Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale

   

2.3.- Desactivamos la función Relative sequence numbers:

 

By default Wireshark and TShark will keep track of all TCP sessions and convert all Sequence Numbers (SEQ numbers) and

Acknowledge Numbers (ACK Numbers) into relative numbers. This means that instead of displaying the real/absolute SEQ

and ACK numbers in the display, Wireshark will display a SEQ and ACK number relative to the first seen segment for that

conversation.

 

This means that all SEQ and ACK numbers always start at 0 for the first packet seen in each conversation.

 

This makes the numbers much smaller and easier to read and compare than the real numbers which normally are initialized

to randomly selected numbers in the range 0 - (2^32)-1 during the SYN phase.

 

Fuente: wireshark.org

 

 

2.4.- Captura inside (pre firewall):

 

En esta captura podemos ver la dirección IP origen y el número de secuencia original.

 

 

2.5.- Captura outside (post firewall):

 

En esta captura podemos ver la dirección IP origen “nateada” en 192.168.1.20 y el número de secuencia alterado.

 

 

2.6.- Comparación de cambios de #seq, de direcciones IP (NAT) y líneas de tiempo:

 

 

3.- Verificación en el firewall:

 

Dentro de lo rudimentario del PIX 501 con versión 6.3, pude capturar la sesión TCP mediante debug. Con versiones mas nuevas o

con un ASA podemos realizar directamente una captura y analizarla con Wireshark.

 

3.1.- Activamos debug para ambas interfaces:

 

Firewall# debug packet inside

Firewall# debug packet outside

Firewall#

 

3.2.- Paquete #1 (SYN inside-outside):

 

--------- PACKET ---------

 

-- IP --

192.168.0.10    ==>     192.168.1.10  (paquete #1 en inside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x28

        id = 0x6e12     flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0xa4d

                                                                                           (valor en hexadecinal, en decimal es 3389)    

        -- TCP –                                                                      |   

                source port = 0xe40e    dest port = 0xd3dsyn (flag SYN)

 

                seq = 0x8e0cf963 (valor en hexadecinal, en decimal es 2383214947)

                ack = 0x0                 (primer paquete, no existe acuse de recibo)

                hlen = 0x5              window = 0xfaf0

                checksum = 0x828b       urg = 0x0

        tcp options:

                        0x1     0x3     0x3     0x8    0x1     0x1     0x4    0x2

                        0x1     0x1     0x4     0x2

 

--------- END OF PACKET ---------

 

--------- PACKET ---------

 

-- IP --

192.168.1.20    ==>     192.168.1.10  (paquete #1 en outside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x34

        id = 0x6e12     flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0x943

 

        -- TCP --

                source port = 0xe40e    dest port = 0xd3dsyn

 

                seq = 0xb6828afa (valor alterado por el firewall)

                ack = 0x0                 (primer paquete, no existe acuse de recibo)

                hlen = 0x8              window = 0xfaf0

                checksum = 0xbe37       urg = 0x0

tcp options:

                        0x2     0x4     0x5     0x64    0x1     0x3     0x3    0x8

                        0x1     0x1     0x4     0x2

 

--------- END OF PACKET ---------

 

3.3.- Paquete #2 (SYN ACK outside-inside):

 

--------- PACKET ---------

 

-- IP --

192.168.1.10    ==>     192.168.1.20 (paquete #2 en outside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x30

        id = 0xf6       flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0x7663

 

        -- TCP --

                source port = 0xd3d     dest port = 0xe40esyn ack

 

                seq = 0xc9f011bb (valor original)

                ack = 0xb6828afb (corresponde a b6828afa +1)

                hlen = 0x7              window = 0x2000

                checksum = 0xd4d7       urg = 0x0

tcp options:

                        0x1     0x3     0x3     0x8     0x1     0x1     0x4    0x2

 

--------- END OF PACKET ---------

 

--------- PACKET ---------

 

-- IP --

192.168.1.10    ==>     192.168.0.10 (paquete #2 en inside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x30

        id = 0xf6       flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0x776d

 

        -- TCP --

                source port = 0xd3d     dest port = 0xe40esyn ack

 

                seq = 0xc9f011bb (valor original, no se modifica ya que fué creado en outside)

                ack = 0x8e0cf964  (8e0cf963 + 1, será el próximo número de secuencia esperado por 192.168.1.10)

                hlen = 0x7              window = 0x2000

                checksum = 0x8fee       urg = 0x0

tcp options:

                        0x1     0x3     0x3     0x8     0x1     0x1     0x4    0x2

 

--------- END OF PACKET ---------

 

3.4.- Paquete #3 (ACK inside-outside):

 

--------- PACKET ---------

 

-- IP --

192.168.0.10    ==>     192.168.1.10 (paquete #3 en inside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x28

        id = 0x6e13     flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0xa58

 

        -- TCP --

                source port = 0xe40e    dest port = 0xd3dack

 

                seq = 0x8e0cf964 (corresponde a 8e0cf963 + 1, que es el ACK enviado por 192.168.1.10)

                ack = 0xc9f011bc  (corresponde a c9f011bb +1)

                hlen = 0x5              window = 0x200

                checksum = 0xd705       urg = 0x0

        -- DATA --

                00000020:                         00 00 00 00 00 00 30     |          ......0

 

--------- END OF PACKET ---------

 

--------- PACKET ---------

 

-- IP --

192.168.1.20    ==>     192.168.1.10 (paquete #3 en outside)

 

        ver = 0x4       hlen = 0x5      tos = 0x0       tlen = 0x28

        id = 0x6e13     flags = 0x40    frag off=0x0

        ttl = 0x80      proto=0x6       chksum = 0x94e

 

        -- TCP --

                source port = 0xe40e    dest port = 0xd3dack

 

                seq = 0xb6828afb (corresponde a b6828afa +1 y es el número esperado por 192.168.1.10)

                ack = 0xc9f011bc  (valor original, no se modifica ya que fué creado en outside)

                hlen = 0x5              window = 0x200

                checksum = 0x1bef       urg = 0x0

 

--------- END OF PACKET ---------

 

3.5.- Verificación en el firewall de la sesión TCP:

 

Firewall# sh conn

1 in use, 1 most used

TCP out 192.168.1.10:3389 in 192.168.0.10:58382 idle 0:00:21 Bytes 38 flags UIO

Firewall#

                                                                   

 

4.- Desactivando la función de alterar los números de secuencia TCP:

 

4.1.- En PIX y ASA con línea de comando mas actual y parecida a IOS la sintaxis es:

 

class-map TCP

 match port tcp range 1 65535

!

policy-map global-policy

 class TCP

  set connection random-sequence-number disable

!

service-policy global_policy global

 

4.2.- En este PIX en particular que tiene un set de comandos viejo (algo áspero, casi mi favorito).

 

nat [(local_interface)] id local_ip [mask [dns] [outside |[norandomseq] [max_conns [emb_limit]]]]

 

Firewall# conf t

Firewall(config)# no static (inside,outside) 192.168.1.20 192.168.0.10 netmask 255.255.255.255

Firewall(config)# static (inside,outside) 192.168.1.20 192.168.0.10 netmask 255.255.255.255 norandomseq

Firewall(config)# exit

Firewall#

 

4.3.- Verificación:

 

Firewall# sh conn

1 in use, 1 most used

TCP out 192.168.1.10:3389 in 192.168.0.10:5036 idle 0:00:10 Bytes 38 flags UIO

Firewall#

 

4.4.- Verificación de la captura de tráfico:

 

 

5.- Configuración del equipo:

 

Firewall# sh runn (sólo lo mas importante)

: Saved

:

PIX Version 6.3(5)

interface ethernet0 auto

interface ethernet1 100full

nameif ethernet0 outside security0

nameif ethernet1 inside security100

hostname Firewall

mtu outside 1300

mtu inside 1500

ip address outside 192.168.1.1 255.255.255.0

ip address inside 192.168.0.1 255.255.255.0

static (inside,outside) 192.168.1.20 192.168.0.10 netmask 255.255.255.255 0 0

timeout xlate 3:00:00

timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 rpc 0:10:00 h225 1:00:00

dhcpd address 192.168.0.10-192.168.0.11 inside

dhcpd lease 3600

dhcpd ping_timeout 750

dhcpd enable inside

Cryptochecksum:d2a7592c51622808c2959c2c4acfaf30

: end

Firewall#

 

6.- El libro con el que me inicié en el 2002 y el PIX 501 con la marca de bala:

 

 

(2020) Networking for alien minds

Rosario, Argentina