Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Rooted2020 encontrando 0days-en_2020_-_antonio_morales

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Nächste SlideShare
Paralela2
Paralela2
Wird geladen in …3
×

Hier ansehen

1 von 92 Anzeige
Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Ähnlich wie Rooted2020 encontrando 0days-en_2020_-_antonio_morales (20)

Anzeige

Weitere von RootedCON (20)

Aktuellste (20)

Anzeige

Rooted2020 encontrando 0days-en_2020_-_antonio_morales

  1. 1. Encontrando 0days en 2020 Antonio Morales
  2. 2. // WHO AM I #define speaker Antonio Morales Maldonado #define job Security Researcher at #define twitter @nosoynadiemas using namespace RootedCON; int main(int argc, char* argv[]){ 2
  3. 3. ● Podéis pegaros una cabezadita sin problema (siempre que no ronquéis en exceso) Aviso 5 No seré yo quien os lo recrimine (que soy andaluz)
  4. 4. • Pero no esta… 6 Motivación
  5. 5. … si no esta. Agenda: • CVE-2020-9273 • CVE-2020-9365 • Fuzzing: • Mutation Scheduling • Structure-Aware-Fuzzing • Domain-Specific feedback 7 Motivación
  6. 6. Where’s the hash? 8
  7. 7. … si no esta. Agenda: • CVE-2020-9273 • CVE-2020-9365 • Fuzzing: • Mutation Scheduling • Structure-Aware-Fuzzing • Domain-Specific feedback 9 Motivación
  8. 8. ● Se trata de un Use-After-Free que afecta al memory pool de Pro-FTPd ● Fue reportado el 21 de Enero de 2020 ● El fallo permite corromper el memory pool de ProFTPd a través de la interrupción de una transferencia activa ● La gravedad del fallo aumenta dado que: ○ Es explotable (se puede obtener una primitiva de escritura) ○ La corrupción del memory pool deriva en otras vulnerabilidades (como un OOB-Write o un OOB-Read) Motivación: CVE-2020-9273 10
  9. 9. ¿¿Memory Pool?? 11 Motivación: CVE-2020-9273
  10. 10. ● Se conoce como memory pool al uso de “pools” (colección de recursos) para la gestión de memoría dinámica. ● Se utiliza con el objetivo de reducir la fragmentación de las funciones nativas (malloc, new) u obtener mejoras en la organización de la memoria (ej. jerarquía). 12 Motivación: CVE-2020-9273
  11. 11. ● Así que, ¿por qué no crear mi propio memory pool? 13 Motivación: CVE-2020-9273
  12. 12. 14 Motivación: CVE-2020-9273
  13. 13. La implementación de ProFTPd está basada en la de Apache HTTP server, y se estructura de forma jerárquica (de mayor a menor vida útil). Internamente, cada pool se organiza como una lista enlazada de recursos y dichos recursos son liberados de forma automática cuando se destruye el pool. 15 Motivación: CVE-2020-9273
  14. 14. ● Con el objetivo de reducir el número de “allocations” (malloc) ProFTPd reserva bloques de memoria de gran tamaño que se van añadiendo a la lista enlazada del pool. ● Cada vez que se realiza una llamada a pcalloc intenta satisfacerla con la memoria disponible en el ultimo elemento de la lista. Si se requiere más memoria que la disponible en el ultimo bloque, entonces hay que añadir un nuevo bloque como último elemento. • next • first_avail Memory pool • next • first_avail Memory • next • first_avail Memory 16 Motivación: CVE-2020-9273
  15. 15. ● Asimismo, se mantiene una lista de bloques libres para reducir el numero de “deallocations” (free). De este modo solo es necesario reservar memoria nueva cuando la lista de bloques libres se queda vacía. ● Pero, qué sucedería si la función new_block (encargada de devolver un nuevo bloque) nos devolviera un bloque que no está vacío… block_freelist • next • first_avail Memory • next • first_avail Memory 17 Motivación: CVE-2020-9273
  16. 16. ● La función “new_block” nos devuelve como vacío un bloque que ya se encuentra en el pool, corrompiendo la lista del pool • next • first_avail Memory pool • next • first_avail Memory • next • first_avail MemoryMemory 18 Motivación: CVE-2020-9273
  17. 17. ● Aquí podemos apreciar como dicho pool está totalmente corrupto: 19 Motivación: CVE-2020-9273
  18. 18. ● Aquí podemos apreciar como dicho pool está totalmente corrupto: 20 Motivación: CVE-2020-9273
  19. 19. ● Este tipo de errores son difíciles de detectar utilizando ASAN, dado que ASAN no cuenta con “interceptors” para las funciones de gestión de memoria del pool (ej. pcalloc) ● Por tanto, solo podremos detectar fallos derivados de estos (a menos que implementemos nuestros propios interceptors) ● En este caso se detectó un OOB write y un Null dereference durante el proceso de fuzzing (ambos provenientes del mismo UAF) 21 Motivación: CVE-2020-9273
  20. 20. 22 Motivación: CVE-2020-9273
  21. 21. Spot the bug! 23
  22. 22. Motivación: CVE-2020-9365 24
  23. 23. ● Se trata de un OOB-Read que afecta a la función pure_strcmp de Pure-FTPd ● Fue reportado el 24 de Febrero de 2020 ● El fallo se produce dado que dicha función da por supuesto que la longitud de ambos strings siempre será igual, aunque dicha premisa es totalmente falsa. 25 Motivación: CVE-2020-9365
  24. 24. ¿Cómo se han encontrado estas vulnerabilidades? 26
  25. 25. 27 FUZZING
  26. 26. Pero no este fuzzing… 28
  27. 27. 29
  28. 28. Fuzzing inteligente 30
  29. 29. ● El problema de encontrar todos los posibles bugs para un input de un tamaño dado, se puede modelar como un problema de búsqueda. ● Razonando un poco acerca de la complejidad del problema, para un archivo de entrada de tamaño 1KB, si quisiéramos probar todas las posibles combinaciones de bytes 256 ^ 1024 posibles combinaciones ● Por tanto, resultará imposible realizar una búsqueda por fuerza bruta sobre todo el posible espacio de búsqueda 31 Complejidad del problema
  30. 30. ● El problema de encontrar todos los posibles bugs para un input de un tamaño dado, se puede modelar como un problema de búsqueda. ● Razonando un poco acerca de la complejidad del problema, para un archivo de entrada de tamaño 1KB, si quisiéramos probar todas las posibles combinaciones de bytes 256 ^ 1024 posibles combinaciones ● Por tanto, resultará imposible realizar una búsqueda por fuerza bruta sobre todo el posible espacio de búsqueda 32 Complejidad del problema
  31. 31. 33 Mutation-Scheduling
  32. 32. ● Los fuzzers como AFL o Libfuzzer son de tipo evolutivo: un proceso iterativo que evoluciona los inputs de entrada con el tiempo ● La estrategia de selección de posibles candidatos puede ser muy variada y puede conducir a diferentes resultados 34 Mutation Scheduling
  33. 33. 35 Recorrido en profundidad
  34. 34. 36 Recorrido en anchura 887175 e515cd 3b479f 6ae6fb 1a76138e
  35. 35. Fuzzing evolutivo ≈ Recorrido de un árbol ● El proceso evolutivo de fuzzing se puede equiparar al proceso de recorrido sobre un árbol ● El nodo padre representa nuestro archivo de entrada inicial, y los hijos que cuelgan de cada uno de ellos son el resultado de las distintas mutaciones sucesivas. ● Sin embargo, el problema de “path explosion” nos impide recorrer todos y cada uno de estos paths (crecimiento exponencial) ● Es por tanto necesario aplicar una estrategia de selección heurística que ofrezca un equilibrio entre tiempo/resultados 37
  36. 36. American Fuzzy Lop (AFL) 38 AFL
  37. 37. ● AFL asigna una mayor cantidad de esfuerzo a aquellos inputs situados a mayor profundidad, con el objetivo de obtener inputs con mayor cantidad de mutaciones. 39 AFL
  38. 38. ● Implementado por Marcel Böhme (Monash University, Australia), se trata de una extension de AFL que introduce el concepto de power schedule ● Dichos power schedules gestionan la cantidad de esfuerzo dedicado en la generación de nuevos inputs a lo largo del tiempo de fuzzing ● Es importante hacer notar que dichos power schedules solo tienen influencia sobre las etapas de mutaciones no deterministas de AFL (havoc). 40 AFLFast
  39. 39. ● Entre los power schedules implementados por AFLFast Podemos encontrar: ○ Constante: Asignación de energía constante para cada nivel ○ Lineal: Incremento de tiempo lineal para ○ Exponencial: Incrementa de forma exponencial el tiempo de espera de aquellos ● Dicho de otro modo, un esquema “exponencial” será más similar a una búsqueda en anchura mientras que un esquema “lineal” será más incisivo y profundizará mucho más en el árbol. 41 AFLFast
  40. 40. 42 AFLFast
  41. 41. ● Podemos encontrar implementado todos estos power schedules en AFL++ ● AFL++ es un fork de AFL que se encuentra en desarrollo activo y que incluye gran cantidad de añadidos sobre la versión de AFL original ● Para hacer uso de los power schedules en AFL++ basta con hacer uso de la opción “-p [schedule]” ● Entre los schedules incluidos podemos encontrar: exploit, coe, fast, explore, quad o lin 43 AFL++
  42. 42. ● Se trata de un proceso heurístico, donde se emplean mutaciones no deterministas, por lo que no será posible obtener conclusiones que funcionen para todo software ● La elección de cada uno de los enfoques responde a: ○ A un método de ensayo/error ○ Experiencia práctica del humano ● Es en este punto donde se entremezclan el arte y la ciencia 45 Aviso
  43. 43. ● Se trata de un proceso heurístico, donde se emplean mutaciones no deterministas, por lo que no será posible obtener conclusiones que funcionen para todo software ● La elección de cada uno de los enfoques responde a: ○ A un método de ensayo/error ○ Experiencia práctica del humano ● Es en este punto donde se entremezclan el arte y la ciencia 46 Aviso
  44. 44. 47 Structure-aware-fuzzing
  45. 45. ● El nuevo vocablo de moda en el mundo del fuzzing Ciber-Resiliencia Sinergias BlockChain DataMining IoTMachine Learning 48 ¿Qué es?
  46. 46. 49
  47. 47. 50
  48. 48. ● Al uso de mutaciones personalizadas (custom mutators) en base al dominio de nuestros inputs ● Por ejemplo, podemos crear mutaciones en base a una gramática dada. 51 ¿Qué es realmente?
  49. 49. ● Al uso de mutaciones personalizadas (custom mutators) en base al dominio de nuestros inputs ● Por ejemplo, podemos crear mutaciones en base a una gramática dada. 52 ¿Qué es realmente?
  50. 50. ● Cuando analicemos un software con una arquitectura en pipeline ▪ No confundir con el paralelismo de instrucciones en los procesadores ▪ Nos referimos a una arquitectura de software “en- cadena” donde el output de cada uno los módulos es el input del siguiente módulo. 53 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  51. 51. ● Cuando analicemos un software con una arquitectura en pipeline Visión general de la arquitectura de GCC 54 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  52. 52. ● Cuando analicemos un software con una arquitectura en pipeline 55 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  53. 53. ● Cuando analicemos un software con una arquitectura en pipeline ▪ En estos casos, un error en el análisis léxico puede provocar que no se avance a la fase de análisis sintáctico. ▪ O un error en la sintaxis de nuestro input, provocará que no sea evaluado por el analizador semántico. 56 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  54. 54. ● Software con gran uso de variables / estados globales 57 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  55. 55. ● Software con gran uso de variables / estados globales ▪ Tiende a conducir a software con baja modularidad ▪ Las variables con gran alcance (scope) suelen incrementar la complejidad de un potencial análisis dado que hay más código que puede modificar el valor de las mismas 58 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  56. 56. ● Software con gran uso de variables / estados globales ▪ Tiende a conducir a software con baja modularidad ▪ Las variables con gran alcance (scope) suelen incrementar la complejidad de un potencial análisis dado que hay más código que puede modificar el valor de las mismas 59 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  57. 57. ● Tengamos que cumplir restricciones complejas ▪ Por ejemplo restricciones complejas en el orden de envío de los datos o en los tiempos de ejecución ▪ Un ejemplo de esto serían algunos protocolos de red o algunas APIs, donde es crucial el orden de la secuencia de peticiones 60 ¿Cuándo es útil utilizar structure-aware-fuzzing? 887175 e515cd 3b479f 6ae6fb 1a76138e
  58. 58. ● Tengamos que cumplir restricciones complejas 61 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  59. 59. Un ejemplo de Structure-Aware-Fuzzing bien utilizado https://github.com/googleprojectzero/fuzzilli 62 ¿Cuándo es útil utilizar structure-aware-fuzzing?
  60. 60. ● Cuando tengamos restricciones sencillas en el código (como checksums) ● Para dichos casos se antoja mucho más sencillo eliminarlos del código y después volver a re-calcularlo para dicho input 63 ¿Cuándo no es tan útil utilizar structure-aware-fuzzing?
  61. 61. ● Cuando tengamos un software altamente modular ● En dicho caso puede ser preferible descomponer el software en módulos más simples, y analizar dichos módulos por separado. 64 ¿Cuándo no es tan útil utilizar structure-aware-fuzzing?
  62. 62. DEMO TIME 65
  63. 63. 66
  64. 64. AFL + Diccionarios
  65. 65. AFL + Custom Mutator
  66. 66. AFL + Custom Mutator
  67. 67. 70 Protocol buffers: Es un formato creado por Google que permite serializar y representar información estructurada (archivos .proto) Un paso más allá
  68. 68. 71 Un paso más allá Al igual que en libFuzzer, podemos incluir libprotobuf-mutator en nuestro custom- mutator de AFL++. De este modo, es posible utilizar archivos .proto para definir la estructura de nuestro formato.
  69. 69. ● Independientemente del caso en el que lo utilicemos, siempre que hagamos uso de custom mutators estaremos acotando nuestros inputs y por tanto corremos el riesgo de perder casos límites ● Al final todo se reduce a priorizar entre profundidad y anchura del espacio de búsqueda 72 Structure-aware-fuzzing
  70. 70. 73 Domain-specific feedback
  71. 71. 74 Node coverage
  72. 72. 75 Node coverage
  73. 73. • Edge coverage: • LibFuzzer (método nativo de LLVM SanitizerCoverage) • AFL (almacenado en un bitmap de 64kb) • Complete path coverage • All possible states Edge Coverage Complete path coverage All possible states 76 Otros tipos de cobertura de código
  74. 74. Cobertura = { (0,1), (0,2), (1,2), (2,3), (2,4), (3,6), (4,5), (4,6), (5,4) } 77 Edge coverage (cobertura de arista) 1 2 3 4 5 6
  75. 75. • Edge coverage • Complete path coverage: • Requiere que todos los pasibles paths de ejecución sean cubiertos • Nos encontramos con el problema de los loops en el código • All possible states Edge Coverage Complete path coverage All possible states 78 Otros tipos de cobertura de código
  76. 76. Cobertura = { (0,1,2,3,6), (0,1,2,4,6), (0,1,2,4,5,4,6), (0,1,2,4,5,4,5,4,6), ... } 79 Complete path coverage (cobertura de camino competo) 1 2 3 4 5 6
  77. 77. • Edge coverage • Complete path coverage • All possible states: • Todas las posibles combinaciones de variables han sido probadas • Cada posible estado en memoria ha sido probado Edge Coverage Complete path coverage All possible states 80 Otros tipos de cobertura de código
  78. 78. Edge Coverage Complete path coverage All possible states INITIAL CORPUS FUZZER ● Idealmente, nuestro conjunto inicial de archivos debería de cubrir todas las lineas de código y una cantidad importante de execution paths (todas las funcionalidades del programa). ● El proposito de nuestro fuzzer es encontrar execution paths “extraños” y estados del programa que se salgan de lo previsto. Escenario de comienzo ideal
  79. 79. The CODE COVERAGE Is Not ENOUGH 82
  80. 80. Necesitaremos utilizar otros métodos de feedback para guiar a nuestro fuzzer a encontrar nuevos paths de ejecución… 83
  81. 81. ● FuzzFactory es una extension de AFL que evoluciona el concepto de coverague-guided fuzzing en el de domain-specific-guided fuzzing. ● Introduce el concepto de waypoints: inputs que no incrementan la cobertura de código de nuestro fuzzer, pero que maximizan alguna otra métrica dentro de nuestro dominio. https://github.com/rohanpadhye/FuzzFactory 84 FuzzFactory: Domain-Specific-guided fuzzing
  82. 82. Algunos ejemplos de domain-specific-feedback: ● Inputs que maximizan la longitud de los “execution paths” 85 FuzzFactory: Domain-Specific-guided fuzzing 887175 e515cd 3b479f 6ae6fb 1a76138e
  83. 83. Algunos ejemplos de domain-specific-feedback: ● Inputs que maximizan las reservas de memoría dinámica 86 FuzzFactory: Domain-Specific-guided fuzzing
  84. 84. Algunos ejemplos de domain-specific-feedback: ● Inputs que minimizan el numero de “asserts” negativos (evitan que el programa termine de forma prematura con un estado de error) 87 FuzzFactory: Domain-Specific-guided fuzzing
  85. 85. 88 Conclusión
  86. 86. 1. Cuando trabajamos con heurísticas siempre existe un factor de aleatoriedad, por lo que los resultados variaran para un mismo input. 2. Cualquier aproximación que nos permita profundizar en el espacio de búsqueda, tendrá un costo de perdida de casos límites (anchura), y a la inversa 3. El factor humano siempre marcará la diferencia a la hora de obtener resultados. 89 Conclusión
  87. 87. Menuda chapa os he pegado!! 90 Conclusión
  88. 88. 91 Reto Twitter
  89. 89. GRACIAS! Antonio Morales Maldonado Twitter: @nosoynadiemas Email: antoniomoralesmaldonado@gmail.com 92

×