NTP Reply 洪水攻击

NTP(Network Time Protocol),网络时间协议。用来本地与远程NTP服务器时间进行同步所使用的协议。玩过那么多协议,竟然从来没有重视过这个协议。看了黑防 Linxinsnow 和 Longas 的文章,才正儿八经研究了研究。作为笔记记录之。

关于此协议详细的就不多写了。简单描述之便可。具体细节远不止如此,NTP 协议不复杂,但也不是很简单的。

  1. 本地向远程 NTP 服务器发送 NTP 数据包,用的不可靠的 UDP 协议。
  2. NTP 服务器收到数据包,返回时间戳。
  3. 本地根据返回的,再结合某些算法,计算出时间差,然后调整本地时间。

不过构造特殊的 NTP 数据包的时候,NTP 服务器就可以返回最近接近 600 个向该服务器更新过的 IP,可能实际上返回不了那么多,因为 UDP 不可靠。这个举动造成两个结果:1、信息泄露,IP 地址全部曝光了。关于 IP 泄露的防范,个人觉得应该将一台对外的服务器作为 NTP 服务器,然后内部都以这台服务器的时间为准进行同步;2、传说中的 NTP Reply 洪水攻击,理论上返回 600 个 UDP 数据包,我抓包计算了一下,一个包大概有 400 多字节,我抓的时候是 488 个字节左右(具体数据包大小没有完全确认过)。倘若网络完全没有障碍,返回了接近 600 个数据包,那么理想情况下,就等于 UTP 服务器发送了 600*488 个字节的数据给本机。

关于这个特殊的 NTP 数据包,下图是我抓包得到的:

1.jpg

十六进制的内容:

2.jpg

正常情况下,客户端向 NTP 服务器发送请求后,NTP 服务器向客户端答复请求,流程大概如下图(我用 Cisco Packet Tracer 随便画的,中间那根线代表路径,不代表网线):

3.jpg

但是,咱们可以构造 UDP 数据包,由于 UDP 没有 TCP 的三次握手,导致随意的数据包可以流过去,于是,将 UDP 数据包中源地址改成欲攻击对象的,这样返回的数据包就飞到那个造孽的娃娃电脑上去了,大概流程图如下:

4.jpg

于是,老样子,用 Python 完成一个简单的测试程序,数据包是我硬编码的,内容就是上文中第二张截图的内容:),如下:

import socket
ntp_data = '\x17\x00\x02\x2a'
ntp_data += '\x00' * 156

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('133.100.11.8',123))
s.send(ntp_data)

我用 Wireshark 抓包,过滤其他的包,只抓 NTP 协议的,如图:

5.jpg

这个 Python 程序是将数据包返回本地机的,可以构造 UDP 数据包,用 Python 构造或者 WinPcap 编程也行。倘若不停向几台 NTP 服务器发送请求,请求应答却发送到其他机器上,就形成了 DDoS,目前好像全世界有 100 多台 NTP 服务器吧,忘记具体数字了,不是 100 多台就算了哈,不计较这个数据问题。

对于防范方法,理论上的方法倒有几个,可能实际上行不通,就不献丑了。