Capturando credenciales en claro mediante un firewall Fortigate

En este mundillo estamos cansados de repetir que se sustituya FTP y telnet por sus respectivos equivalente seguros: SCP, FTPS, SFTP, SSH... pero después de tantos años se siguen utilizando :(

Hoy vamos a hacer una pequeña demostración de la inseguridad del uso de estos protocolos no cifrados capturando tráfico mediante un firewall y obteniendo las contraseñas en claro. 

En la vida real el firewall podría ser la máquina de un atacante, el cuál tendría la misma facilidad para robar credenciales simplemente esnifando el tráfico en un nodo que está en medio del camino de nuestra conexión cliente-servidor. Y no sólo el atacante podría ser una persona hábil que ha envenenado ARP y ha conseguido hacer un MiTM... en este gran entramado que es Internet, un ISP o hasta el administrador de red de una empresa podría estar vigilando...

Para nuestro escenario concreto el firewall será un Fortigate. Estos cacharros tienen una gran variedad de comandos de diagnóstico. Permiten depurar aplicaciones comunes (ike, sslvpn, urlfilter...), el proceso de flujo de paquetes e incluso activar un sniffer bastante decente que arroja una salida muy similar a la de tcpdump (será un fork?). La sintaxis del comando es la siguiente:


# diag sniffer packet <interfaz> <'filtro'> <verbose> <contador> a

Veamos primero un ejemplo sencillo:
# diag sniffer packet internal 'src host 192.168.0.130 and dst host 192.168.0.1' 1

192.168.0.130.3426 -> 192.168.0.1.80: syn 1325244087
192.168.0.1.80 -> 192.168.0.130.3426: syn 3483111189 ack 1325244088
192.168.0.130.3426 -> 192.168.0.1.80: ack 3483111190
192.168.0.130.3426 -> 192.168.0.1.80: psh 1325244088 ack 3483111190
192.168.0.1.80 -> 192.168.0.130.3426: ack 1325244686
192.168.0.130.1035 -> 192.168.0.1.53: udp 26
192.168.0.130.1035 -> 192.168.0.1.53: udp 42
192.168.0.130.1035 -> 192.168.0.1.53: udp 42
192.168.0.130 -> 192.168.0.1: icmp: echo request
192.168.0.130.3426 -> 192.168.0.1.80: psh 1325244686 ack 3483111190
192.168.0.1.80 -> 192.168.0.130.3426: ack 1325244735
192.168.0.130 -> 192.168.0.1: icmp: echo request

Y las opciones que manejamos:

- Interfaz, como su nombre indica, es el interfaz por el que se capturarán los paquetes. Podemos especificar "any" para que capture en todos los interfaces.


- El filtro puede tener también la siguiente sintaxis: '[[src|dst] host] [[src|dst] host] [[arp|ip|gre|esp|udp|tcp] [port_no]] [[arp|ip|gre|esp|udp|tcp] [port_no]]'


- Verbose tiene diferentes niveles:
    1: muestra la cabecera de los paquetes
    2: muestra la cabecera y los datos IP de los paquetes
    3: muestra la cabecera y los datos ethernet de los paquetes
    4: muestra la cabecera de los paquetes con el nombre de interfaz
    5: muestra la cabecera y los datos IP de los paquetes con el nombre de interfaz
    6: muestra la cabecera y los datos ethernet de los paquetes con el nombre de interfaz


- El contador indica el número de paquetes que se recogerán antes de parar el sniffer. Si no especificamos nada seguirá recogiendo paquetes hasta que lo paremos con CTRL+C.


- Y por último la opción "A" es para mostrar timestamps

Ahora imaginemos que queremos capturar las credenciales de un acceso FTP. Podríamos capturar las de todas las sesiones en un momento dado filtrando simplemente el puerto TCP; pero para el ejemplo supongamos que queremos capturar sólo las credenciales de un acceso a un servidor FTP específico, ftp.rediris.org con IP 130.206.1.5.

Primero, en Putty, no olvidemos capturar la salida de la sesión a un fichero de log:



Después iniciaremos el sniffer: 
# diag sniffer packet any 'dst host 130.206.1.5' 6
interfaces=[any]
filters=[dst host 130.206.1.5]

Y desde un cliente ftp estándar lanzaremos la conexión:

C:\Users\vmotos\Desktop>ftp ftp.rediris.org
Conectado a zeppo.rediris.es.
220-  Bienvenido al FTP an├│nimo de RedIRIS.
220-Welcome to the RedIRIS anonymous FTP server.
220 Only anonymous FTP is allowed here
Usuario (zeppo.rediris.es:(none)): vicente
331-            RedIRIS - Red Acad├®mica y de Investigaci├│n Espa├▒ola
331-                RedIRIS - Spanish National Research Network
331-
331-           ftp://ftp.rediris.es  -=-  http://ftp.rediris.es
331-
331 Any password will work
Contraseña:
230 Any password will work

Ahora comprobareis rápidamente que el sniffer está capturando datos. Si os fijáis en el fichero de log generado aparecerá la contraseña en claro:

7.816069 123.123.123.11.19043 -> 130.206.1.5.21: psh 840580428 ack 3720924021
0x0000   0000 0000 0000 0009 0fd3 bac5 0800 4500        ..............E.
0x0010   0035 1d7b 4000 7c06 5d89 c2e0 3d0b 82ce        .5.{@.|.]...=...
0x0020   0105 4a63 0015 321a 3d4c ddc8 cb75 5018        ..Jc..2.=L...uP.
0x0030   07a1 ba58 0000 5041 5353 2070 7275 6562        ...X..PASS.prueb
0x0040   610d 0a      

Aunque si lo preferís, existe un script en perl fgt2eth.pl (o su versión ejecutable) para exportar el fichero a formato pcap y analizarlo más claramente con Wireshark.

Primero quitamos la cabecera que nos deja putty:

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2014.12.04 01:35:03 =~=~=~=~=~=~=~=~=~=~=~=

Y luego lo exportamos con esta utilidad:

C:\Users\vmotos\Desktop>fgt2eth.exe
Version : 1.22 (Feb 21 2008)

Assuming OS: windows
Usage : fgt2eth.pl -in <input_file_name>

Mandatory argument are :
   -in  <input_file>     Specify the file to convert (FGT verbose 3 text file)

Optional arguments are :
   -help                 Display help only
   -version              Display script version and date
   -out <output_file>    Specify the output file (Ethereal readable)
                         By default '<input_file>.eth' is used
   -lines <lines>        Only convert the first <lines> lines
   -system <system>      Can be either linux or windows
   -debug                Turns on debug mode
      
C:\Users\vmotos\Desktop>fgt2eth.exe -i putty.log -o putty.pcap
Conversion of file putty.log phase 1 (FGT verbose 3 conversion)
Output written to putty.pcap.
Conversion of file putty.log phase 2 (windows text2pcap)
Ouput file to load in Ethereal is 'putty.pcap'

Y por último lo abrimos con Wireshark. Si queréis afinar más la búsqueda podéis usar el filtro:

(ftp.response.code == 230 || ftp.request.command == "PASS") || (ftp.request.command == "USER")




¡Feliz caza!

Comentarios