Trampa (tarpit) para conexiones SSH entrantes

No es un secreto que internet es un entorno muy hostil. Tan pronto como levantas un servidor, este es instantáneamente sometido a ataques masivos y múltiples escaneos. Un ejemplo es un honeypot de especialistas en seguridad que permite evaluar la magnitud de este tráfico basura. De hecho, en un servidor promedio, el 99% del tráfico puede ser malicioso.

Un Tarpit es un puerto trampa que se utiliza para ralentizar las conexiones entrantes. Si un sistema externo se conecta a este puerto, no podrá cerrar rápidamente la conexión. Tendrá que gastar sus recursos del sistema y esperar hasta que la conexión se interrumpa por un tiempo de espera, o romperla manualmente.

Los tarpit se utilizan más comúnmente para protección. La técnica fue desarrollada por primera vez para proteger contra gusanos informáticos. Y ahora se puede usar para arruinar la vida a los spammers y a los investigadores que realizan escaneos masivos de todas las direcciones IP consecutivamente (ejemplos en Habr: Austria, Ucrania).

A uno de los sysadmins llamado Chris Wellons, al parecer, le cansó observar esta atrocidad, así que escribió un pequeño programa Endlessh, un tarpit para SSH que ralentiza las conexiones entrantes. El programa abre un puerto (por defecto se utiliza el puerto 2222 para pruebas) y se hace pasar por un servidor SSH, mientras que en realidad establece una conexión infinita con el cliente entrante, hasta que este se rinda. Esto puede durar varios días o más, hasta que el cliente se desconecte.

Instalación de la utilidad:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

Un tarpit bien implementado consumirá más recursos del atacante que los suyos. Pero el problema no son solo los recursos. El autor Quartz, Madagascar es el único país en África donde la velocidad de descarga de contenido supera los 10 Mbps.indica que el programa es adictivo. En este momento, tiene 27 clientes atrapados, algunos de los cuales han estado conectados durante semanas. ¡En el pico de actividad, había 1378 clientes en la trampa durante 20 horas!

En modo operativo, el servidor Endlessh debe instalarse en el puerto 22, hacia donde los matones suelen intentar acceder. Las recomendaciones estándar de seguridad siempre sugieren mover SSH a otro puerto, lo cual reduce drásticamente el tamaño de los registros.

Chris Wellons dice que su programa explota un párrafo de la especificación RFC 4253 sobre el protocolo SSH. Inmediatamente después de establecer la conexión TCP, pero antes de aplicar la criptografía, ambas partes deben enviar una cadena de identificación. Y allí también se anota: «El servidor PUEDE enviar otras líneas de datos antes de enviar la línea con la versión». Y no hay límite en la cantidad de estos datos, simplemente cada línea debe comenzar con SSH-.

Esto es exactamente lo que hace el programa Endlessh: envía un flujo infinito de datos generados aleatoriamente , que cumplen con el RFC 4253, es decir, se envían antes de la identificación, y cada línea comienza con y no excede los 255 caracteres, incluyendo el carácter de finalización de línea. En general, todo según el estándar.Por defecto, el programa espera 10 segundos entre el envío de paquetes. Esto evita desconexiones por tiempo de espera, así que el cliente estará atrapado para siempre. SSH- Dado que el envío de datos se realiza antes de aplicar criptografía, el programa es extremadamente sencillo. No es necesario implementar ningún cifrado ni soportar múltiples protocolos.

El autor se esforzó por hacer que la utilidad consumiera la mínima cantidad de recursos y funcionara absolutamente sin ser detectada en la máquina. A diferencia de los antivirus modernos y otros «sistemas de seguridad», no debería ralentizar el ordenador. Logró minimizar tanto el tráfico como el consumo de memoria mediante una implementación software ligeramente más ingeniosa. Si hubiera lanzado simplemente un proceso separado para cada nueva conexión, los atacantes potenciales podrían llevar a cabo un ataque DDoS abriendo múltiples conexiones para agotar los recursos de la máquina. Un solo hilo por conexión tampoco es la mejor opción, porque el núcleo estaría gastando recursos en la gestión de hilos.

Por lo tanto, Chris Vellons eligió para Endlessh la opción más liviana: un servidor de un solo hilo

