Este artículo es la tercera y última entrega de la serie Sysmon Threat Analysis. Todas las demás partes de la serie:
Parte 1. Introducción al análisis de registros de Sysmon
Parte 2. Uso de datos de eventos de Sysmon para identificar amenazas
Parte 3. Análisis en profundidad de las amenazas de Sysmon mediante gráficos (estamos aquí)
Búsqueda de subgrafos no estándar con datos de eventos de Sysmon (ejemplo simple)
Antes de ver un ejemplo de identificación de anomalías en subgrafos que indican una amenaza potencial (y si estas palabras no despiertan al nerd que hay en ti, ¡nada te despertará!), Hagamos una pequeña digresión.
En este punto, debo emitir una advertencia: esta publicación, junto con el código en GitHub, no puede reemplazar una solución de nivel empresarial. Se puede ayudar a identificar las amenazas en una escala más pequeña, pero mi noble misión es ayudar a los profesionales de seguridad de entender y apreciar las soluciones del mundo real de protección contra amenazas. Y una forma de lograrlo es crear su propia solución usted mismo (con mi ayuda).
Los experimentos en casa lo ayudarán a comprender lo difícil que es escalar el software de detección de amenazas de bricolaje. Tienes que trabajar con grandes conjuntos de datos y todo lo relacionado con ellos: limpieza (que es una tarea extremadamente difícil), procesamiento eficiente (encontrar las estructuras de datos, algoritmos, etc.) y proporcionar resultados con un número bajo de falsos positivos para que tu los mismos compañeros entonces no se subieron a ti con los puños. Con esto en mente, puede considerar una solución preparada para detectar amenazas ... pero solo después de completar nuestra serie de artículos y realizar sus propios experimentos.
Configuración de pesos de gráficos
Una forma sencilla de crear una solución de defensa contra amenazas que no dependa de firmas de malware es utilizar el gráfico de amenazas de la parte anterior .
Dicho gráfico conecta los nodos de proceso en función de las entradas del registro de eventos de Sysmon.
Tenga en cuenta: no separé cada evento de inicio de proceso (ID de evento 1 en eventos de Sysmon) en un nodo separado. En su lugar, creé un gráfico más abstracto que muestra, digamos, el vértice de PowerShell tiene un enlace a cualquier aplicación que inicie desde cualquier usuario: un enlace para Excel, uno para el navegador, y así sucesivamente.
La vista de árbol de PSQuickGraph de mi gráfico de amenazas Sysmon. Preste atención a la rama anómala en cmd.exe
Sin embargo, aún queremos realizar un seguimiento de la frecuencia de los procesos en ejecución. Por ejemplo, si PowerShell lanzó "whoami" 1 vez y el editor de Windows obsoleto "Notepad.exe" 10 veces, entonces los bordes del gráfico que van desde el vértice de PowerShell deben marcarse con los "pesos" correspondientes de 1 y 10, respectivamente. Es lógico
En muchos de los algoritmos de detección de amenazas más simples, este peso se convierte en una métrica para comparar las regiones del gráfico. El punto principal es que un subgrafo con un peso promedio más bajo en comparación con el peso promedio general es sospechoso.
¿No lo es? La cumbre poco visitada es una zona anómala. Por lo tanto, si las acciones del usuario en el análisis de amenazas potenciales van hacia un subgrafo que se usa con poca frecuencia, debe elevar el nivel de alarma a amarillo.
El enfoque que describo y los scripts de PowerShell a continuación no están destinados a ser utilizados con fines prácticos para grandes infraestructuras. Pero para un servidor separado, la solución puede funcionar, o al menos proporcionar una verificación independiente de las soluciones corporativas que utiliza.
¿ Mencioné que los algoritmos PowerShell de Doug Finke para estructuras de datos son herramientas excelentes y poderosas? Sin su trabajo, no habría logrado nada en mi proyecto de gráfico de anomalías. ¡Gracias de nuevo, Doug!
Con la ayuda de su biblioteca PowerShell de hermosas funciones gráficas, puedo calcular fácilmente el peso de mi gráfico de amenazas Sysmon con solo unas pocas líneas PS, y también averiguar el peso promedio de vértice para todo el gráfico. A medida que atraviesa el gráfico, el código también asigna a cada vértice el peso de todos sus bordes salientes:
$AW=0 #average weight
$GW=0 #total weight
$mset = [System.Collections.ArrayList]@() #master set of subraphs
#calculate total weight by summing up the frequencies or weights of the edges
foreach ($e in $g.getAllEdges() ) {
$GW = $GW + $e.weight
}
write-host "Weight of Graph: " $GW
$AW = $GW / $g.vertices.count
write-host "Average weight per vertex: " $AW
#assign weight of edges to vertice
for ($i=0; $i -lt $g.vertices.count; $i++) {
$w=0
$v=$g.vertices[$i]
foreach($e in $v.getEdges()) {
if($e -eq $null) {continue}
$w=$w + $e.weight
}
$v.value.Weight = $w
}
El código anterior hace los cálculos que necesitamos. En este caso, cada vértice puede considerarse como la frecuencia de visitas, en función de los bordes de salida.
La parte más difícil de mi script de gráfico de anomalías de PowerShell, que le mostraré en breve, es encontrar las regiones del gráfico que tienen menos probabilidades de ocurrir y luego encontrar el subgráfico más grande que las contiene . Es posible que deba hojear un libro antiguo de informática para completar esta tarea. ¡Pero en realidad no es tan difícil de escribir!
Utilicé la búsqueda clásica Breadth First para mi gráfico visitando cada vértice y luego expandiéndolo a expensas de los vértices vecinos hasta que mi subgráfico alcanza un cierto umbral dependiendo del peso promedio del vértice. Me gusta esto:
function extend-subgraph($v, $t) {
$vertexQueue = New-Object Queue
#initialize
$vertexQueue.enqueue($v)
$h=$v.value.Weight
$s=@() #subgraph
$s+=$v
$extend=$false
while (!$vertexQueue.isEmpty()) { #bfs
$currentVertex = $vertexQueue.dequeue()
$es= $currentVertex.getEdges()
foreach($e in $es) {
$ev= $e.endVertex
if ((($h + $ev.value.Weight)/($s.count+1) -lt $th) {
#extend the sub-graph
$s+=$ev
$h =$h + $ev.value.weight
#queue it up
$vertexQueue.enqueue($ev)
}
}
Una nota rápida para los aficionados al bricolaje: utilizar el ArrayList tipo para crear una matriz de matrices y usted se ahorrará muchos dolores de cabeza.
Amenazas y subgrafos de bajo peso
Hay muchos algoritmos diferentes para gráficos anómalos. El que utilicé se basa en cierto graphBAD que encontré en Internet, y daré un enlace tan pronto como lo encuentre de nuevo.
En general, el principal problema en la detección práctica de amenazas es encontrar un buen conjunto de datos para formar una línea de base. Como blogger a tiempo completo y especialista en detección de amenazas en fiestas, nunca logré crear un registro de Sysmon lo suficientemente interesante que contenga muchas aplicaciones diferentes. Fue bastante difícil generar subgrafos anómalos ya que no tenía una distribución de pesos lo suficientemente grande. De una forma u otra, al usar un servidor real, puede terminar con un conjunto de datos mucho mejor que el uso ocasional de una instancia de AWS Windows, como en mi caso.
El script PS de gráficos anómalos que escribí dio bastante subgrafos sospechosos con pesos promedio bajos. E incluso logré captar algunos entornos interesantes (ver más abajo).
Algoritmo de pesos de subgrafo en acción: Entorno interesante con bajo peso del subgrafo 7
Como mencioné anteriormente, existen otros algoritmos para detectar anomalías en gráficos con métricas distintas de los pesos simples que vale la pena aprender. Uno de ellos busca grupos de vértices "similares" y advierte conexiones o conexiones entre diferentes entornos. En este caso, la anomalía radica en el usuario o proceso que conecta entornos a través de alguna otra característica. Tiene sentido, ¿no?
Si tu nerd interior es fuerte en ti, puedes consultar SCAN(Algoritmo de agrupamiento estructural para redes), que hace lo anterior. Junto con los algoritmos PowerShell de Doug Finke, incluso puede usarlo. Yo mismo quiero asumir este proyecto y publicarlo pronto en mi GitHub .
Encuentra anomalías a través de paseos aleatorios
Terminemos esta sección con otra forma de encontrar anomalías en el gráfico de amenazas. Me referí a este enfoque al final de la parte anterior . Para mí, como persona con las matemáticas en el "tú", es más intuitivo. Y los fanáticos de los viejos programas de televisión entumecidos reconocerán inmediatamente el concepto de [aclarar la garganta] cadenas de Markov.
Para todos los demás, puede pensar en esto como un "recorrido aleatorio" a través del gráfico. En cada uno de los vértices, tiramos un dado y seleccionamos un borde del gráfico en función de su peso: cuanto mayor sea el peso del borde, mayor será la probabilidad de que lo sigamos. Debe dividir el gráfico en dos partes (en teoría de grafos se denomina gráfico bipartito) con los usuarios en una parte y las aplicaciones en la otra.
A continuación, clasificastodas las aplicaciones de vértice a las que puede acceder el usuario en función de la probabilidad de alcanzar un vértice particular. Para analizar la amenaza, buscará aplicaciones en ejecución y, si alguna de ellas tiene una probabilidad muy baja de alcanzarlas, es posible que haya encontrado una amenaza real.
Más un karma para alguien que lo vinculó al algoritmo PageRank de Google. Describiré esto con más detalle en la siguiente sección, pero los interesados pueden buscar en Google la frase caminata aleatoria con reinicio .
Teoría de recorrido aleatorio y práctica de EQL
Tomemos otra digresión y analicemos lo que estamos tratando de lograr con el registro de Sysmon, que es una gran herramienta para detectar amenazas y realizar investigaciones posteriores al incidente.
- , Sysmon. Sysmon , .
- 2 Sysmon , , .
- En la tercera parte, profundizamos en una descripción general de un algoritmo simple que considera las conexiones de borde como pesos. Las secciones de un gráfico que pesan menos (en términos de bordes) que el peso promedio total en todo el gráfico pueden ser una amenaza potencial. Voy a subir los scripts de PowerShell de los algoritmos de esta sección a mi GitHub (después de pasar el cursor sobre ellos).
La ventaja de estos métodos es que no dependen de comandos específicos o nombres de procesos que los atacantes cambian o enmascaran constantemente.
Además, existe otro método basado en la probabilidad para encontrar vulnerabilidades. Echemos un vistazo más de cerca.
Recorrido aleatorio de un gráfico de vulnerabilidades a partir de datos basados en eventos de Sysmon
En lugar de analizar la estructura del gráfico en sí, podemos pensar en las conexiones como una especie de ruta o hoja de ruta, en la que cada aplicación es una parada separada en el camino. A partir de los datos de registro de Sysmon, podemos obtener la frecuencia con la que se inicia cada aplicación desde su padre.
Si observa mi script de gráfico de amenazas en GitHub, encontrará que esta frecuencia se almacena dentro de cada objeto de borde utilizando los maravillosos algoritmos PowerShell de Doug Finke.
¡Podemos considerar la frecuencia de cruzar cada uno de los bordes del gráfico de vulnerabilidad como una probabilidad!
El siguiente paso es usar esta información para encontrar la probabilidad de, digamos, iniciar una aplicación de PowerShell taskmgr.exe, un analizador de procesos de Windows, un bloc de notas o hostname.exe.
¿A qué me refiero?
En resumen: puedo crear una matriz de transición de probabilidad, tan querida por los seguidores de Markovy de uso común en sistemas de modelado. De hecho, tirar los dados, pasar a la siguiente aplicación del gráfico y repetir estas acciones es un recorrido aleatorio del gráfico. En última instancia, este método matemático clasifica cada vértice del gráfico de acuerdo con la probabilidad de llegar allí desde el punto de partida. Y descubrirá que, por ejemplo, el lanzamiento de hojas de cálculo desde el Explorador de Windows es un proceso extremadamente común, y el motor de host de Windows Script es, en teoría, extremadamente no estándar y, en consecuencia, potencialmente un indicador de amenaza.
Este método se conoce como Random Walk With Restart (en adelante, RWWR, caminata aleatoria con reinicio) y es una variación del ahora legendario algoritmo de clasificación de PageRank de Google.
Echemos un vistazo a un fragmento de script que escribí para calcular estos rangos:
#lets build a row
$row= @(0)*$g.vertices.count
$w=0
foreach($e in $start.getEdges()) { #calculate total frequency
$w+=$e.weight
}
if ($w -eq 0) { #make it connected
$row[$ix] =1
}
else { #we assign probabilitys
#now create transition probability
foreach($e in $start.getEdges()) {
$ev = $e.endVertex
$p = $e.weight
$jx = v-index $ev.value.Key
$row[$jx]= $p/$w #normalize by dividing by total
}
}
$P[$ix] = $row #yay! One row added to transition matrix
Para cada vértice, calculo la frecuencia resultante de todos los vecinos y luego asigno la probabilidad de cada transición a través de la normalización por el total. Por lo tanto, si PowerShell.exe tiene 20 visitas a todos sus vecinos, pero nc.exe solo se ha visitado una vez desde la parte superior de PowerShell.exe, entonces la probabilidad de que vaya será 1/20 o 0.05. Es lógico
La dificultad radica en calcular la matriz utilizada en RWWR, pero para quienes hayan asistido a lecciones de modelado probabilístico, este procedimiento no será difícil. Hay un buen artículo de revisión sobre este tema en el sitio web de Medium .
Mi script, al que llamo evaluador aleatorio , clasifica y genera los 10 valores más pequeñosvalores de la lista. De esta manera, puede obtener aplicaciones que tienen la menor probabilidad de ser lanzadas, comenzando desde un vértice dado del gráfico de amenazas. Este es el resultado al usar PowerShell.exe como punto de partida:
El algoritmo Random Walk With Restart puede producir una clasificación de amenazas similar a la de Google. Hmmm, whoami es el que tiene menos probabilidades de ejecutarse.
Como nota práctica y advertencia, vale la pena señalar que PWWR será un problema de big data en un sistema real. Incluso en el caso de mi pequeño registro de Sysmon, el retraso de cálculo fue bastante notable debido a la gran cantidad de operaciones de punto flotante.
Lenguaje de consulta de eventos (EQL) para análisis de amenazas
Por ahora, vale la pena señalar que los proveedores que utilizan enfoques más sofisticados para detectar amenazas en sus productos van mucho más allá de lo que usted o yo podemos hacer por su cuenta. Y, definitivamente, con mucha mayor precisión.
Para aquellos que quieran sumergirse en el tema de la detección de amenazas, pero no quieren trabajar con mis scripts, ¡lo entiendo! - hay Event Query Language , o EQL . Es un proyecto de código abierto para aplicar el lenguaje de consulta de registros de Sysmon, sobre el que puede obtener más información en la publicación extremadamente completa.... EQL no solo es excelente para investigar incidentes, sino que también se puede utilizar como herramienta siempre que tenga una copia nueva del registro de Sysmon.
La suite EQL proporciona un controlador de eventos que convierte el registro en JSON legible por humanos. Puede consultar una copia de mi rama en GitHub. A diferencia de mi secuencia de comandos PS estática show-amenaza-ruta , EQL le permite realizar consultas sobre la marcha.
Digamos que estoy interesado en todos los shells de cmd.exe que se iniciaron en nombre de scvhost.exe; esto puede ser una señal del uso de psexec.exe o smb.exe por parte del atacante. La solicitud se verá así:
Usando EQL para encontrar shells cmd.exe iniciados desde svchost.exe. Por cierto, jq es una utilidad de Linux para mostrar datos JSON.
Existe una forma aún más genial y poderosa de obtener este resultado usando el modificador secundario. Esta consulta EQL le permite buscar en todos los procesos con un antepasado específico, en cualquier lugar de la jerarquía. Por ejemplo, puede buscar aplicaciones que, digamos, tuvieran el proceso regsvr32.exe como antepasado y podrían aprovechar una vulnerabilidad conocida que describí aquí .
Hay mucho que decir sobre EQL en esta publicación ya larga, así que prefiero publicar un artículo separado sobre los detalles de las habilidades de EQL para encontrar vulnerabilidades.
Reflexiones finales sobre las soluciones de detección de amenazas de bricolaje
Prometí descargar el repositorio de Sysmon con todos los scripts de detección de amenazas descritos en este artículo. Vuelva a consultar mi GitHub periódicamente, ya que agregaré nuevas herramientas de detección de amenazas basadas en gráficos a lo largo del tiempo, junto con documentación adicional, demasiado para cubrir en un artículo.
Llegaste a este lugar, ¡felicitaciones!
Pruebe mis scripts o utilícelos como base para desarrollar sus propias ideas de detección de amenazas. PowerShell es adecuado para algoritmos complejos. Para mí, que crecí en el lenguaje shell de Linux, fue una agradable sorpresa trabajar con un lenguaje de scripting maduro. Y le aconsejo que consulte la Galería de PowerShell, otro gran recurso para scripts de batalla listos para usar: no tiene que reinventar la rueda en el mundo de PowerShell.
Otra conclusión más importante de todo el artículo será la comprensión de que los proveedores de soluciones de nivel empresarial no solo utilizan tecnologías de detección de amenazas mucho más sofisticadas que las que un desarrollador de TI puede escribir en su tiempo libre, sino también la adaptabilidad de estas soluciones para trabajar con el nivel de tráfico. gran organización. Por supuesto, es una buena idea usar soluciones de bricolaje para analizar un servidor infrautilizado o una validación adicional de productos empresariales. Pero la inteligencia e identificación de amenazas es de hecho un problema de big data y, obviamente, no es un desafío que PowerShell pueda resolver.
Si está interesado en la oportunidad de aprender más sobre cómo Varonis maneja la tarea de analizar y detectar amenazas, siempre puede solicitar una demostración personal .