Actualizado el 29 de Junio del 2017 (Publicado el 10 de Mayo del 2017)
543 visualizaciones desde el 10 de Mayo del 2017
1,6 MB
26 paginas
Creado hace 10a (26/09/2013)
Compilador ROP
Christian Heitman
Fundación Dr. Manuel Sadosky
Septiembre de 2013
1 / 26
Return Oriented Programming
Los mecanismos de protección actual previenen la ejecución de
código en páginas de datos.
La técnica ROP permite evadir estos mecanismos.
Consiste en utilizar fragmentos de código dentro de un binario,
llamados gadgets, para computar ciertas operaciones.
Encadenando varios gadgets se puede armar funciones
arbitrarias.
2 / 26
Return Oriented Programming
3 / 26
ROPC
Es un PoC de un compilador ROP “Turing Complete”.
GitHub del autor: http://github.com/pakt
Posee un lenguaje de programación “similar” a C + ASM,
llamado ROPL.
Saltos condicionales
Funciones (soporta recursión)
Variables locales
Etiquetas
Punteros, dereferenciación de memoria, etc.
Hola Mundo (ROPL)
4 / 26
ROPC
Está basado en el paper “Q: Exploit Hardening Made Easy”.
Está escrito en ‘OCaml’.
Hola Mundo
Sumar una lista de enteros
5 / 26
Q / BAP
Q es similar a ROPC pero no está disponible.
BAP es una plataforma de análisis de binarios, con enfásis en la
verificación formal.
ROPC utiliza BAP para varias cosas:
Pasar código x86 a un lenguaje intermedio
Ejecución simbólica
Interacción con SMT solvers
6 / 26
SMT (Satisfiability Modulo Theories)
Extensión de SAT solver para trabajar con otros tipos de teorías,
por ejemplo, teoría aritmética.
Con SAT podemos responder cosas del estilo:
Existen r , p, q tales que (r ∧ ¬p) ∨ (q ∧ p)
Con SMT podemos responder cosas del estilo:
Existen x, y tales que 2x + 5y = 12 ∧ x > 2 ∧ y > −1
SMT permite modelar fácilmente código binario y podemos
preguntar sobre propiedades del mismo
Por ejemplo, el gadget g es semánticamente equivalente a una
suma?
Lo logramos expresando el gadget mediante fórmulas y añadiendo
las restricciones que queremos que cumpla.
7 / 26
ROPC - Estructura/Etapas
Gadgets:
Descubrimiento : procedimiento estandar
Clasificación : mediante ejecución simbólica
Cargar una constante : reg ← valor
Copiar un registro : reg dst ← reg src
Operación aritmética : reg ← reg 1 OP reg 2
Escribir a memoria : mem[addr + offset] ← reg
Leer de memoria : reg ← mem[addr + offset]
Leer y operar : reg ← reg OP mem[addr + offset]
Operar y escribir : mem[addr + offset] ← reg OP mem[addr + offset]
Verificación : mediante SMT solvers
8 / 26
ROPC - Estructura/Etapas
Parsing:
Parsea un programa en “ROPL” y genera un AST (Abstract Syntax
Tree)
Transformación:
Transforma el AST a una lista de pseudo instrucciones y en forma
SSA (Static Single Assigment)
Compilación:
Matching casi directo entre instrucciones simplificadas y gadgets
Busca una asignación de registros y gadgets que eviten conflictos
entre los mismos.
9 / 26
ROPC - Workflow
10 / 26
LLVM
Conjunto de herramientas para el desarrollo de compiladores.
Tiene un lenguaje intermedio llamado “LLVM IR”
Existen front-ends para C/C++/Objective-C, etc que generan
“LLVM IR”
Ejemplo del IR:
Código C
11 / 26
LLVM
IR LLVM
12 / 26
ROPC - Soporte Básico para LLVM
La idea es poder usar cualquier lenguaje que tenga un front-end
de LLVM para desarrollar un exploit
Se trató de modificar lo menos posible el código de ROPC.
La opción eligida fue traducción de ASTs: LLVM → ROPL
Hay ventajas y desventajas:
Modificaciones mínimas al código actual
Hay que lidiar con algunas limítaciones de ROPL
Por lo tanto,
“ROPL”.
Se implementó un parser/lexer de LLVM
Se implementó un traductor entre el AST de LLVM y el AST de
Antes, se hizo refactoring del código y se crearon módulos bien
definidos.
Una vez conseguido eso se pudo compilar ROP partiendo de un
.c (bueno, maso. . . )
13 / 26
ROPC - Workflow con LLVM
14 / 26
Parseando LLVM
LLVM incluye mucha información que, a fines prácticos de lo que
estamos haciendo, no es necesaria:
Atributos de funciones
Información de tipado
Metadata
Etc.
Durante el parseo y la generación del AST, se descarta esta
información.
El IR de LLVM es bastante extenso
Escribimos programas básicos en C
Los compilamos al IR (con clang)
Implementamos las instrucciones necesarias para poder
compilarlos a ROP.
El AST generado está pensado para que sea lo más parecido al
de ROPL
Esto facilita la implementación del traductor de ASTs
15 / 26
Traducción entre ASTs (LLVM → ROPL)
Hay instrucciones que no tiene un matching inmediato
Hay funcionalidades que no están soportadas en ROPL
Para estos casos, se hace la traducción en 2 etapas,
Simplificación / Reescritura del AST de LLVM
Resolución
Por ejemplo,
Branches:
Consta de 2 instrucciones diferentes, comparación y salto, la
condición de salto está en una y las etiquetas en otra.
GetElementPtr:
Es una instrucción “compleja” para calcular el offset dentro de un
arreglo / estructura.
Return:
La instrucción “return” de ROPL no retorna valores.
16 / 26
ROPC - Ejemplo
fib.ropl
fib.ropl (parseado)
17 / 26
ROPC con Soporte para LLVM - Ejemplo
fib.c
función “fib” (LLVM)
función “main” (LLVM)
18 / 26
ROPC con Soporte para LLVM - Ejemplo
función “fib” (parseado)
función “main” (parseado)
19 / 26
ROPC con Soporte para LLVM - Ejemplo
20 / 26
Problemas Encontrados
Limitaciones de ROPL. . .
Variables globales
En ROPC, todas las variables son globales
Hay una tabla donde están definidas
Las variables globales (de LLVM), se inicializan al comienzo del
“main” en la traducción.
Intrinsics de LLVM
Funciones conocidas, muy difundidas y con semántica definida:
‘memcpy’→ ‘llvm.memcpy’
‘memmove’→ ‘llvm.memmove’
‘memset’→ ‘llvm.memset’
Etc.
Pueden aparecer en código LLVM sin, necesariamente, haberlas
usado en el código C.
21 / 26
Limitaciones
Por el momento, es solo un PoC. . .
El código ROP generado es muy grande para ser usado en un
ambiente de ‘producción’.
Escrito en OCaml, lenguaje no muy difundido. . .
22 / 26
Trabajo Futuro
Optimizar código generado
Soportar un subconjunto más grande de LLVM
23 / 26
Referencias
ROPC - Soporte para LLVM
http://github.com/programa-stic/ropc-llvm
ROPC
http://github.com/pakt/ropc
Non-exec stack
http://seclists.org/bugtraq/2000/May/90
Future of buffer overflows ?
http://seclists.org/bugtraq/2000/Nov/32
“Advanced return-into-lib(c) exploits (PaX case study)”
http://www.phrack.com/issues.html?issue=58&id=
4&mode=txt
24 / 26
Referencias
“The Geometry of Innocent Flesh on the Bone: Return-into-libc
without Function Calls (on the x86)”
http://cseweb.ucsd.edu/˜hovav/dist/geometry.pdf
“Q: Exploit Hardening Made Easy”
http://users.ece.cmu.edu/˜ejschwar/papers/usenix11.pdf
BAP : The Next-Generation Binary Analysis Platform
http://bap.ece.cmu.edu/
SMT Solvers for Software Security
http://www.usenix.org/system/files/conference/
woot12/woot12-final26.pdf
25 / 26
¡Gracias!
Me contactan en:
26 / 26
Comentarios de: Compilador ROP (0)
No hay comentarios