poll(2)

, donde los clientes atrapados prácticamente no consumen recursos adicionales, aparte del objeto de socket en el núcleo y otros 78 bytes para el seguimiento en Endlessh. Para no asignar buffers de recepción y envío para cada cliente, Endlessh abre un socket de acceso directo y transmite paquetes TCP directamente, ignorando casi todo el stack TCP/IP del sistema operativo. El buffer de entrada no es necesario en absoluto, porque los datos entrantes no nos interesan. El autor dice que en el momento de su programano sabía

de la existencia de asyncio de Python y otros tapones. Si hubiera sabido de asyncio, podría haber implementado su utilidad en solo 18 líneas en Python: не знал о существовании питоновского asycio и других тарпитов. Если бы он знал об asycio, то свою утилиту мог бы реализовать всего в 18-ти строчках на Python:

import asyncio
import random

async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()

asyncio.run(main())

Asyncio es ideal para escribir tarpits. Por ejemplo, un tarpit como este puede colgar Firefox, Chrome u otro cliente durante horas, mientras intenta conectarse a tu servidor HTTP:

import asyncio
import random

async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()

asyncio.run(main())

Un tarpit es una excelente herramienta para castigar a los matones de internet. Sin embargo, existe el riesgo de atraer su atención hacia el comportamiento inusual de un servidor en particular. Alguien podría pensar en la venganza y en un ataque DDoS dirigido a tu IP. Sin embargo, hasta ahora no ha habido tales casos, y los tarpits funcionan muy bien.

Temas:
Python, Seguridad Informática, Software, Administración de Sistemas

Etiquetas:
SSH, Endlessh, tarpit, tarpit, trampa, asycio
Trampa (tarpit) para conexiones SSH entrantes

No es un secreto que internet es un entorno muy hostil. Tan pronto como levantas un servidor, este es instantáneamente sometido a ataques masivos y múltiples escaneos. Un ejemplo es un honeypot de especialistas en seguridad que permite evaluar la magnitud de este tráfico basura. De hecho, en un servidor promedio, el 99% del tráfico puede ser malicioso.

Un Tarpit es un puerto trampa que se utiliza para ralentizar las conexiones entrantes. Si un sistema externo se conecta a este puerto, no podrá cerrar rápidamente la conexión. Tendrá que gastar sus recursos del sistema y esperar hasta que la conexión se interrumpa por un tiempo de espera, o romperla manualmente.

Los tarpit se utilizan más comúnmente para protección. La técnica fue desarrollada por primera vez para proteger contra gusanos informáticos. Y ahora se puede usar para arruinar la vida a los spammers y a los investigadores que realizan escaneos masivos de todas las direcciones IP consecutivamente (ejemplos en Habr: Austria, Ucrania).

A uno de los sysadmins llamado Chris Wellons, al parecer, le cansó observar esta atrocidad, así que escribió un pequeño programa Endlessh, un tarpit para SSH que ralentiza las conexiones entrantes. El programa abre un puerto (por defecto se utiliza el puerto 2222 para pruebas) y se hace pasar por un servidor SSH, mientras que en realidad establece una conexión infinita con el cliente entrante, hasta que este se rinda. Esto puede durar varios días o más, hasta que el cliente se desconecte.

Instalación de la utilidad:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

Un tarpit bien implementado consumirá más recursos del atacante que los suyos. Pero el problema no son solo los recursos. El autor Quartz, Madagascar es el único país en África donde la velocidad de descarga de contenido supera los 10 Mbps.indica que el programa es adictivo. En este momento, tiene 27 clientes atrapados, algunos de los cuales han estado conectados durante semanas. ¡En el pico de actividad, había 1378 clientes en la trampa durante 20 horas!

En modo operativo, el servidor Endlessh debe instalarse en el puerto 22, hacia donde los matones suelen intentar acceder. Las recomendaciones estándar de seguridad siempre sugieren mover SSH a otro puerto, lo cual reduce drásticamente el tamaño de los registros.

