El día que el DNS Technitium me mostró un malware

Ni la primera semana de haber vuelto de la licencia… todo desconectado estaba, tratando de retomar el ritmo. Me preparo un mate, arranco la jornada tranquilo y, casi por costumbre, se me da por entrar al DNS interno para ver cómo venía la red. Hacía tiempo que no lo revisaba.

Grave error… o gran acierto.

Empiezo a mirar el top de dominios consultados y aparece algo que no cerraba para nada. Dominios raros, completamente fuera de lo habitual. Ahí ya me hizo ruido.

Siguiente paso: ver qué equipos estaban haciendo esas consultas.

fecha-inicio-malware.pngCuando veo las IP… servidores internos.

Ahí fue cuando pensé: “okey bueno, arrancó el baile”. Todo indicaba que podía estar frente a algún tipo de malware o actividad maliciosa dentro de la red.

Y a partir de ese momento, empezó el análisis.


Punto de partida: consultas DNS sospechosas

Detecto consultas recurrentes a un dominio que no me cerraba por ningún lado:

v1ns.9kpk.com

Primera reacción: bloquearlo directamente desde el DNS.

v1ns-9kpk-virus.pngA los pocos minutos… boom.
Pasa al top de dominios bloqueados.

Ahí ya no era casualidad.

Mientras tanto, algo no me cerraba en la cabeza:
estos servidores no tienen o no deberían tener salida a internet, y además son servicios internos, no expuestos.

Y sin embargo… estaban consultando dominios externos.

Con esa contradicción dando vueltas, me conecto al servidor infectado para analizar qué estaba pasando desde adentro.


Análisis en servidor comprometido

Antes de meter mano, lo primero fue entender dónde estaba parado.

Los servidores afectados corrían sobre:

Y acá ya aparece un dato no menor… estamos hablando de sistemas legacy, sin soporte y con múltiples vulnerabilidades conocidas.

Con ese contexto, todo empezaba a tener más sentido.
Entonces arranco con lo básico para ver ese trafico hacia el servidor DNS interno:

tcpdump -i any port 53

Y lo que veo confirma la sospecha:

  • Consultas tipo A hacia dominios raros

  • Respuestas NXDOMAIN (dominios inexistentes)

  • Consultas PTR asociadas

Comportamiento típico de manual:

  • Intentos de contacto con servidores de comando y control (C2)

  • Validación de conectividad

  • Posible uso de DGA (Domain Generation Algorithm)

Y ahí aparece el segundo actor en escena:

2.ip1100.com

Listo, ya no era uno solo.

El tráfico malicioso estaba apuntando a:

  • v1ns.9kpk.com

  • 2.ip1100.com


Buscando el origen

Empiezo a revisar servicios en el servidor… y algo no cuadraba.

cat /etc/init.d/selinux

En CentOS 5 ese servicio no existe.

Ahí había algo raro.

Veo el contenido:

#!/bin/bash
/usr/bin/bsd-port/knerl

Bien!! Sospechoso de acá a la china esto ya era otra cosa.

Buscando referencias, aparece el primer indicador claro:

Un binario llamado knerl, intentando hacerse pasar por kernel.

Clásico intento de camuflaje.


El problema: no lo podía matar

Y ahí empezó la parte frustrante.

Buscaba el proceso:

ps awx | grep knerl

Nada.

Con top… nada.

Horas pasando… y el proceso seguía ahí, generando tráfico.

Probaba matar otros procesos, volvía a mirar con tcpdump
seguía sucio.

Ya era personal.


Rootkit en juego

Investigando más a fondo, todo apuntaba a lo mismo:

comportamiento tipo rootkit

Eso explicaba todo:

  • ps, top, netstatcomprometidos

  • El proceso estaba… pero no lo podía ver

Hermoso desafío.


Contraataque

La solución fue ir por afuera:

Me traje binarios limpios (ps, top, netstat) desde un servidor no comprometido, los empaqueté y los ejecuté directamente en el infectado.

Y ahí sí…

./ps -AF | grep knerl

Apareció.

