De Nikto a crear un usuario en 17 minutos

Plataforma
LetsDefend
Categoría
Análisis de logs
Dificultad
Easy

Investigate Web Attack

We detected some web attacks and need to do deep investigation.

Se han detectado ataques contra una web y hay que investigarlos a fondo. Lo único que nos dan es el access.log del servidor, así que toca leerlo y responder siete preguntas.

Primer vistazo al log

Partimos del access.log de una aplicación web. A priori es mucho texto, pero cada línea es una petición al servidor y todas siguen el mismo formato. Esta es una de las primeras, de alguien navegando con normalidad:

192.168.199.1 - - [20/Jun/2021:12:35:48 +0300] "GET /bWAPP/logout.php HTTP/1.1" 302 - "http://192.168.199.5/bWAPP/portal.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0"

Por partes:

  • 192.168.199.1: la IP de quien hace la petición.
  • [20/Jun/2021:12:35:48 +0300]: fecha y hora, con su zona horaria.
  • GET /bWAPP/logout.php: el método y la página que pide.
  • 302: el código de respuesta del servidor (aquí, una redirección).
  • -: el tamaño de la respuesta en bytes (- si va vacía).
  • http://192.168.199.5/bWAPP/portal.php: el Referer, la página desde la que venía.
  • Mozilla/5.0 (...) Firefox/89.0: el User-Agent, el programa que hace la petición.

La aplicación es bWAPP, una web hecha vulnerable a propósito para practicar. Al principio solo hay tráfico normal desde 192.168.199.1, y en seguida aparece otra IP, 192.168.199.2, que es la del atacante. Leído en orden, el log cuenta el ataque entero: reconocimiento, fuerza bruta, acceso, ejecución de comandos y persistencia.

Preguntas

1. Herramienta de escaneo

Which automated scan tool did attacker use for web reconnaissance?

Respuesta: Nikto

En mi caso el ojo se me fue directamente a la respuesta, porque la herramienta se presenta sola en el User-Agent:

Líneas 25 a 40 del access.log. Las primeras son peticiones normales desde 192.168.199.1 con Firefox; a partir de la 30, la IP 192.168.199.2 lanza peticiones con User-Agent "Mozilla/5.00 (Nikto/2.1.6)" y etiquetas como "(Test:getinfo)" y "(Test:map_codes)", recuadrado en rojo, pidiendo ficheros inventados como /bwapp/4RaXX5Ac.exe, .java o .bat que devuelven 404.

Nikto no disimula: pone su nombre, su versión y hasta la prueba que está haciendo.

Además de Nikto/2.1.6, se ve cómo trabaja: pide ficheros con nombres aleatorios (4RaXX5Ac.exe, 4RaXX5Ac.java...) para ver cómo responde el servidor a cosas que no existen.

2. Descubrimiento de directorios

After web reconnaissance activity, which technique did attacker use for directory listing discovery?

Respuesta: Directory brute force

Revisando un poco el log después de Nikto, se ve que el atacante no para de probar rutas una detrás de otra, casi todas con 404. Eso es fuerza bruta de directorios: tirar una lista de nombres habituales y quedarse con los que existen.

3. Tercer ataque

What is the third attack type after directory listing discovery?

Respuesta: Brute force

Aquí toca fijarse en los POST. Casi todo lo anterior son GET, pero de repente aparecen un montón de POST seguidos contra /bWAPP/login.php, varios por segundo:

Fragmento del access.log con decenas de líneas "POST /bWAPP/login.php HTTP/1.1" 200 4086 seguidas, entre las 12:41:41 y las 12:43:20 +0300, todas con el mismo User-Agent de Firefox 52 en Linux. La columna del método POST está recuadrada en rojo.

Varios intentos de login por segundo, todos idénticos: esto no lo hace una persona.

Tres cosas lo delatan:

  • El ritmo: varios POST por segundo al mismo formulario.
  • La respuesta: todos devuelven 200 con 4086 bytes, siempre lo mismo. Que sea 200 no quiere decir que haya entrado (lo explico en el tip de abajo).
  • La duración: siguen así durante unos ocho minutos, hasta la línea 12.545 del fichero.

