Skip to content
Ejercicios y teoría sobre explotación de binarios y búsqueda de vulnerabilidades.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
fuzzing
infoleak
mitigaciones
primitivas
shellcode
stack
xploit
README.md

README.md

ABO++

STIC, Fundación Sadosky

Por consultas, correcciones, sugerencias, o cualquier comentario relacionado a la guía, pueden mandar un mail a abarreal@fundacionsadosky.org.ar. Agradecimientos especiales a Juan Heguiabehere y a Teresa Alberto de STIC por sus aportes para mejorar el material.


Introducción

Este repositorio contiene ejercicios varios sobre explotación de vulnerabilidades de corrupción de memoria, abarcando distintas técnicas y distintos temas teóricos. Adicionalmente, cada ejercicio cuenta con su correspondiente resolución.

La idea de este material es que sea complementario a la guía de escritura de exploits de Teresa Alberto, basada en los ABOs de Gerardo Richarte. El objetivo de ABO++ es proveer material adicional que permita adquirir los conocimientos y las destrezas necesarias para encontrar y explotar vulnerabilidades de corrupción de memoria en entornos modernos, con herramientas modernas utilizadas en la industria hoy en día.

Los ejercicios están organizados en secciones:

  1. Infoleak
  2. Shellcode
  3. Stack
  4. Mitigaciones - parte 1
  5. Búsqueda de vulnerabilidades y desarrollo de primitivas
  6. Ataques de corrupción de memoria - parte 1
  7. Fuzzing

Las primeras tres secciones pueden llevarse en paralelo a la guía de Teresa. Para las secciones que siguen se recomienda ya tener familiaridad con los niveles 1 y 2 de la mencionada guía como mínimo. Las secciones arriba listadas corresponden a la primera parte de ABO++; la segunda parte se encuentra actualmente en desarrollo.

Nota: Todos los ejercicios fueron probados en una instalación de Ubuntu Desktop 18.04, usando gcc 7.3.0, glibc 2.27, y ocasionalmente Clang 6.0 para los ejercicios de fuzzing. Adicionalmente, a excepción que se indique lo contrario, todos los binarios deberían ser compilados usando gcc y sin opciones adicionales (e.g. gcc ejercicio.c -o ejercicio)

Ejercicios

Infoleak

Ejercicios sobre filtración de datos. Muchos exploits modernos requieren la capacidad de leer el espacio de memoria del proceso que está siendo atacado. Estos ejercicios introducen algunas técnicas para lograrlo.

  • Infoleak-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es lograr, sin editar el código ni el binario generado por el compilador, que el programa emita por la salida estándar el valor del campo secret_token.

  • Infoleak-02 (Ejercicio / Solución)
    Nuevamente, el objetivo es lograr, sin editar el programa, que el mismo emita por salida estándar el valor del campo secret_token. Adicionalmente, en la solución de este ejercicio introducimos gdb y gef para el análisis de programas en tiempo de ejecución.

Shellcode

Ejercicios sobre escritura y manejo de shellcode.

  • Shellcode-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es lograr, sin modificar el código ni el binario, que el programa muestre "hello, world!" en la terminal y luego finalice sin error.

  • Shellcode-02 (Ejercicio / Solución)
    El objetivo de este ejercicio es, tomando el mismo código de shellcode-01, lograr que el programa se conecte a un cierto puerto TCP y provea una shell que permita ejecutar comandos. Para desarrollar la solución utilizamos msfvenom, parte de la suite de Metasploit.

Stack

Ejercicios para familiarizarse con la estructura del stack y con el flujo de ejecución de los procesos. Se recomienda ir leyendo la introducción al funcionamiento del stack en la guía de escritura de exploits de Teresa Alberto.

  • Stack-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es lograr, sin modificar el código fuente ni el binario compilado, que el programa en cuestión muestre un cierto mensaje en la terminal. Para eso hay que encontrar alguna forma alternativa de controlar el flujo de ejecución del programa.
  • Stack-02 (Ejercicio / Solución)
    El objetivo de este ejercicio es lograr, sin modificar el código fuente ni el binario compilado, que el programa ejecute una función que normalmente no se ejecutaría.
  • Stack-03 (Ejercicio / Solución)
    En enunciado de este ejercicio está en el código. La idea del ejercicio es familiarizarse con una mitigación que hoy día impide que los ataques clásicos ya ampliamente conocidos sigan funcionando. En la solución se presentan los detalles del ataque y del funcionamiento de la mitigación.

Mitigaciones - parte 1

Resúmenes sobre los mecanismos más relevantes y más ampliamente adoptados por los sistemas Linux modernos para prevenir ataques de corrupción de memoria. Antes de comenzar con este material se recomienda familiarizarse con el stack overflow clásico, explicado detalladamente en la guía de escritura de exploits de Teresa Alberto.

Cabe mencionar que estas no son las únicas mitigaciones existentes, aunque en su conjunto logran una protección de propósito general bastante adecuada. Existen, por otro lado, mitigaciones adicionales que pueden ser adoptadas por sistemas con requisitos de seguridad más rigurosos. Dichas mitigaciones todavía no son tan ubicuas, sin embargo, ya sea por requerir configuración manual, por impactar significativamente en el consumo de recursos, por ser difíciles de implementar, por ser demasiado recientes, o por algún otro motivo. En general, más allá de las mitigaciones aquí listadas, cada sistema adoptará medidas adicionales según sus requisitos de seguridad concretos. En la segunda parte estaremos analizando algunas de estas mitigaciones en detalle.

