Resumen
- Censys son increíblemente ricos en detalles que a menudo pasan desapercibidos sin un ojo experto. Esta guía destaca el valor de estos datos altamente estructurados y ofrece información sobre cómo los utilizamos internamente para encontrar infraestructuras sospechosas.
- Estamos lanzando una utilidad gratuita llamada Censeyeque puede descubrir pivotes útiles en los datos de hosts de Censys y (opcionalmente) rastrear hosts relacionados utilizando los datos de esos descubrimientos.
Pivotar para obtener beneficios
Después de años trabajando con datos de Censys , notas patrones que se acercan al análisis de Internet. A lo largo de muchas investigaciones, su caja de herramientas crece y se llena de nuevas utilidades, terminología y técnicas que le ayudan a pasar sin problemas de una pista a otra. Ya se trate de identificar un programa informático nunca visto antes o de rastrear de forma proactiva la infraestructura conectada a Internet de un presunto delincuente, a menudo todo empezó con un único hilo: una pista que, al tirar de ella, empezó a desentrañar una historia más amplia.
Es posible que a menudo veas hosts de aspecto extremadamente genérico con sólo un puñado de servicios que sólo a veces son lo que parecen; cuando se contrasta con la totalidad de Internet, muchos de estos hosts son, de hecho, razonablemente únicos. Tomemos como ejemplo la siguiente respuesta HTTP:
HTTP/1.1 200 OK
Date: <REDACTED>
Server: Apache/2.4.41 (Ubuntu)
Content-Length: 0
Content-Type: text/html; charset=UTF-8
A primera vista, se trata de una respuesta HTTP típica de un servidor web Apache ejecutado en Ubuntu. Si filtramos los hosts por el valor exacto de la cabecera Server, encontramos más de 420.000 hosts con la misma configuración, lo que no esmuy excepcional. Sin embargo, cuando analizamos toda la respuesta utilizando un hash SHA-256 y limitamos nuestra búsqueda al puerto 80, esas 420.000 coincidencias se reducen a sólo 1.961 resultados.
Esto también ocurre a la inversa: algo que parece único suele ser bastante genérico. Las huellas dactilares JARM se utilizan a menudo como indicadores de tipos específicos de malware, pero la realidad es que esas huellas dactilares no representan al malware en sí, sino a la API TLS subyacente sobre la que se ejecuta el malware. Así que cuando te dan una huella digital JARM de un supuesto servidor malicioso y ves que coincide con decenas de miles de hosts en ejecución(como Metasploit JARM), debes tomarlo con cautela.
El punto general es que el diablo está en los detalles con respecto a los datos de escaneo de Internet. Cuando se encuentra algo muy específico en un número limitado de hosts, a menudo (pero no siempre) significa que se puede establecer una conexión. Pero identificar esas cosas muy específicas puede ser un reto, y es fácil pasar por alto algunas cosas que nuestros cerebros están acostumbrados a ver.
Un ejemplo de algo muy singular que podría verme fácilmente pasando por alto sin otro contexto es este certificado TLS:
Si descorremos un poco más la cortina, veremos que la organización "Microsoft IT" no se encuentra cerca de una red propiedad de Microsoft, e incluso hay cuatro servicios Cobalt Strike verificados (en dos hosts) que presentan un certificado "Microsoft IT".
"Parece interesante", puede que se diga a sí mismo, y haga clic en los detalles del host para buscar otros hosts con el mismo título HTML, sólo para encontrarse con dos hosts coincidentes en el mismo ASN pero en subredes diferentes:
Así que ahora nos preguntamos qué demonios es "nmps" y por qué sólo se encuentra en dos hosts, uno de los cuales es obviamente malicioso. Así que, de nuevo, abrimos la página de detalles del host y miramos todo el cuerpo de la respuesta para averiguar qué es esta cosa, ya que buscar "nmps" en la web sólo nos permite saber que "New Mexico Professional Surveyors" es aparentemente una cosa:
Aún así, ninguna información buena aquí me ayudaría a concluir qué es "nmps". El HREF parece estar truncado o quizá corrupto, así que tomamos un fragmento del cuerpo y lo pegamos en GitHub para ver si forma parte de un proyecto de código abierto, concretamente el texto "404 not found,power by":
Y ahora tenemos una respuesta. "nmps" es una bifurcación de "nps", que es (cito) un "servidor proxy de penetración de intranet ligero, de alto rendimiento y potente" y, a juzgar por las estadísticas del repositorio, muy conocido.
Ahora que un host con "nps" no ejecuta Cobalt Strike, 47.108.57.1, empieza a parecer mucho más sospechoso con esta nueva información. Si nos dirigimos a VirusTotal y buscamos la IP, vemos que 14 proveedores han marcado esta IP como maliciosa:
En la pestaña de la comunidad del resultado VT, varios usuarios informaron de que se había encontrado una baliza Cobalt Strike en el puerto 80 hace sólo 19 días:
Para verificarlo, miramos los datos históricos asociados a ese host y descubrimos que, sí, hasta alrededor del 26 de octubre de 2024, existía, de hecho, una baliza Cobalt Strike en este host, al igual que el otro servidor con ese error "NPS" en la actualidad.
Lamentablemente, los datos de escaneado de Internet no pueden decirnos con seguridad si estos dos hosts están relacionados, pero sí sabemos que, con unos pocos pivotes, pudimos identificar una infraestructura maliciosa desconocida hasta entonces.
Informes y automatización
Esta es una tarea que acabamos haciendo a menudo en Censys: utilizar una entrada sospechosa para encontrar más cosas que parezcan igual de sospechosas. Y si no sabes qué campos específicos de nuestros datos son adecuados para pivotar, entonces esta tarea puede ser bastante engorrosa cuando se hace manualmente. Pero pivotar es el rey. Así que nos pusimos a automatizar algunas de estas sencillas tareas para utilizarlas internamente, lo que resultó ser muy útil, tanto que hemos decidido poner estas herramientas a disposición de toda la comunidad de Internet.
Censys Los datos del escáner son lo que yo consideraría "altamente estructurados", en el sentido de que cada parte de la información está dividida en sus propios campos individuales: una cosa se ramifica en otra formando un árbol jerárquico, que permite entender la propiedad de un elemento a otro. Este formato estructurado se presta muy bien a pasar de un dato a otro.
Presentación de "Censeye": una herramienta de información autopivotante
Censeye es una herramienta basada en terminal que desarrollamos en el transcurso de unas semanas y que comenzó con una premisa sencilla: tomar un único resultado de host estructurado y, para cada campo, decirme cuántos otros hosts de Internet tienen lo mismo. Para lograrlo, simplemente analizamos un resultado de escaneo y generamos una expresión CenQL para todos los pares clave/valor. A continuación, para cada consulta generada, ejecutamos un informe agregado en el que el campo de desglose era el número de IP. El objetivo era encontrar pivotes interesantes que podríamos haber pasado por alto al examinar manualmente un host.
Rápidamente nos dimos cuenta de que no todos los términos de búsqueda eran buenos para encontrar pivotes, así que empezamos a crear una lista de términos permitidos para la generación de informes. También añadimos una lógica sencilla que empezaría a resaltar términos de búsqueda específicos que parecieran conducir a cosas más prometedoras. Por ejemplo, si una clave/valor se encuentra en varios hosts pero es inferior a un máximo configurable, queríamos que esos términos de búsqueda estuvieran en primer plano. A continuación se muestra la salida por defecto de un informe generado para la dirección IP "114.55.250.233".
Aquí, vemos una tabla con tres columnas - la primera columna es el número de direcciones IP únicas que coincidieron con la clave de la columna 1 con el valor de la columna 2. Las filas en negrita muestran los términos de búsqueda que tuvieron más de una pero menos de (por defecto) 120 coincidencias. Por último, muestra todos los términos de búsqueda "interesantes" que se encontraron por el camino. Si el terminal lo admite, todos los datos mostrados son interactivos y le llevarán al resultado de búsqueda Censys para ese elemento específico.
Hay alguna manipulación adicional que se realiza en el backend para cada entrada; por ejemplo, algunos de los resultados TLS generarán en realidad varios informes de diferentes maneras:
- Un informe sobre la clave/valor TLS exacto: services.tls.certificates.leaf_data.subject.common_name: "ejemplo.com"
- Otro informe buscando (no services.tls.certificates.leaf_data.subject.common_name: "ejemplo.com") y "ejemplo.com"
Se trata de tomar un nombre de host del certificado y ver si aparece en algún otro lugar de Internet.
En resumen, el flujo de trabajo de Censeye consiste en un proceso de seis pasos. Partiendo de una dirección IP de entrada, el sistema recupera los datos del host de Censys, extrayendo y refinando los pares clave-valor de los detalles del servicio para conservar sólo los campos más relevantes. Se genera un informe agregado a partir de Censys para cada par clave-valor seleccionado, en el que el recuento de direcciones IP sirve como métrica de desglose. A continuación, se aplica un umbral semi-único para identificar los "términos de búsqueda interesantes". Si se especifica un parámetro de profundidad, la utilidad obtiene una lista de hosts coincidentes, extrae sus direcciones IP y las reutiliza como entrada en el paso inicial. Este ciclo se repite hasta que el contador de profundidad llega a cero. Nada del otro mundo.
El mecanismo de informes sin sentido ha demostrado ser increíblemente útil por sí mismo, ya que hemos encontrado muchas cosas nuevas que podríamos haber pasado por alto sin él. De hecho, un caso de uso cotidiano para nosotros es alimentar hosts que ya han sido etiquetados como servidores de comando y control (c2) para encontrar conexiones a otros hosts que no etiquetados como "c2". En otras palabras, preguntamos si hay servidores C2 conocidos que tengan enlaces con infraestructuras desconocidas.
Por defecto, Censeye leerá de stdin, por lo que es fácil utilizar otras herramientas, como el CLI Censys , para sembrarlo con hosts. En este caso, queremos buscar hosts que ya estén etiquetados como "c2", pero al generar los informes de hosts para cada campo, excluir cualquier host etiquetado como "c2" de los totales. Esto se hace con la opción"-query-prefix":
~$ censys search 'labels=c2' | \
jq '.[].ip' | \
python censeye.py --query-prefix 'not labels=c2'
Para cada una de las IP de entrada, se genera el mismo informe tabular:
Puede observar que varias de estas filas tienen un recuento de hosts igual a cero; esto se debe al argumento de prefijo de consulta que establecimos anteriormente: esto nos indica que esas filas sólo se encontraron en hosts que ya tienen la etiqueta "c2" aplicada, lo que nos deja con tres términos de búsqueda "interesantes" que se encuentran en hosts que no son c2:
Ya que estamos con el tema de los certificados, cuando Censeye ve una huella digital de un certificado TLS que se encuentra en un único host (lo que significa que el certificado sólo se ha visto en el host que está viendo), intentará determinar si ese certificado se ha visto en algún otro host en el pasado y, si es así, esa información estará disponible. Tomemos como ejemplo este supuesto servidor MoonBounce C2:
Este certificado solo se observa en este host actualmente, pero ha aparecido en más de 17 hosts diferentes desde 2020. El informe principal también destaca esto mostrando el número de hosts históricos (únicos) entre paréntesis. Se trata de una forma rápida de determinar si un certificado solitario en un host se ha visto antes en algún otro lugar. Debe tenerse en cuenta que el historial, y lo lejos en el pasado que se puede ver, está ligado a los niveles de permiso de su cuenta.
Como ya indicamos lo que consideramos términos de búsqueda "interesantes" y tenemos una lista estricta de campos que seguirá, con limitaciones sobre la cantidad de datos que podemos extraer, tenemos suficientes barandillas para permitir que la herramienta trabaje de forma independiente. Así, en lugar de obtener un único informe, consultar los resultados de los términos de búsqueda encontrados y, a continuación, ejecutar más informes basados en esas búsquedas, puede indicarle a Censeye que lo haga por usted.
Para ilustrar esto, veamos una única dirección IP(5.188.87.38) que se ha visto recientemente actuando como servidor C2 para el ladrón de información Stealc. Si vemos el host en Censys, veremos que no parece haber mucho que hacer:
A pesar de esto, cuando se ve bajo Censeye, podemos ver inmediatamente que el servicio SSH en el puerto 22 tiene una huella digital que coincide con otros 45 hosts.
Podemos hacer clic en esto manualmente y buscar nosotros mismos, o podemos suministrar una nueva bandera que le dice a la herramienta para generar informes sobre todos los resultados de los "términos de búsqueda interesantes". Censeye puede actuar como una especie de rastreador: con una profundidad de cero (la predeterminada), sólo mostrará los informes sobre el host consultado. Sin embargo, si aumentamos esta profundidad, la herramienta buscará hosts coincidentes para los "términos de búsqueda interesantes" que encontró en el host original y ejecutará el mismo proceso de informes en ellos.
Aquí, modificamos nuestros argumentos originales con "-depth 1". Para cualquier "término de búsqueda interesante" encontrado en 5.188.87.38, la herramienta obtendrá una lista de hosts que coincidan y generará el mismo informe para cada uno. Como ya hemos visto que el único término de búsqueda compartido en este host es la huella digital SSH, a esta profundidad, la herramienta sólo mostrará información sobre los otros hosts que ejecutan esta misma huella digital.
La salida ahora es un poco diferente; nos encontramos con muchos más informes tabulares para todos los hosts coincidentes, pero esta vez, tenemos un nuevo resultado que muestra el "árbol pivotante", que es una representación visual de los hosts que descubrimos y cómo la herramienta llegó allí.
En la salida de arriba, vemos varias direcciones IP nuevas, todas ejecutando la misma huella SSH que nuestra IP original, 5.188.87.38. También notaremos que ahora tenemos dos "términos de búsqueda interesantes" mostrados en la parte superior, uno es la huella SSH original usada para descubrir estos hosts y una segunda huella SSH (semi) única, 6278464b, ejecutándose en siete hosts diferentes, incluyendo un único host, 179.60.149.209.
Si observamos este nuevo host en Censys, veremos que la huella SSH original se ejecuta en el puerto 22, mientras que esta nueva huella SSH (junto con otros siete hosts) está vinculada al puerto 2222.
Así pues, avancemos un poco y establezcamos nuestro valor "-depth" en '3'. Esto significa que la herramienta intentará encontrar términos de búsqueda interesantes en Censys en tres iteraciones. Todos estos hosts tienen una o más conexiones con el padre; en este caso, un montón de huellas SSH compartidas.
En el ejemplo anterior, 193.29.13.183 ejecutaba la huella SSH bd613b3b, la misma que el puerto 22 en 185.232.67.15. El host 185.232.67.15 también ejecutaba 6278464b, la misma huella encontrada en 179.60.149.209 puerto 2222. Este puerto ejecutaba f95812cb, la misma huella digital encontrada en nuestro host original (Stealc C2), 5.188.87.38.
Nota: la parte "(via: ...)" del árbol pivote es el término CenQL utilizado para encontrar ese host.
En nuestra búsqueda final (en profundidad 3), se encontraron varios términos de búsqueda nuevos que podrían aportar más información:
Cabe señalar que todo esto funciona con datos históricos de host, también; por ejemplo, si sabía que había un servidor de Cobalt Strike en un host que fue retirado o el servicio fue eliminado, y usted sabe la fecha en que fue visto por última vez en el host, puede suministrar la bandera '-at-time' así:
% python censeye.py 103.234.98.97 --at-time 2024-09-25
Supongamos que la herramienta encuentra un certificado histórico (como se ha descrito anteriormente, un certificado que no se ve en ejecución actualmente pero que lo ha estado en el pasado), y se suministra el indicador "-profundidad". En ese caso, Censeye utilizará los datos históricos del host donde se encontró ese certificado para encontrar pivotes potenciales en el día actual. Tanto el informe de host como el árbol de pivote le indicarán cuándo ocurre esto mostrando la fecha en que se obtuvieron estos resultados:
ADVERTENCIA
- Esta herramienta puede consumir muchas consultas, lo que significa que buscar en un solo host podría agotar toda tu cuota mensual.
- La herramienta tampoco es muy rápida; se genera un informe para cada campo (configurado) de un host, lo que significa que se producen varias llamadas a la API en segundo plano. Cuando se utiliza el indicador de profundidad, aumenta exponencialmente el número de llamadas a la API.
Sin embargo, hemos implementado varias capas de caché para reducir el número de llamadas a la API en una sola sesión. Todas ellas se almacenan en un "espacio de trabajo" definido por el usuario (que puede redefinirse con el argumento "-workspace"). Mi flujo de trabajo (personal) es mantener un espacio de trabajo diferente para cada "cosa" que estoy investigando. De esta manera, tengo una versión local de los datos que obtuve originalmente y puedo revisarlos más tarde e ir incrementando los diferentes pivotes que encuentra la herramienta.