4. ¿Tuvo éxito?

Is the third attack successful?

Respuesta: Yes

Al final del bloque de fuerza bruta la respuesta cambia:

Líneas 12541 a 12557 del access.log. Recuadradas en rojo: tras varios POST a login.php con 200 4086, uno devuelve 302 sin cuerpo, sigue un GET a /bWAPP/portal.php con 200 y 23369 bytes, un POST a portal.php, un GET a /bWAPP/phpi.php y un GET a phpi.php?message=test. Debajo empiezan las peticiones con system('whoami'), net user y net share.

El 302 es el momento en el que entra.

Al principio pensé que la prueba era el message=test que aparece justo después, pero eso ya es el atacante dentro, probando la siguiente página. La prueba del login es el 302 seguido del portal.php.

5. Cuarto ataque

What is the name of fourth attack?

Respuesta: Code injection

Ya dentro, el atacante va a /bWAPP/phpi.php. En bWAPP esa página es el ejercicio de PHP Code Injection: lo que llega en el parámetro message se mete dentro de un eval() de PHP, así que se ejecuta como código.

Primero prueba con message=test para ver cómo responde. Después, en vez de un texto, manda esto (el log lo guarda codificado en URL):

message=%22%22;%20system(%27whoami%27)
message=""; system('whoami')

El servidor construye algo así como echo ""; system('whoami');: el "" cierra el echo con una cadena vacía y el system() ejecuta un comando del sistema operativo.

6. Primer payload

What is the first payload for 4th attack?

Respuesta: whoami

Lo de siempre: lo primero al conseguir ejecución es saber con qué usuario se está ejecutando. Después sigue con net user y net share para ver usuarios y recursos compartidos del equipo.

Las cinco peticiones a phpi.php: system('whoami'), system('net user') y system('net share') recuadradas en rojo, y debajo dos veces system('net user hacker Asd123!! /add') en otro recuadro.

Primero reconocimiento, luego persistencia.

7. Persistencia

Is there any persistency clue for the victim machine in the log file ? If yes, what is the related payload?

Respuesta: %27net%20user%20hacker%20Asd123!!%20/add%27

Ojo, que aquí la respuesta es solo el comando que va dentro de system(), con sus comillas y tal cual sale en el log, codificado en URL. Decodificado se entiende mejor:

%27net%20user%20hacker%20Asd123!!%20/add%27
'net user hacker Asd123!! /add'

net user ... /add crea un usuario local en Windows: hacker con la contraseña Asd123!!. Aunque se parchee la inyección, el atacante tiene una cuenta propia para volver a entrar. En ATT&CK es T1136.001, Create Account: Local Account.

Que use net user también dice algo del servidor: por debajo de bWAPP hay un Windows.

Cronología

Con todo junto, así queda el ataque de principio a fin. Las horas del log van en +0300; aquí están pasadas a UTC.

Hora (UTC) Qué pasa
2021-06-20T09:36:24Z Empieza el escaneo con Nikto
2021-06-20T09:41:41Z Fuerza bruta contra /bWAPP/login.php
2021-06-20T09:49:35Z Un POST al login devuelve 302: entra
2021-06-20T09:50:15Z Visita phpi.php y prueba con message=test
2021-06-20T09:52:36Z Primer comando inyectado: whoami
2021-06-20T09:53:13Z Crea el usuario hacker

Diecisiete minutos entre el primer escaneo y el usuario nuevo.

Aprendizajes

  1. Con un log se puede reconstruir todo: no hizo falta ninguna herramienta rara. Leyéndolo en orden se ve el ataque entero, desde que empieza a escanear hasta que se crea su usuario.
  2. Un 200 no significa que haya entrado: para saber si un login ha funcionado hay que fijarse en el tamaño de la respuesta y en cuándo aparece el 302.
  3. Primero decodificar, luego leer: los payloads en el log vienen codificados y puede costar entenderlos. Decodificados se ve al momento qué hacía el atacante.