Búsqueda de vulnerabilidades y desarrollo de primitivas

  • Introducción
  • Vuln-01 (Ejercicio / Solución)
    El código de este ejercicio consiste en dos archivos vuln-01.c y file.h. El objetivo es desarrollar una primitiva que permita escribir datos arbitrarios a partir de direcciones arbitrarias en el espacio de memoria del proceso objetivo. Esencialmente, queremos poder escribir una secuencia de bytes arbitraria d a partir de una dirección arbitraria x. El objetivo no es conseguir una shell ni ejecutar un exploit completo; esto probablemente no sea posible sin deshabilitar ASLR.

Técnicas de explotación y ataques de corrupción de memoria - parte 1

  • ROP-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es aprender a utilizar la técnica llamada Return Oriented Programming (ROP) para vencer a W^X y lograr la eventual ejecución de código arbitrario. Los datos necesarios para vencer a ASLR y a Stack Protector son provistos por el programa. Por una introducción detallada a ROP consultar [2]; alternativamente, en la primera parte de la solución se provee una introducción más amena.

  • ROP-02 (Ejercicio / Solución)
    Este ejercicio es similar al anterior. Esta vez, sin embargo, el conjunto de direcciones conocidas es diferente. Será necesario realizar algunos pasos adicionales para lograr la explotación.

  • First Boss (Intro / Ejercicio / Solución)
    La idea de este ejercicio es integrar todos o la mayoría de los conceptos estudiados hasta ahora. El objetivo es desarrollar desde cero un exploit totalmente funcional para lograr ejecutar código arbitrario en un servidor TCP. El binario debería ser generado sin flags que pudieran debilitar la seguridad del programa resultante (i.e. sin deshabilitar mitigaciones). Al 22/01/2019 el servidor es explotable en un Ubuntu 18.04 x64 actualizado. En la solución implementamos también un módulo de Metasploit que puede ser utilizado para explotar el servidor en forma automática. Nota: Está de más decir que este servidor no debería ser expuesto a redes o a usuarios que no sean de confianza. Ante la duda, se recomienda ejecutar el servidor en una máquina virtual aislada.

Fuzzing

Ejercicios sobre técnicas y herramientas de fuzzing. Fuzzing es una técnica muy utilizada hoy en día para ayudar a la detección de vulnerabilidades.

  • Introducción
    Material introductorio. Solo se hace mención de algunos conceptos básicos y de las herramientas más relevantes que estaremos usando para resolver los siguientes ejercicios.

  • libFuzzer-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es aprender a utilizar libFuzzer, un fuzzer integrado con el compilador Clang, fuzzeando un ejemplo sencillo.

  • libFuzzer-02 (Ejercicio / Solución)
    El objetivo de este ejercicio es aprender a construir un corpus para el fuzzer, y a desarrollar funciones objetivo quizás menos triviales.

  • AFL-01 (Ejercicio / Solución / Sugerencias)
    El objetivo de este ejercicio es familiarizarse con AFL, un fuzzer un poco más complejo que libFuzzer, si bien más flexible en varios aspectos.

  • AFL-02 (Ejercicio / Solución)
    El objetivo de este ejercicio es aprender a definir diccionarios para AFL. Los diccionarios le permiten al fuzzer aprender y fuzzear gramáticas complicadas como la de SQL, HTML, HTTP, etc.

  • TCP-01 (Ejercicio / Solución)
    El objetivo de este ejercicio es lograr fuzzear un servidor TCP simple. Al día de la fecha no parecería existir un procedimiento genérico y siempre aplicable para fuzzear servidores. En la solución de este ejercicio se presenta un posible esquema que resulta ser bastante eficiente y fácil de implementar cuando es posible aplicarlo.

  • TCP-02 (Ejercicio / Solución)
    La idea aquí es tomar el mismo código del ejercicio TCP-01 y fuzzearlo usando preeny, una solución similar en espíritu a la que sugerimos originalmente pero más práctica y más robusta en varios aspectos.

  • TCP-03 (Ejercicio / Solución)
    La idea de este ejercicio es fuzzear un servidor TCP usando preeny. La diferencia con TCP-02 es que en este caso conviene llevar al servidor a un cierto estado concreto antes de enviar el payload mutado.

  • Black-Box-01 (Ejercicio / Solución)
    La idea de este ejercicio es fuzzear un binario MIPS no instrumentado. Para ello podemos utilizar AFL y una versión instrumentada de qemu, la cuál puede ser compilada en base a parches distribuidos con el mismo fuzzer.

  • Black-Box-02 (Ejercicio / Solución)
    El objetivo de este ejercicio es tomar el servidor fuzzeado en el ejercicio TCP-01 y compilarlo para MIPS, sin enlace estático. Luego hay que utilizar AFL y qemu para fuzzear el programa en modo caja negra. Si fuese necesario hacer algún cambio, solo es admisible parchear el binario.

  • Fuzzing nanosvg
    Ejemplo de cómo fuzzear una biblioteca con AFL. Introducimos algunas funciones adicionales de AFL que no habíamos mencionado en los ejercicios anteriores, y también detallamos algunos componentes de la interfaz gráfica del fuzzer para permitir el monitoreo del rendimiento y del progreso de las pruebas.

Recursos útiles

Referencias

[1] Anley, Heasman, Lindner & Richarte (2007). The Shellcoder's Handbook: Discovering and Exploiting Security Holes.

[2] Shacham (2007). The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86).

Nota: Hay también referencias adicionales listadas en las soluciones de los ejercicios relevantes.

You can’t perform that action at this time.