Análisis forense de logs de Apache/Nginx

24610865264_40c52172b4_o
Estándar

En este artículo voy a describir técnicas y herramientas para llevar a cabo un análisis forense de un archivo (o archivos) de log de un servidor Web Apache o Nginx.

Por defecto, los servidores Web Apache y Nginx (como así también IIS) utilizan el formato de log NCSA Common Log Format para registrar las solicitudes de clientes y errores. Este formato registra la URL completa de cada recurso al que se accede. De esta forma, realizar un análisis forense sobre un archivo de log se reduce a buscar actividad sospechosa en URLs, esto es, intentos de inyección, accesos inadecuados, manipulación de parámetros GET, accesos a archivos sospechosos, etc.

Es posible utilizar comandos comunes para filtrar y buscar patrones de ataque desde línea de comandos (de manera artesanal), o utilizar herramientas específicas de análisis forense, como por ejemplo LORG.

Análisis de forma manual con herramientas de línea de comandos

Efectuar búsquedas de patrones en cadenas de texto es una tarea trivial que puede ser realizada con infinidad de herramientas, solo basta con conocer un poco acerca de la codificación de URLs (URL encoding), la cual convierte los caracteres de las URLs a un formato estándar que pueda ser transmitido a través de Internet.

Las URLs sólo pueden ser enviadas a través de Internet utilizando el conjunto de caracteres ASCII. Además, una cierta porción de los caracteres ASCII están reservados por el protocolo HTTP, son especiales. Sin embargo, debido a que las URLs generalmente utilizan caracteres fuera del conjunto ASCII y caracteres considerados especiales, deben ser convertidas a un formato ASCII válido y seguro. El proceso de URL encodingreemplaza caracteres no ASCII por un caracter % seguido de dos números hexadecimales que indican su codificación. Este proceso es también conocido como percent-encoding.

Esto implica que, al momento de buscar una cierta cadena, es necesario buscar tanto las forma plana como la versión codificada. Incluso se deberían probar todas las combinaciones posibles de caracteres codificados y sin codificar, para detectar los ataques más avanzados (aquellos que tratan de pasar desapercibidos al ojo del monitor de seguridad).

Para saber cómo se codifica un caracter o cadena es posible consultar la página HTML URL Encoding Reference

En sistemas operativos de la familia Unix, es posible filtrar y buscar cadenas que caracteres que den indicios de ataques o intentos de ataques utilizando herramientas de línea de comandos como grep, sed, awk, cut, etc.

SQLi

Buscar palabras clave del lenguaje SQL (union, insert, select, etc) que den indicios de intento de inyección de código:

# grep --color 'union' ssl_access.log
# grep --color 'insert' ssl_access.log
# grep --color 'select' ssl_access.log

Por ejemplo:

root@debian:/usr/local/tmp# grep --color 'select' ssl_access.log
76-112-228-181.cab.prima.com.ar - - [06/Jul/2016:18:40:37 -0300] "GET /supercoolapp/select%20*%20from%20alumnos HTTP/1.1" 302 929 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17"

Esta ridiculez fue encontrada en un log real de un servidor en producción.

emi@hal9000:~ % drill -x 181.228.112.76
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 40213
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0 
;; QUESTION SECTION:
;; 76.112.228.181.in-addr.arpa. IN      PTR

;; ANSWER SECTION:
76.112.228.181.in-addr.arpa.    85194   IN      PTR     76-112-228-181.cab.prima.com.ar.

;; AUTHORITY SECTION:
228.181.in-addr.arpa.   79814   IN      NS      o200.prima.com.ar.
228.181.in-addr.arpa.   79814   IN      NS      o2000.prima.com.ar.

;; ADDITIONAL SECTION:

;; Query time: 1 msec
;; SERVER: 8.8.8.8
;; WHEN: Mon Jul 11 12:54:31 2016
;; MSG SIZE  rcvd: 129

Se supone que este fenómeno vive por mi barrio:

Para que la búsqueda sea eficaz, es necesario restringir la búsqueda sólo al campo que almacena la URL (delimitado por comillas dobles). Luego, de ser necesario, buscar más información relacionando los resultados. De lo contrario es imposible buscar ciertos caracteres como coma (,), punto y coma (;), etc.

# cat ssl_access.log | cut -d'"' -f2

Buscar comillas simples ‘ (%27):

# cat ssl_access.log | cut -d'"' -f2 | grep --color "'"
# cat ssl_access.log | cut -d'"' -f2 | grep --color "%27"

Buscar asteriscos * (%2A) en URLs:

# cat ssl_access.log | cut -d'"' -f2 | grep --color '%2A'
# cat ssl_access.log | cut -d'"' -f2 | grep --color '\*'

Buscar palabras clave de motores de bases de datos (como system, exec, etc.):

# cat ssl_access.log | cut -d'"' -f2 | grep --color 'system'
# cat ssl_access.log | cut -d'"' -f2 | grep --color 'exec'

Buscar comentarios de MySQL (–):

# cat ssl_access.log | cut -d'"' -f2 | grep --color '%2D'
# cat ssl_access.log | cut -d'"' -f2 | grep --color '--'

Por ejemplo:

root@debian:/usr/local/tmp# grep --color '\*' ssl_access.log 
76-112-228-181.cab.prima.com.ar - - [06/Jul/2016:18:40:37 -0300] "GET /supercoolapp/select%20*%20from%20alumnos HTTP/1.1" 302 929 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17"

Aparece nuevamente el peligroso hacker con su temida Mac corriendo Safari.

Ataques clásicos/path traversal

