Casos de ataques encontrados en los registros de acceso
(nishtahir.com)- En los registros de acceso de una IP pública autoalojada durante más de 10 años aparecen intentos de ataque habituales contra servicios expuestos a Internet, desde búsqueda de credenciales hasta inyección de comandos contra dispositivos IoT
- El patrón más común fue la búsqueda de archivos de configuración y directorios como
.env,.aws/credentials,.git/config,backup/ytest/, y algunas solicitudes usaban User-Agent con errores tipográficos comoMozlila/5.0 - Los intentos de Shellshock incluían payloads con forma de función de Bash dentro del User-Agent para leer
/etc/passwd, además de adivinar repetidamente varias rutas CGI - Los ataques dirigidos a LuCI y Zyxel intentaban insertar comandos en las interfaces web de routers y dispositivos embebidos para descargar y ejecutar scripts remotos y binarios para múltiples arquitecturas
- Hay que reducir al mínimo lo que se expone a Internet pública, aplicar autenticación y restricciones por IP a las herramientas o directorios necesarios, y mantener los dispositivos IoT actualizados y, de ser posible, separados de la red pública
Tráfico que reciben los servicios expuestos a Internet pública
- Tras más de 10 años de autoalojamiento, la experiencia ha sido mantener control directo sobre los propios datos y reducir la dependencia de plataformas ajenas a un host en la nube
- Cuando una IP queda expuesta a Internet pública, enseguida empieza a recibir mucho tráfico malicioso, y los registros de acceso permiten rastrear qué tipos de ataques se han recibido recientemente
- Este análisis se parece más a la observación de un desarrollador curioso que a una investigación forense hecha por un especialista en seguridad
- Por precaución, se ocultaron las direcciones IP de los atacantes y algunas expresiones insultantes usadas por ellos
Búsqueda de credenciales y archivos de configuración
- El ataque más común fue el intento de encontrar credenciales mediante recorrido de directorios, y en particular aparecieron muchas solicitudes al archivo
.env- Ejemplos de rutas solicitadas:
/laravel/.env,/backend/.env,/api/.env,/.env,//.env .envnormalmente se maneja como un archivo que contiene secretos de la aplicación
- Ejemplos de rutas solicitadas:
- También se buscaban archivos relacionados con AWS y configuraciones de repositorios Git
- Ejemplos:
/aws.yml,/.env.bak,/info.php,/.aws/credentials,/config/aws.yml,/.git/config
- Ejemplos:
- También se solicitaron repetidamente directorios comunes que podrían haber quedado por error
- Ejemplos:
/old/,/new/,/test/,/backup/,/temp/
- Ejemplos:
- Algunos User-Agent incluían
Mozlila/5.0, que parece un error tipográfico deMozilla/5.0- Los resultados de búsqueda en GitHub sugieren que este error pudo haberse generado en una herramienta común y luego haberse copiado y pegado
- También se detectaron solicitudes que buscaban herramientas de acceso remoto o de configuración
- Ejemplos:
/actuator/gateway/routes,/hudson,/ui/login.action,/?XDEBUG_SESSION_START=phpstorm
- Ejemplos:
- Conviene exponer a Internet pública solo lo estrictamente necesario, y si se deben exponer herramientas o directorios, hace falta una capa de autenticación y, cuando sea posible, restricciones a IP específicas
Intentos de Shellshock
- Varias solicitudes parecían apuntar a la vulnerabilidad Shellshock
- Este ataque busca ejecutar comandos arbitrarios en servidores web que ejecutan scripts CGI con versiones vulnerables de Bash
- Al iniciarse un programa CGI, se establecen variables de entorno a partir del contenido de la solicitud, y
HTTP_USER_AGENTes una de ellas - Si incluye caracteres como
() { :; };, Bash lo interpreta como una función que debe ejecutar
- Al iniciarse un programa CGI, se establecen variables de entorno a partir del contenido de la solicitud, y
- En los registros reales, el User-Agent contenía payloads como estos
() { ignored; }; echo Content-Type: text/html; echo ; /bin/cat /etc/passwd() { ignored; };tiene la forma de una definición de función de Bashecho Content-Type: text/html; echo ;imprime el Content-Type de la respuesta HTTP y una línea vacía/bin/cat /etc/passwdes un comando que intenta mostrar el contenido de/etc/passwd, donde está la información de cuentas de usuario
- Si el ataque hubiera tenido éxito, podría haber derivado en acceso a credenciales de usuario y ejecución de código arbitrario en el servidor
- Igual que en el recorrido de directorios, el atacante adivinaba rutas comunes como
/cgi-bin/status,/cgi-bin/stats,/cgi-bin/test,/cgi-bin/status/status.cgi,/test.cgi,/debug.cgi,/cgi-bin/test-cgi
Inyección de comandos dirigida a LuCI
- Una solicitud parecía apuntar a LuCI, la interfaz web para routers OpenWRT
- La URL del ataque estaba estructurada para insertar comandos en el campo
countryy así descargar y ejecutar el script de shell remototenda.sh- Después de decodificar la URL, el comando seguía un flujo de ir a
/tmp, borrar archivos, descargar el script conwget, darle permisos de ejecución y luego ejecutarlo
- Después de decodificar la URL, el comando seguía un flujo de ir a
- El script descargado contenía instrucciones para bajar y ejecutar binarios adicionales
- Incluía nombres que parecen corresponder a arquitecturas objetivo como
mips,mpsl,x86_64,arm,arm5,arm6,arm7,i586,i686,powerpc,sh4,m68k,sparc - Intentar binarios para varias arquitecturas parece una forma de ampliar el alcance del ataque cuando no se conoce la arquitectura exacta del dispositivo objetivo
- Incluía nombres que parecen corresponder a arquitecturas objetivo como
- Para investigar más, se descargó un binario incompatible con el entorno y se examinó con Ghidra
- Al principio solo había 3 funciones y muy pocos datos de texto
- En una gran región de datos aparecieron las cadenas
$Info: This file is packed with the UPX executable packeryUPX 3.94
- Era un binario ELF comprimido con UPX, y si el encabezado de UPX o el binario empaquetado no fueron modificados, puede desempaquetarse con
upx -d- De hecho, al ejecutar
upx -d mips, el tamaño del archivo aumentó de34932a93732, y fue posible ver muchas más cadenas
- De hecho, al ejecutar
- Entre las cadenas del binario desempaquetado aparecían
M-SEARCH * HTTP/1.1,ST: urn:dial-multiscreen-org:service:dial:1y un payload XML para actualizar dispositivos Huawei- Esto parece ser un comando UPnP para buscar en la red dispositivos compatibles con el protocolo DIAL
- El payload XML parece estar preparado para escanear dispositivos Huawei vulnerables a inyección de comandos
- Este comportamiento parece haber sido identificado como parte de la botnet Mirai
- El archivo referenciado
yeye.mipsno estaba disponible cuando se intentó obtenerlo- Al ejecutar
nmapcontra el servidor, solo se detectaron los puertos abiertos22/tcp sshy646/tcp filtered ldp
- Al ejecutar
Inyección de comandos dirigida a Zyxel
- Otra solicitud contenía comandos de shell dentro de una URL GET, y al eliminar la sustitución de shell
${IFS}quedaba una forma más fácil de leer- El comando depurado seguía un flujo de ir a
/tmp, borrar archivos*mips*, descargarhuhu.mips, darle permisos de ejecución y ejecutarlo con el argumentozyxel.selfrep
- El comando depurado seguía un flujo de ir a
- Este ataque parecía apuntar al exploit de
zhttpden dispositivos Zyxel - Este binario no estaba empaquetado, así que las cadenas podían verse directamente en Ghidra
- Entre las cadenas aparecían
M-SEARCH * HTTP/1.1, el encabezadoSTrelacionado con DIAL,skyljne.arm,skyljne.arm5,skyljne.arm6,skyljne.arm7,skyljne.mips,skyljne.mpsl,skyljne.x86_64,skyljne.sh4 - También incluía un payload XML dirigido a dispositivos Huawei para descargar
huhu.mipsy ejecutarlo comoselfrep.huawei
- Entre las cadenas aparecían
- Otra cadena contenía un comando para enviar un POST a
/goform/set_LimitClient_cfg- Junto con el encabezado
Cookie: user=admin, intentaba insertar comandos en el parámetromacpara descargar y ejecutarhuhu.mpsl - Según un artículo de Akamai, esta vulnerabilidad afecta a routers y puede explotarse sin autenticación previa porque no tiene verificaciones especiales de autenticación ni autorización
- Junto con el encabezado
- Se considera muy probable que este binario sea un agente de la botnet Mirai
- Algunas fuentes también mencionan una posible relación con Linux Medusa
Respuesta desde la operación
- Los registros revisados son solo una parte del total, y cada día se intentan muchos otros exploits
- Es importante mantener los equipos, especialmente los dispositivos IoT, al día
- Siempre que sea posible, los dispositivos IoT no deberían exponerse directamente a Internet pública
- Si es imprescindible exponerlos, conviene aislarlos en una VLAN separada siempre que sea posible
1 comentarios
Opiniones de Hacker News
Curiosamente, algunos atacantes parecen monitorear los logs de Certificate Transparency para encontrar certificados recién emitidos.
Varias veces me pasó que, al dejar un servidor nuevo en una IP nueva durante más de una semana, en los logs de acceso solo aparecían algunos escaneos aleatorios, pero alrededor de una hora después de obtener un certificado de Let’s Encrypt llegaban cientos de solicitudes como las del artículo.
La conclusión es que los servicios nuevos deben estar seguros lo antes posible; idealmente, antes de exponerlos a Internet.
O también se puede usar una autoridad certificadora propia y, hasta hacer el cambio, usar un certificado autofirmado y mTLS.
Por ejemplo, si cierto software expone tal cual una pantalla de instalación inicial para crear la cuenta de administrador, conectar la DB, etc., resulta más riesgoso que definirlo desde el inicio mediante variables de entorno, archivos de configuración o una herramienta dedicada de gestión de secretos.
Por ejemplo, buscar dominios dentro de un periodo específico.
Merkle Town[0] de Cloudflare es útil para ver un panorama general, pero todavía no encontré una forma sencilla de consultar logs CT, y ct-woodpecker[1] también parece prometedor.
[0] https://ct.cloudflare.com/
[1] https://github.com/letsencrypt/ct-woodpecker
Las VPN hoy son tan buenas que dan tranquilidad, y cosas como hosting de fotos o backups en particular no quiero exponerlas públicamente.
Cuando empecé a administrar un sitio autoalojado, también revisaba los logs de acceso y, durante un tiempo, usé un sistema de detección de intrusiones que recopilaba datos y mostraba los intentos de ataque entrantes.
Al final dejé tanto de revisar los logs proactivamente como de pagar por el sistema de detección de intrusiones; era una pérdida de tiempo y una distracción.
Es fácil encontrar materiales que resumen bien las vulnerabilidades y ataques comunes, así que se pueden usar como criterio para administrar servidores. Hay muchas guías de buenas prácticas para cada tecnología común de servidor web, y con solo aplicarlas al 100% ya quedas muy por delante de casi todos los atacantes.
Después de eso, la mejor forma de usar tiempo y recursos es priorizar un ciclo de parchado lo más rápido posible. La mayoría de los ataques apuntan a vulnerabilidades públicas.
Los logs son especialmente útiles para diagnosticar después de que ocurre un problema. El software de análisis de logs me ayudó 2 o 3 veces a almacenar y buscar información para encontrar la causa raíz de ataques exitosos, y cada vez la causa fue una vulnerabilidad conocida que se había parchado demasiado tarde.
La solución es la defensa en capas y, al autoalojar servicios personales, la mayoría se puede aplicar con bastante facilidad.
Pon un firewall al frente o escóndelo detrás de una VPN/Tailscale; si ocultas phpMyAdmin en una subcarpeta como
/mawer/phpmyadmin/en vez de/phpmyadmin/, que es lo que buscan los ataques automatizados, el 99.9% no lo encontrará. A eso se le llama seguridad por oscuridad y no hay que confiar solo en eso, pero como capa adicional es muy útil.Hay que poner las apps en sandboxes y aislar los servidores para que, aunque haya una intrusión, sea difícil moverse a otros lugares; además, dejar logs para poder verificar si hubo ataque y si tuvo éxito.
La clave es no depender de un solo mecanismo de defensa, ya sea parches o firewall. Al final, alguno va a fallar.
Ahora intento actualizar paquetes cada trimestre[0], pero sería bueno tener una herramienta que avise sobre vulnerabilidades conocidas para poder responder de inmediato.
[0] Aquí, “intento” significa que si hay rupturas de compatibilidad difíciles de adaptar a la versión más reciente, o si se trata de una versión X.0.0 en la que todavía no confío, no puedo actualizar de inmediato.
Como el autor dijo que no es experto en seguridad, corrigiendo un detalle menor: los ejemplos del principio son búsqueda de credenciales y configuración, no directory traversal.
Entiendo que directory traversal es el término usado para técnicas en las que el atacante “escapa” de la raíz web o engaña al servidor para que entregue archivos fuera del directorio normal.
"/../../passwd/etc".Al menos según mi experiencia, el punto clave es que una parte considerable de estos ataques viene de actores estatales hostiles.
Puede ser controversial, pero bloquear rangos completos de IP de países problemáticos con los que no tienes ninguna razón para tratar puede ser útil. Con eso llegué a bloquear el 100% de los intentos de escaneo que entraban a un servicio nuevo.
La mayoría de los escaneos que llegan a mi servidor vienen de Estados Unidos, y muy por detrás, en segundo lugar, Países Bajos. Supongo que la mayoría viene de AWS y otros centros de datos.
Trabajo en seguridad de aplicaciones/productos y durante varios años administré WAF de empresas de miles de millones de dólares.
Basta con mover el DNS a Cloudflare y poner algunas reglas de WAF en el sitio. Por ejemplo, aplicar un desafío administrado si la puntuación de bot es menor que 2, o actuar cuando la puntuación de ataque alcanza cierto valor. Probablemente cueste casi nada y resolverá muchos problemas.
Eso sí, hay que probarlo sí o sí antes de pasarlo a producción. También conviene tener un dominio de pruebas. Un WAF no es una solución mágica, sino más bien un parche temporal; si la app en sí no está reforzada para resistir ataques, ni el WAF más avanzado ni la protección contra bots la van a salvar.
Parece que Free Managed Ruleset se despliega por defecto, y Cloudflare mantiene el registro de cambios aquí: https://developers.cloudflare.com/waf/change-log
Funciona muy bien. Como solo accede mi familia, fue fácil configurarlo, y cada uno tiene su propio certificado, que puedo revocar si hace falta.
Como parece que conoces bien este campo, me da curiosidad saber si has administrado alguna solución que combine infraestructura de Azure con Cloudflare y, si es así, si hay cosas que la gente suele pasar por alto aparte de lo típico como OWASP.
Puede ser necesario si una empresa, por el motivo que sea, tiene que operar algo que no está actualizado, pero al final no deja de ser un parche temporal.
Llevo más o menos un año haciendo self-hosting de un servidor HTTP/S de 400 líneas que diseñé yo mismo, y es sorprendente la cantidad de tráfico de ataque que entra por los 3 puertos abiertos (22, 80, 443).
Aunque no me he tomado el tiempo de analizar qué intentan hacer realmente los atacantes, este artículo llena muchos vacíos.
Estaría bueno analizar de la misma forma las cosas raras que aparecen en
/var/log/auth.log.Todo el código es open source y no hay estado del lado del servidor, así que me parece raro que un atacante se moleste en apuntarme a mí. Lo mejor que podría obtener sería acceso root a un VPS de 5 dólares al mes y una alteración temporal de un dominio al que no entra nadie.
Si abres los 3 puertos más conocidos, vas a recibir conexiones; no saben qué estás ejecutando ni les importa.
También pueden alojar malware o ejecutar mineros de criptomonedas.
Mi ISP casi nunca cambia la IP en la práctica, y si cambia puedo iniciar sesión en el panel web de administración del hosting y actualizar la regla.
En cada servidor siempre ejecuto fail2ban, y también agrego jails personalizados para detectar ataques acordes al tipo de funcionalidades que expone el sitio.
Dicho eso, hace mucho que no verifico si los otros valores predeterminados de fail2ban siguen siendo suficientes para bloquear ataques comunes. Voy a guardar este enlace para verlo después.
Yo también reviso los logs de acceso de servicios que tengo en self-hosting, y hay un detalle que falta de forma notable en este análisis.
Una buena parte de las solicitudes maliciosas proviene de personas comunes ejecutando escáneres de seguridad que se consiguen fácilmente en lugares como GitHub. Por lo general son ataques poco sofisticados: instancias de esos proyectos que golpean servidores sin siquiera mirar la respuesta ni preocuparse por si fueron rate-limited.
Algunos ataques no apuntan directamente a una IP, sino que monitorean dominios y subdominios, y repiten periódicamente el mismo escaneo desde el mismo rango de IP.
En un trabajo anterior recibíamos escaneos repetidos desde una única IP fija de Turquía, al punto de que el equipo empezó a llamarlo “el turco”; cuando veíamos un patrón raro de solicitudes, el primer paso de la respuesta a incidentes era revisar si esa persona estaba tocando nuestro servicio.
Si estás viendo logs como estos en AWS, por favor conviene poner AWS WAF delante de la VPC.
No es caro y en situaciones así ayuda bastante a reducir dolores de cabeza. Aunque no bloquee todo lo que llega hasta el servicio, puede ser de gran ayuda.
Algunas reglas demasiado agresivas rompieron partes de la app de forma sutil.
Había una regla de cuerpo de solicitud que bloqueaba solicitudes si el body contenía
"localhost", y otra que bloqueaba solicitudes sin encabezado User-Agent. Como antes no exigíamos User-Agent en las solicitudes de API, les rompió toda la API a algunos usuarios hasta que encontramos la causa.Hay que saber qué se está bloqueando y validarlo primero; si no, en algunos casos terminas perdiendo clientes.
Dan una falsa sensación de seguridad aunque se eludan fácilmente, tienen un costo de rendimiento alto y también una probabilidad considerable de bloquear tráfico legítimo: https://www.macchaffee.com/blog/2023/wafs/
Por ejemplo, los investigadores de nuestra universidad estudian datos de Twitter, y las IP de la universidad quedan bloqueadas por la mayoría de los WAF solo porque siguen enlaces desde una pequeña muestra aleatoria de tuits.
A veces se me ocurre que sería divertido crear un servidor Express que responda correctamente a uno de estos ataques para hacerle perder el tiempo a alguien
Pero si hiciera eso, también estaría perdiendo mi propio tiempo
[1] https://infosec.exchange/@gnyman/109318464878274206
[2] https://nyman.re/super-simple-ssh-tarpit/