En Nerdearla 2022 tuve el privilegio de dar dos charlas, una mía personal que más que un taller era una charla larga, una versión extendida de lo presentado en Flisol 2022 relativa a open hardware, cores y software y otra, en representación de mi trabajo, ésta si una charla de verdad, nacida de una combinación de necesidades y oportunidades, de la aplicación de ML a un problema de seguridad.
El proyecto expuesto trata de cómo hallar información sensible en diversos almacenamientos, en particular credenciales en texto plano en archivos de texto plano en sistemas de archivos utilizando técnicas de ML. Claramente todas estas ideas pueden extenderse otra información sensible en más tipo de archivos (pdf, documentos con formato, planillas) en diversos sistemas (repositorios, páginas web, comprimidos), pero no de modo sencillo ni automático.
Sin embargo, el aspecto que quiero destacar en esta entrada no es tanto el diseño técnico y la arquitectura del sistema, que vendrían a incluir aspectos como lidiar con diversos encodings, realizar la exploración en determinados horarios para no impactar en la disponibilidad de los sistemas a examinar, actualizar el modelo y las reglas de inclusión y exclusión de búsqueda tanto de archivos como de patrones de palabras clave de modo relativamente dinámico para poder aplicarlos durante la ejecución y no tener que esperar a que finalice, considerá que quizás estás recorriendo millones de archivos a lo largo de semanas. De este tema tengo muchísimo elaborado pero poco testeado y además no he revisado soluciones existentes para comparar.
Lo que me interesa y tema de esta entrada nace de esta frase:
"(A) Vinieron unos pentesters y revisaron en cierto lugar y (B) encontraron un archivo con una clave que aunque no era la actual mostraba el patrón de generación (C) lo cual permitió acceder a un sistema donde se encontraron otras credenciales.(D) Tenemos que hacer un control para prevenir esta situación".
Ok, nos gustaría mucho que no ocurra que hayan credenciales en texto plano en primer lugar, para ello existen técnicas de autenticación para evitar que hayan claves en los scripts y concientización para que no hayan claves fuera de los almacenes seguros tipo keepass, pero esto se trata justamente de detectar cuando alguien no las respeta.
Aunque a primera vista no lo parezca, el salto que hay desde (A) unos pentesters... a (D) hacer un control... es abismal y más si pasamos por (B) y (C), veamos el detalle y el contraste:
- El éxito de una campaña de pentesting se puede alcancar ante el primer hallazgo importante o cuando se alcanza al tiempo límite de ejecución asignado.
- Ésta campaña, aunque pueda tener mucha asistencia de automatización, es esencialmente manual e interactiva, no hay foco en optimizar aspectos como que un humano no tenga que revisar más de 5.000 líneas, por decir un número para mí razonable. Esto significa que:
- si el humano se tiene que pasar una tarde mirando una lista de 100.000 líneas candidatas, lo va a hacer.
- La búsqueda no es exhaustiva, se pueden buscar archivos con nombres clave tipo "claves.txt", con hallar uno alcanza.
- La frecuencia puede ser tal que sea una o dos veces por año, quizás cada dos años.
Contrastemos con un control:
- La ejecución del control se completa cuando recorre todo el conjunto de activos a revisar y emite su reporte, el cual puede ser contínuo, no hace falta que sea al final.
- El éxito se alcanza cuando recorre todo y halla todo lo que podría hallar.
- Debe ser esencialmente automático, el humano sólo debería intervenir para una decisión final acerca de los positivos y realimentar la lógica.
- En mi experiencia, completamente personal, no debería examinar más de 10.000 líneas. Y pensá que esto hay que repetirlo periódicamente, es esencial que sean pocas líneas.
- Debe ser permanente, no bien termina de ejecutarse debe comenzar otra vez.
- Considerando (B) clave pista y (C) que conduce a otro lado, esto es imposible en un control, se hace indispensable la intervención humana.
Esta intervención puede pasar a formar parte del control, pero hay que tener en cuenta que pueden haber mucho "candidatos", una cosa es mirar rápido y ver que "let password = "3234234" amerita contactar al dueño del sistema y otra es que cuando el dueño te contesta "esa clave no se usa más" confiar y seguir escarbando.
Otra es, si el hit fué "let password = $texto", tendrías que ir a ver dónde y cómo se definió $texto, pudo haber sido
let texto = "3234234"
que es un nivel de indirección que nuestro análisis difícilmente pueda interpretar, o peor aún:
let password = exec("proceso.exe", "id_sistema")
donde proceso.exe puede ni siquiera estar presente en el sistema que estamos examinando. No pongo las manos en el fuego pero consideraría esta una técnica válida, esa línea la encontraste en un repositorio y proceso.exe sólo existe en el sistema productivo donde se ejecutará el código.
Existen herramientas de análisis estático de código que son
capaces de seguirle el rastro a una cadena de asignación de valores
dentro del flujo de un programa, sólo sería cuestión de activarla cuando se detecta que es código fuente, pero bueno, es una complejidad adicional.
En síntesis, la idea está en concordancia con el concepto de la asimetría que hay entre atacante y el defensor, el EH respeta la visión del atacante y el Control la del defensor:
- El atacante tiene toda la ventaja del tiempo, es lo único que hace.
- El atacante tiene toda la ventaja de concentrarse en un único conocimiento, el de tal ataque en particular, mientras el defensor debe abarcar de modo obviamente superficial todo el conocimiento de todo lo que defiende.
- Al atacante le alcanza con un éxito y en última instancia no importa mucho cómo lo consigue.
Entonces la idea es, no sencillo en general modelar un control a partir del resultado de un reporte de EH y en particular en el caso de la frase, probablemente imposible.