بسم الله الرحمن الرحيم
الحصول على عنوان الأنترنت الخاص بالإجهزة على الشبكة هو الخطوة الأولى لكي تبدأ عملية اكتشاف نقاط الضعف في هذه الأجهزة , و في هذه التدوينة سوف نبني برنامج بايثون يقوم بهذه المهمة , و هنا يأتي السؤال لماذا ؟ , ألا يوجد برامج تقوم بهذا العمل و تغني عن هذا المجهود , الأجابة نعم لكن افضل طريقة للتعلم هو التطبيق, سنبدأ أولا بشرح نظري للطريقة التي سنستخدمها مع نظرة لبرتوكول ARP , ثم تثبيت مكتبة Scapy في ويندوز و لينكس و أخيرا سوف نقوم بكتابة سكريبت يقوم باستخدام بروتوكول ARP لكشف الأجهزة المتصلة .
نظرة لبرتوكول ARP :
Address
Resolution Protocol أو أختصاراً (ARP) , هو برتوكول يهدف لعرض العنوانين
الفزيائية أو ما يسمى بعنوان MAC المرتبط بعنوان الأنترنت ( IP Address ) و
العكس صحيح .
لنفترض بأنك تريد الاتصال بكمبيوتر يوجد على الشبكة المحلية و لديك عنوان الأنترنت (IP) فتحصل الخطوات التالية :
- سيبحث جهازك عن العنوان الفزيائي في جدول العناوين الموجود على النظام والمسمى ARP Caching Table .
- في حالة وجود هذا العنوان في الجدول سوف يتم الأعتماد عليه بدون ارسال طلب ARP .
- في حالة عدم وجود العنوان سوف يرسل الجهاز طلب ARP Request لجميع الأجهزة المتصلة (Broadcast message).
- جهاز الــ"switch" سيقوم بأرسال هذه الرسالة لجميع المنافذ النشطة ما عدا المنفذ الذي تم منه الأرسال .
- عند وصول الرسالة إلى الجهاز الذي يحمل عنوان الأنترنت المطابق سوف يرد برسالة تحمل عنوانه الفيزيائي .
- في حالة عدم وجود جهاز يحمل عنوان الأنترنت على الشبكة المحلية سوف ينتهي وقت انتظار الرد و يفترض الجهاز المرسل بأنه لا وجود لهذا الجهاز .
هذه صورة لطلب 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 ) و ما يميزها هو سهولة تثبيت المكتبات و وجود محرر ممتاز لذا سوف نستخدمها في حالتنا .
- قم بتنزيل التوزيعة من الموقع الرسمي ( https://www.anaconda.com/products/individual-d ) .2. اتبع خطوات التثبيت3. تأكد من تفعيل خيار أضافة مجلد التثبيت إلى متغير مسار البرامج ( PATH )
4. بعد أنتهاء التثبيت قم بتشغيل برنامج Anconda من القائمة Start
5. عندما ينتهي تحميل البرنامج ستظر لم نافذة كالتالي :
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 للشبكات ) و الشرح ببساطة :- Preamble : هو مجموعة 56 بايت تستخدم لمزامنة ساعة المستقبل على نفس ساعة المرسل ( Clock Sync ) و هنا لا نعني التوقيت كالوقت و التاريخ , هذا المصطلح يخص الإلكترونيات , و هذا النطاق يخص الطبقة الأولى من من OSI وسوف اتجنب شرحها لكي لا أعقد الموضوع .
- SFD : اختصار لــ Start Frame Delimiter بداية البيانات الخاص بالإطار أيضا يقع في الطبقة الأولى من OSI .
- Destination Address : العنوان الفيزيائي للبطاقة الشبكة (Mac Address ) المرسل لها البيانات يتكون من 6 بايتات يتم عرضه بتمثيل Hexadecimal و فصل بين كل بايت بـ ":" .
- Source Address : العنوان الفيزيائي للبطاقة الشبكة (Mac Address ) المرسل منها البيانات يتكون من 6 بايتات ايضا و يتبع نفس التمثيل كما في العنوان المرسل له .
- النوع : بحسب البرتوكول المستخدم في حالتنا سيكون ARP و سيحمل القيمة 0x0806.
- البيانات : البيانات الفعلية
- FCS : هذه القيمة تمثل ناتج معادلة تأكد للمرسل أذا حدث خطأ في نقل البيانات , حيث يتم تنفيذ نفس المعادلة في المرسل و المستقبل و في حالة أختلاف القيمة في المرسل يتم أفتراض حصول خطأ .
في Scapy يمكن الوصول إلى العنوان المرسل و المستقبل و البيانات و النوع , و FCS متروكين للنظام أما Preamble و SFD فهما متروكين لبطاقة الشبكة .لإنشاء أطار Ethernet في Scapy فقط استخدم الأمر التالي الذي سوف ينشأ أطار Ethernet و يسنده إلى المتغير الخاص بنا:- Preamble : هو مجموعة 56 بايت تستخدم لمزامنة ساعة المستقبل على نفس ساعة المرسل ( Clock Sync ) و هنا لا نعني التوقيت كالوقت و التاريخ , هذا المصطلح يخص الإلكترونيات , و هذا النطاق يخص الطبقة الأولى من من OSI وسوف اتجنب شرحها لكي لا أعقد الموضوع .
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 , هذه المكتبة تعطيك اختيارات غير محدودة في برمجة الشبكات, و أن شاء الله سوف نحاول نغطي هذه الإمكانيات في أكثر من موضوع .أذا اعجبك الموضوع طلب بسيط دعوة طيبة منك تكفي :-) .
ليست هناك تعليقات:
إرسال تعليق