传入SSH连接的陷阱(tarp)

互联网是一个非常不利的环境,这已经不是什么秘密了。 提起服务器后,它将立即遭受大规模攻击和多次扫描。 以一名保安人员hanipo为例,可以估计这种垃圾流量的规模。 实际上,在平均服务器上,99%的流量可能是恶意的。

Tarpit是一个陷阱端口,用于减慢传入的连接。 如果第三方系统连接到该端口,它将无法快速关闭连接。 她将不得不花费自己的系统资源,并等待直到连接被超时中断为止,或者手动断开连接。

大多数情况下,柏油用于保护。 该技术最初是为了防止计算机蠕虫而开发的。 现在,它可以用来破坏垃圾邮件发送者和研究人员的生活,他们连续对所有IP地址进行广泛的扫描(例如,哈布雷(Habré)的例子: 奥地利乌克兰 )。

一位名叫Chris Wellons的系统管理员显然厌倦了看到这种耻辱-他编写了一个小型程序Endlessh (SSH的tarpit),减慢了传入连接的速度。 该程序打开端口(默认情况下,指定端口2222用于测试)并假装为SSH服务器,但实际上,它与传入的客户端建立了无限连接,直到它放弃。 这可能会持续数天或更长时间,直到客户端崩溃为止。

实用程序安装:

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

正确实施的tarpit将比您占用更多的攻击者资源。 但问题甚至不在资源中。 作者写道 ,该程序令人上瘾。 目前有27位客户被困,其中有些人连接了数周。 在活动高峰期,有1378位客户在陷阱中坐了20个小时!

在操作模式下,Endlessh服务器需要安装在常规端口22上,在那里流氓大量流传。 标准安全建议始终建议将SSH移至其他端口,这会立即将日志大小减小一个数量级。

克里斯·韦伦斯(Chris Wellons)说,他的程序利用了SSH的RFC 4253规范的一个段落。 建立TCP连接之后,但在应用加密之前,双方应立即发送一个标识字符串。 有一条注释: “服务器可以在发送带有版本的行之前发送其他数据行 并且此数据的数量没有限制 ,只是每一行都不应该以SSH-开头。

这正是Endlessh所做的:它发送一个无休止的随机生成的数据流,数据流遵循RFC 4253,即在识别之前发送,并且每一行都不以SSH-开头并且不超过255个字符,包括行终止符。 通常,一切都是标准的。

默认情况下,程序在发送数据包之间等待10秒。 这样可以防止超时旅行,从而使客户端永远被困住。

由于数据是在应用密码术之前发送的,因此程序非常简单。 它不需要实现任何密码并支持多种协议。

作者试图使该实用程序消耗最少的资源,并在计算机上绝对无缝地工作。 与现代防病毒软件和其他“安全系统”不同,它不应降低计算机的速度。 由于采用了更为狡猾的软件,他设法将流量和内存消耗降至最低。 如果他只是在新连接上启动了单独的过程,则潜在的攻击者可能会发起DDoS攻击,打开许多连接以耗尽计算机上的资源。 每个连接一个线程也不是最佳选择,因为内核将在线程管理上花费资源。

因此,克里斯·韦伦斯(Chris Wellons)为Endlessh选择了最轻量的选项:单线程poll(2)服务器,陷阱中的客户端实际上不消耗不必要的资源,不计算内核中的套接字对象以及另外78个字节来跟踪Endlessh。 为了不为每个客户端分配接收和发送缓冲区,Endlessh打开直接访问套接字并直接转换TCP数据包,而忽略了操作系统的几乎整个TCP / IP堆栈。 根本不需要输入缓冲区,因为输入数据对我们不感兴趣。

作者说,在编写程序时,他不了解 Python Asycio和其他tarpit的存在。 如果他了解asycio,那么他可以在Python中仅用18行实现其实用程序:

 import asyncio import random async def handler(_reader, writer): try: while True: await asyncio.sleep(10) writer.write(b'%x\r\n' % 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非常适合编写tarpit。 例如,这样的陷阱将使Firefox,Chrome或试图连接到您的HTTP服务器的其他客户端挂很多小时:

 import asyncio import random async def handler(_reader, writer): writer.write(b'HTTP/1.1 200 OK\r\n') try: while True: await asyncio.sleep(5) header = random.randint(0, 2**32) value = random.randint(0, 2**32) writer.write(b'X-%x: %x\r\n' % (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()) 


Tarpit是惩罚在线恶霸的好工具。 的确,恰恰相反,将他们的注意力吸引到特定服务器的异常行为上存在一定的风险。 有人可能会想到对您的IP 进行复仇和针对性的DDoS攻击。 但是,到目前为止,还没有这种情况,并且沥青混凝土可以很好地工作。





Source: https://habr.com/ru/post/zh-CN445318/


All Articles