/usr/bin/bsd-port/knerl (PID 7372)

Ahí te tenía.


Primer golpe

kill -9 7372

Vuelvo corriendo a mirar el tráfico:

tcpdump -i any port 53

Sigue habiendo tráfico sucio.

Pero algo cambió.

v1ns.9kpk.com desapareció
Quedaba solo 2.ip1100.com

Eso confirmaba que andaba otro cangrejo vivo.

el malware tenía más de un componente activo

Y la limpieza… todavía no había terminado.


Segundo componente malicioso

Si algo ya estaba claro, era esto: no estaba peleando contra un solo proceso.

Sigo revisando… y aparece otro candidato sospechoso un binario:

/usr/bin/sshupdate-bootsystem-insserv

Este tipo de nombres intenta simular procesos legítimos del sistema.

Se procedió nuevamente:

kill -9 <PID>


El momento de la verdad

Ahí sí… paro un segundo.

tiré un “padre nuestro”
y me fui directo a validar:

tcpdump -i any port 53

Silencio.

Ni una consulta rara.
Ni v1ns.9kpk.com.
Ni 2.ip1100.com.

Tráfico limpio.

Después de horas peleando, el ruido había desaparecido.


Identificación de alcance

Con el servidor ya limpio, la siguiente pregunta era inevitable:

¿cuántos más están infectados?

Para determinar el alcance real, me apoyé en dos fuentes clave:

  • Logs DNS en Technitium

  • Tráfico de red desde firewall pfSense

Y fui directo a la base:

SELECT DISTINCT client_ip
FROM dns_logs
WHERE qname = 'v1ns.9kpk.com'
AND timestamp >= 'fecha_inicio'
AND timestamp < 'fecha_fin';

virus-consultaSelect.png


Solución

Con el incidente contenido, el foco ahora pasa a algo igual de importante: evitar que vuelva a ocurrir.

La estrategia definida es migrar este servicio a un entorno más controlado y seguro.

La idea es la siguiente:

  • Implementar un host base sobre Rocky Linux 9, correctamente hardenizado

  • Instalar Podman como motor de contenedores

  • Contenerizar el servicio dentro de una imagen basada en CentOS 7

¿Por qué CentOS 7?

Porque el servicio es legacy y tiene dependencias muy específicas que no son compatibles con versiones más nuevas. Forzar una actualización directa no es viable en este momento.


Indicadores de compromiso (IoC)

  • Dominios:

    • 2.ip1100.com

    • v1ns.9kpk.com

  • Binarios:

    • /usr/bin/bsd-port/knerl

    • /usr/bin/sshupdate-bootsystem-insserv

  • Persistencia:

    • /etc/init.d/selinux modificado


Conclusión

Al momento de escribir este artículo, la investigación sigue en curso.

Todavía no está del todo claro cuál fue el vector inicial de infección ni cómo se propagó hacia otros servidores. La hipótesis más fuerte apunta a un ingreso desde Internet, ya que los servidores afectados son sistemas internos que, en teoría, no deberían estar expuestos y tampoco tienen internet.

Ahí es donde aparece la duda más interesante:
¿en algún momento existió una exposición no controlada? Un NAT temporal, una apertura puntual, alguna configuración que haya quedado habilitada más tiempo del debido… es una posibilidad que no se puede descartar.

Lo que sí parece poco probable es un origen interno mediante dispositivos físicos (como pendrives u otros medios), ya que no hay indicios que apunten en esa dirección.

Hoy por hoy, la única puerta lógica sigue siendo Internet.

Mientras tanto, continúo revisando logs, correlacionando eventos y tratando de determinar el alcance real de la infección.

Seguramente este análisis no termine acá:
si aparecen nuevos hallazgos, evaluaré si hacer una segunda parte o actualizar esta misma entrada con más información.

Porque si algo está claro, es que el incidente ya fue contenido…
pero la investigación recién empieza.


Si querés compartir tu experiencia, dudas o simplemente comentar cómo lo resolviste, escribime a: valerkasystem@protonmail.com

— Valerka
Montevideo, Uruguay