Chris Wellons dice que su programa explota un párrafo de la especificación RFC 4253 sobre el protocolo SSH. Inmediatamente después de establecer la conexión TCP, pero antes de aplicar la criptografía, ambas partes deben enviar una cadena de identificación. Y allí también se anota: «El servidor PUEDE enviar otras líneas de datos antes de enviar la línea con la versión». Y no hay límite en la cantidad de estos datos, simplemente cada línea debe comenzar con SSH-.

Esto es exactamente lo que hace el programa Endlessh: envía un flujo infinito de datos generados aleatoriamente , que cumplen con el RFC 4253, es decir, se envían antes de la identificación, y cada línea comienza con y no excede los 255 caracteres, incluyendo el carácter de finalización de línea. En general, todo según el estándar.Por defecto, el programa espera 10 segundos entre el envío de paquetes. Esto evita desconexiones por tiempo de espera, así que el cliente estará atrapado para siempre. SSH- Dado que el envío de datos se realiza antes de aplicar criptografía, el programa es extremadamente sencillo. No es necesario implementar ningún cifrado ni soportar múltiples protocolos.

El autor se esforzó por hacer que la utilidad consumiera la mínima cantidad de recursos y funcionara absolutamente sin ser detectada en la máquina. A diferencia de los antivirus modernos y otros «sistemas de seguridad», no debería ralentizar el ordenador. Logró minimizar tanto el tráfico como el consumo de memoria mediante una implementación software ligeramente más ingeniosa. Si hubiera lanzado simplemente un proceso separado para cada nueva conexión, los atacantes potenciales podrían llevar a cabo un ataque DDoS abriendo múltiples conexiones para agotar los recursos de la máquina. Un solo hilo por conexión tampoco es la mejor opción, porque el núcleo estaría gastando recursos en la gestión de hilos.

Por lo tanto, Chris Vellons eligió para Endlessh la opción más liviana: un servidor de un solo hilo

poll(2)

, donde los clientes atrapados prácticamente no consumen recursos adicionales, aparte del objeto de socket en el núcleo y otros 78 bytes para el seguimiento en Endlessh. Para no asignar buffers de recepción y envío para cada cliente, Endlessh abre un socket de acceso directo y transmite paquetes TCP directamente, ignorando casi todo el stack TCP/IP del sistema operativo. El buffer de entrada no es necesario en absoluto, porque los datos entrantes no nos interesan. El autor dice que en el momento de su programano sabía

de la existencia de asyncio de Python y otros tapones. Si hubiera sabido de asyncio, podría haber implementado su utilidad en solo 18 líneas en Python: не знал о существовании питоновского asycio и других тарпитов. Если бы он знал об asycio, то свою утилиту мог бы реализовать всего в 18-ти строчках на Python:

import asyncio
import random

async def handler(_reader, writer):
    try:
        while True:
            await asyncio.sleep(10)
            writer.write(b'%xrn' % random.randint(0, 2**32))
            await writer.drain()
    except ConnectionResetError:
        pass

async def main():
    server = await asyncio.start_server(handler, '0.0.0.0', 2222)
    async with server:
        await server.serve_forever()

asyncio.run(main())

Asyncio es ideal para escribir tarpits. Por ejemplo, un tarpit como este puede colgar Firefox, Chrome u otro cliente durante horas, mientras intenta conectarse a tu servidor HTTP:

import asyncio
import random

async def handler(_reader, writer):
    writer.write(b'HTTP/1.1 200 OKrn')
    try:
        while True:
            await asyncio.sleep(5)
            header = random.randint(0, 2**32)
            value = random.randint(0, 2**32)
            writer.write(b'X-%x: %xrn' % (header, value))
            await writer.drain()
    except ConnectionResetError:
        pass

async def main():
    server = await asyncio.start_server(handler, '0.0.0.0', 8080)
    async with server:
        await server.serve_forever()

asyncio.run(main())

Un tarpit es una excelente herramienta para castigar a los matones de internet. Sin embargo, existe el riesgo de atraer su atención hacia el comportamiento inusual de un servidor en particular. Alguien podría pensar en la venganza y en un ataque DDoS dirigido a tu IP. Sin embargo, hasta ahora no ha habido tales casos, y los tarpits funcionan muy bien.

Trampa (tarpit) para conexiones SSH entrantes

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster