Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
botnet-hackpack — بناء بوت نت أساسي للقيادة والتحكم بلغة C | Kitploit
أدوات/GitHubGitHub/treehacks/botnet-hackpack
آليات الاستمراريةتحليل البرمجيات الخبيثةالقيادة والسيطرةالتعلم والتعليمالفريق الأحمرتطوير الحمولات
GitHubtreehacks/botnet-hackpack

botnet-hackpack

بناء بوت نت أساسي للقيادة والتحكم بلغة C

عرض المستودع
4039517منذ 7 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

بوتنت C&C بسيط

سيرشدك هذا الـ hackpack خلال تنفيذ إطار عمل أساسي يصف بشكل جوهري ما هي البوتنت. قد يكون من المفيد أن تكون قد عملت مع لغة C من قبل. إذا أعجبك هذا البرنامج التعليمي، تأكد من وضع نجمة على هذا المستودع!

ملاحظة: لا تستخدم أي شيء تتعلمه هنا لأغراض خبيثة. هذا الـ hackpack هو مجرد دراسة حالة عن البوتنتات لأغراض تعليمية. المفاهيم التي ستتعلمها في هذا الـ hackpack لها حالات استخدام بعيدة المدى (أساسًا أي شيء يتعلق بالشبكات). والأهم من ذلك، صُمم هذا الـ hackpack ليُختبر ويُشغَّل محليًا (لذا يرجى عدم مشاركة أي شيء تبنيه متعلقًا بهذا الـ hackpack مع مخترقين آخرين). الخصوصية مهمة لذا يرجى احترامها.

ما هي البوتنت؟

قبل أن تبني بوتنت، من المهم أن تفهم ما هي البوتنت. البوتنت هي شبكة من أجهزة الكمبيوتر القادرة على استلام أوامر عن بُعد وتنفيذها محليًا. ويمكنها اختياريًا اختيار إعادة توجيه المعلومات إلى عقد أخرى في الشبكة. لقد استُخدمت في كل شيء بدءًا من هجمات حجب الخدمة الموزعة وصولًا إلى نشر برمجيات التجسس على نطاق واسع. ربما سمعت عن العديد من البوتنتات في الماضي. وأبرزها على الأرجح Mirai و Gameover Zeus اللتان تحكمان في 3.8 ألف و 3.6 مليون جهاز من أجهزة إنترنت الأشياء على التوالي. هناك تباين كبير في كيفية تنفيذ البوتنتات لمهام معينة. ولكن من أجل بناء البوتنت بنجاح، نحتاج إلى ضمان الميزات التالية في شبكتنا العاملة.

يجب أن تقوم بوتنتنا بما يلي:

  1. تضمين عقدة رئيسية تتحكم في جميع العقد الأخرى على الشبكة
  2. نشر برمجيات خبيثة/عقد تابعة متنكرة على أجهزة الكمبيوتر المضيفة
  3. نقل الأوامر من العقدة الرئيسية إلى العقدة التابعة، وتنفيذها، وإعادة الناتج إلى العقدة الرئيسية

هذه البنية هي سمة لما يُعرف ببوتنتات التحكم والقيادة (Command & Control). تتميز هذه البوتنتات بخادم رئيسي واحد والعديد من الخوادم التابعة. ومع ذلك، فإن هذا النمط من البوتنتات قديم ويمكن إسقاطه بسهولة عن طريق قطع الوصول إلى النطاق الرئيسي. تتبع البوتنتات الأحدث والأكثر تطورًا بنية الند للند (peer-to-peer)، حيث يتم توزيع حقوق الإدارة عبر جميع العقد أو مجموعة فرعية منها في الشبكة. تشكل هذه البوتنتات صداعًا كبيرًا لخبراء الأمن لعدم وجود نقطة تحكم مركزية، ويمكن أن تنمو إلى ملايين العقد. إسقاط مثل هذه البوتنتات هو موضوع شيق بحد ذاته. ومع ذلك، ولأغراض هذا الـ hackpack، دعونا نبقي الأمور بسيطة. سنقوم بتنفيذ عقدة تابعة بسيطة لبوتنت من نوع C&C.

alt tag

التنفيذ

العقدة الرئيسية

سيتعامل هذا الـ hackpack بشكل أساسي مع تنفيذ البرمجية الخبيثة للعميل. بالنسبة للخادم الرئيسي، يمكننا استخدام خادم TCP مفتوح المصدر يُدعى Netcat. لا علاقة لـ Netcat بالبوتنتات. إنها مجرد أداة مريحة وراسخة يمكننا إعادة استخدامها لإرسال حزم نصية من وإلى العملاء (وهذا كل ما هو الخادم الرئيسي فعليًا). لقد عدّلتُ خادم netcat قليلاً وترجمته إلى ملف ثنائي باسم "master". لا حاجة لمزيد من العمل هنا! خادمنا الرئيسي جاهز للاستخدام.

العقدة التابعة

دعنا ننتقل إلى الجزء الأكثر إثارة: استلام الأوامر عن بُعد وتنفيذها (سنقلق بشأن إخفاء برمجيتنا الخبيثة لاحقًا). الهدف هنا هو جعل عقدتنا التابعة بسيطة قدر الإمكان والالتزام بالمتطلبات المذكورة أعلاه. لاحظ أنه تم تعريف العديد من الثوابت في lib/macros.h، لذا لا تتردد في استخدامها. يمكن العثور على جميع تواقيع الدوال المنفذة في lib/connect.h أو lib/utils.h.

1. البدء

افتح ملف bot.c. عند بدء عقدة جديدة في خادمنا، يجب علينا على الأرجح تسميتها حتى يعرف الخادم الرئيسي أي العملاء يوجّه إليها الأوامر. هناك العديد من اصطلاحات التسمية التي يمكن استخدامها. استخدام عنوان IP هو الأفضل على الأرجح لأنه معرّف فريد لكل عميل. ومع ذلك، ولجعل الأمور أكثر قابلية للقراءة للبشر العاديين، دعنا نستخدم اسم مستخدم الكمبيوتر. استخدام دالة C getenv() مع الوسيط "USER" يُرجع ما خزّنه الكمبيوتر في متغير البيئة USER. هذا أحد الأماكن التي يُخزَّن فيها اسم مستخدم المستخدم، لذا دعنا نستخدم ذلك. أيضًا، الآن بعد أن أصبحت عقدتك التابعة تعمل، دعنا نبحث عن الخادم الرئيسي. للقيام بذلك، يجب أن نعرف عنوان IP للخادم الرئيسي. كل جهاز شبكة لديه عنوان IP. إنه مسؤول عن تحديد العقد الأخرى ومعالجة العناوين. علاوة على ذلك، يمكن أن يكون لدى الخادم الرئيسي العديد من الخوادم التي تعمل على منافذ مختلفة. لذا، ليس علينا فقط الاتصال بالخادم الرئيسي، بل يجب أيضًا تحديد المنفذ الصحيح. هذا المنفذ يختاره الخادم الرئيسي ولكن يمكن تغييره. في هذا الـ hackpack، نريد الاختبار محليًا. لذا، سنستخدم جهاز الكمبيوتر الخاص بك كشبكة لنا. عنوان IP المحلي لكل جهاز كمبيوتر (الذي يشير إليه "localhost" أيضًا) هو "127.0.0.1". في الخادم الرئيسي، حددته ليعمل على المنفذ 9999. بهذه الأشياء الثلاثة (عنوان IP للخادم الرئيسي، منفذ الخادم الرئيسي، واسم العقدة التابعة)، يمكننا بدء قناة اتصال بين الخادم والعميل تُسمى socket. مرر هذه الوسائط الثلاثة إلى الدالة init_socket() لإنشاء socket. init_function() ليست أمر C مدمجًا. بل نحتاج إلى تنفيذها. ثم نحتاج إلى تخصيص بعض المساحة على المكدس لاستيعاب الرسائل الواردة. لنكن كرماء هنا واستخدم حوالي 10KB من مساحة المكدس. أطلق على مؤشر المكدس هذا msg. أخيرًا، هناك عبارة printf للإشارة إلى أن كل شيء على ما يرام.

char* name = //Get the client's username and store it in name
int channel = //initiate a channel given SERVER, PORT, and name;
//Allocate stack space of size CMD_LENGTH to hold data of type char. Call the stack pointer msg
printf("%s joining the botnet\n", name);

الآن انتقل إلى lib/connect.c. دعنا ننفذ init_channel(). أولاً، عرّفتُ مخزنًا مؤقتًا للأحرف على المكدس باسم msg بطول CMD_LENGTH وبنية شبكة C خاصة اسمها server تحتفظ بمعلومات حول اتصالنا بالخادم الرئيسي. أولاً، قم بتحويل عنوان IP الذي مررته من صيغة قابلة للقراءة البشرية (مع أرقام ونقاط) إلى صيغة ثنائية بترتيب بايتات الشبكة. يتم ذلك باستخدام دالة C خاصة تسمى inet_addr() من مكتبة socket. إنها ببساطة تأخذ عنوان IP وتخرجه في شكل ثنائي قابل للاستخدام في الشبكة. في C، يمكننا بسهولة تحديد شبكة عن طريق ملء حقول بنية تسمى sockaddr_in. مثيلنا من هذه البنية يسمى server. نحتاج إلى ملء 3 حقول من هذه البنية: server.sin_addr.s_addr (عنوان IP للخادم الرئيسي)، server.sin_family (قيمة 1 بايت تحدد مجال الاتصالات)، و server.sin_port (المنفذ الذي سنتصل به بالخادم الرئيسي). يمكن إعطاء sin_family ماكرو C التي توفرها مكتبة socket. عادةً، كما في هذه الحالة، نضبط هذا الحقل على AF_INET. هذا يعني أن اتصالنا يحدد عقد الشبكة عبر عناوين IP الخاصة بها وهذا ما نريده. ومع ذلك، من الممكن أيضًا استخدام PF_INET وهو مشابه لـ AF_INET لكنه يحدد أن الشبكة يمكنها استخدام أي شيء داخل البروتوكول لتحديد العقد المحددة. هناك أيضًا العديد من الأسباب التاريخية المفترضة لوجود كلاهما، لكن هذا شيء لا أعرفه حقًا أو لا أهتم به. فقط استخدم AF_INET. أخيرًا، عند تعيين منفذ الخادم، يجب تمرير port عبر دالة خاصة تسمى htons() (host to network short). هذا يحول البيانات من ترتيب بايتات المضيف إلى ترتيب بايتات الشبكة. فوضى ترتيب البايتات هذه لها علاقة بشيء يسمى Endianness. يمكنك قراءة المزيد حوله هنا.

أخيرًا، نحتاج إلى تعريف الاتصال الفعلي بين الخادم الرئيسي والعقدة التابعة! للقيام بذلك، عرّف socket شبكي يمكن من خلاله إرسال البيانات. تخيل أن الخادم الرئيسي لديه العديد من 'المقابس الكهربائية'. الآن، نحتاج إلى بناء 'قابس' في العقدة التابعة يناسب 'مقابس الحائط' الخاصة بالخادم الرئيسي. يمكننا فعل ذلك باستخدام دالة socket() من مكتبة socket. يا لها من صدفة! تأخذ socket() 3 وسائط: مجال الاتصالات، نوع socket، وبروتوكولًا. لمجال الاتصالات، ربما خمنت بالفعل: AF_INET. لنوع socket، نريد أن يكون socket الخاص بنا ببساطة ينقل البيانات في كلا الاتجاهين. ومن ثم، استخدم الماكرو المعطى SOCK_STREAM. دعنا لا نقلق بشأن بروتوكول socket. هذه شبكة أساسية إلى حد ما، لذا دعنا نستخدم قيمة 0 للدلالة على البروتوكول الافتراضي. تُرجع الدالة int يمثل socket. خزّن هذه القيمة في channel. بعد ذلك، نريد بدء تشغيل socket الخاص بنا (توصيل العقدة التابعة بمقبس حائط الخادم الرئيسي). استدعِ دالة C connect(). تأخذ هذه ثلاث وسائط: channel، بنية sockaddr، وحجم البنية بالبايتات. إذا أعادت connect() عددًا صحيحًا موجبًا، فهذا يعني أن اتصالك بالخادم الرئيسي ناجح! من أجل اختبار اتصالنا الجديد، دعنا نرسل تحية إلى الخادم الرئيسي! املأ مخزن الرسائل لدينا واستخدم respond() (التي لم تُنفَّذ بعد) لإرسال msg عبر channel إلى الخادم الرئيسي. أخيرًا، نريد من الدالة init_channel() أن تعيد هذا الاتصال الناجح.

int init_channel (char *ip, int port, char *name) {
	char msg[CMD_LENGTH];
	struct sockaddr_in server;
تنزيل الأداة