Buscar ataques comunes, como intentos de acceso al archivo /etc/passwd o directorios de niveles superiores:

# cat ssl_access.log | cut -d'"' -f2 | grep --color 'passwd
# cat ssl_access.log | cut -d'"' -f2 | grep --color '\.\./'
# cat ssl_access.log | cut -d'"' -f2 | grep --color '%2E%2E'

Al buscar la cadena “–” en las URLs pueden aparecer cientos de falsos positivos.

XSS

Buscar menor (%3C) y mayor (%3E):

# grep --color '%3C' ssl_access.log
# grep --color '%3E' ssl_access.log

Buscar punto y coma (%3B):

# cat ssl_access.log | cut -d'"' -f2 | grep --color '%3B'
# cat ssl_access.log | cut -d'"' -f2 | grep --color ';'

Buscar comillas simples (%27) y dobles (%22):

# cat ssl_access.log | cut -d'"' -f2 | grep --color "'"
# cat ssl_access.log | cut -d'"' -f2 | grep --color "%27"
# cat ssl_access.log | cut -d'"' -f2 | grep --color \"
# cat ssl_access.log | cut -d'"' -f2 | grep --color "%22"

Rootkits

Buscar intentos de acceso a shells PHP conocidas:

# cat ssl_access.log | cut -d'"' -f2 | grep --color 'b374k'
# cat ssl_access.log | cut -d'"' -f2 | grep --color 'c99.php'
# cat ssl_access.log | cut -d'"' -f2 | grep --color 'r57'

Del mismo modo, aplicar esta técnica para buscar otros ataques o actividad sospechosa.

Análisis con una herramienta automatizada: LORG

En general existe siempre una amplia variedad de herramientas automatizadas para realizar estas tareas de escaneo, análisis forense, monitoreo, etc. La ventaja que tienen estas herramientas es que son simples, no involucran tiempo o trabajo, y no requieren un profundo conocimiento de las técnicas de ataque. Sin embargo, toda herramienta automatizada tiende a generar toneladas de falsos positivos (pues realizan chequeos genéricos que no se ajustan a la implementación de la aplicación Web que se está analizando), los cuales son difíciles de identificar justamente para alguien que no tiene conocimientos profundos sobre las técnicas de ataque y la materia en general (Seguridad de la Información). El análisis manual es engorroso, lleva tiempo, pero también mucho más exhaustivo y a medida de la aplicación Web en cuestión.

Habiendo dicho ésto, es bueno correr tests con herramientas automáticas para contrastar resultados, obtener resúmenes e información estadística derivada, recopilar material para elaborar reportes, y evitar pasar por alto algún detalle. En este caso decidí probar LORG, una herramienta para el análisis forense de logs de servidores Web, llamada originalmente “Web Forensik”.

Para instalar LORG basta con clonar sus fuentes desde GitHub:

$ git clone https://github.com/jensvoid/lorg

Previamente es necesario instalar PHP junto con los módulos requeridos (pcntl, simplexml, filter, mbstring y ctype). En FreeBSD se instalan desde paquetes ejecutando:

# pkg install php56 php56-pcntl php56-simplexml php56-filter php56-mbstring php56-ctype

Es recomendable aumentar el tamaño máximo permitido en memoria para scripts PHP a través de la variable de entorno memory_limit dentro del archivo de configuración php.ini:

;memory_limit = 128M
memory_limit = 1024M

Para realizar un escaneo básico con LORG, ejecutar ./lorg -d phpids -u -g ARCHIVO. Por ejemplo:

emi@hal9000:~/scripts/lorg % ./lorg -d phpids -u -g ~/ssl_access.log

[#] No input file format given - guessing 'combined'
[#] No output file format given - using 'html'
[#] No output file given - using 'report_13-Jul-2016-161213.html'
[#] Cannot find pChart/GD library - charting disabled
[#] No threshold given - using default value '10'
[#] No client identifier given - using 'host'
[#] Non-binary urlencoded requests will be decoded
[>] Counting number of lines of 'ssl_access.log'
[#] Logfile contains hostnames - this might be a significant slowdown
[>] Processing 2015663 lines of input file 'ssl_access.log' [10%]

Luego de unos minutos (dependiendo del tamaño del archivo de log)…

[>] Creating summary for 'ssl_access.log'

    Found 2525 incidents (9980 tags) from 700 clients
    | sqli:        2029 | id:          2525 | lfi:         2525 | 
    | xss:         1050 | csrf:        1050 | rfe:          796 | 
    | format string:       2 | dt:             3 | 

[>] Check out 'report_13-Jul-2016-161213.html' for a complete report

LORG genera un reporte completo y detallado en formato HTML:

emi@hal9000:~/scripts/lorg % ll -h report_13-Jul-2016-161213.html 
-rw-r--r--  1 emi  wheel    70M Jul 13 14:17 report_13-Jul-2016-161213.html

Encontrar ésto en el reporte me hizo llorar de risa: “The incident happened during unusual working hours in Argentina, so it might be carried out by a hobbyist on caffeine.”.

En este caso la aplicación Web en cuestión está tan horriblemente diseñada (utiliza expresiones en variables GET que son interpretadas como intentos de inyección, cuando en realidad es tráfico válido) que el escáner detecta a la mayoría de los accesos como ataques. Sin embargo es una gran herramienta a tener en cuenta para futuros análisis forenses.

Referencias

man grep
man cut

NCSA Common Log Format

percent-encoding

HTML URL Encoding Reference

Common php webshells

LORG

IP Location Lookup

 

(Fuente: linuxito)