
يُولّد شيلكود مستقل عن الموقع (position-independent shellcode) من نوع x86 أو x64 أو AMD64+x86 يُحمّل تجميعات .NET وملفات PE وغيرها من تحميلات Windows من الذاكرة ويُشغّلها مع وسائط.

الإصدار الحالي: v1.1
دونات (Donut) هو كود مستقل عن الموقع يمكنه تنفيذ ملفات VBScript وJScript وEXE وDLL وتجميعات dotNET في الذاكرة. يمكن تحميل الوحدة التي أنشأها دونات إما من خادم HTTP أو تضمينها مباشرة داخل المُحمِّل نفسه. يتم تشفير الوحدة اختياريًا باستخدام تشفير الكتلة Chaskey ومفتاح 128 بت يتم إنشاؤه عشوائيًا. بعد تحميل الملف وتنفيذه في الذاكرة، يتم مسح المرجع الأصلي لردع ماسحات الذاكرة. يدعم المُولِّد والمُحمِّل الميزات التالية:
توجد مكتبات ديناميكية وثابتة لكل من Linux وWindows يمكن دمجها في مشاريعك الخاصة. يوجد أيضًا وحدة Python يمكنك قراءة المزيد عنها في بناء واستخدام إضافة Python.
يحتوي دونات على مُحمِّلين منفصلين لكل نوع ملف مدعوم. بالنسبة لتجميعات dotNET EXE/DLL، يستخدم دونات واجهة استضافة CLR غير المُدارة (Unmanaged CLR Hosting API) لتحميل بيئة التشغيل العامة (CLR). بمجرد تحميل CLR في العملية المضيفة، يتم إنشاء نطاق تطبيق جديد (Application Domain) للسماح بتشغيل التجميعات في نطاقات تطبيقات قابلة للتخلص. عندما يصبح نطاق التطبيق جاهزًا، يتم تحميل تجميع dotNET عبر طريقة AppDomain.Load_3. أخيرًا، يتم استدعاء نقطة الدخول لملفات EXE أو الطريقة العامة لملفات DLL التي يحددها المستخدم مع أي معلمات إضافية. راجع MSDN للتوثيق حول واجهات استضافة CLR غير المُدارة. للحصول على مثال مستقل لمضيف CLR، راجع الكود هنا.
يتم تنفيذ ملفات VBScript وJScript باستخدام واجهة IActiveScript. يوجد أيضًا دعم محدود لبعض الطرق التي يوفرها مضيف Windows Script Host (wscript/cscript). للحصول على مثال مستقل، راجع الكود هنا. للحصول على وصف أكثر تفصيلاً، اقرأ: تنفيذ JavaScript وVBScript وJScript وXSL في الذاكرة
يتم تنفيذ ملفات EXE/DLL غير المُدارة (الأصلية) باستخدام مُحمِّل PE مخصص يدعم الاستيرادات المتأخرة وTLS وتصحيح سطر الأوامر. يتم دعم فقط الملفات التي تحتوي على معلومات إعادة التوطين. اقرأ تنفيذ DLL في الذاكرة للمزيد من المعلومات.
يمكن للمُحمِّل تعطيل AMSI وWLDP للمساعدة في التهرب من اكتشاف الملفات الضارة التي يتم تنفيذها في الذاكرة. للمزيد من المعلومات، اقرأ كيف تتجاوز الفرق الحمراء AMSI وWLDP للكود الديناميكي لـ .NET. كما أنه يدعم فك ضغط الملفات في الذاكرة باستخدام aPLib أو واجهة برمجة التطبيقات RtlDecompressBuffer. اقرأ ضغط البيانات للمزيد من المعلومات.
اعتبارًا من الإصدار v1.0، تم تجاوز ETW أيضًا. مثل AMSI/WLDP، هذا نظام معياري يسمح لك باستبدال التجاوز الافتراضي بتجاوز خاص بك. التجاوز الافتراضي مستمد من بحث قام به XPN. اقرأ إخفاء .NET الخاص بك - ETW للمزيد من المعلومات.
افتراضيًا، سيقوم المُحمِّل بالكتابة فوق رؤوس PE لملفات PE غير المُدارة (من العنوان الأساسي إلى `IMAGE_OPTIONAL_HEADER.SizeOfHeaders`). إذا لم يتم استخدام وحدة خادعة (تحميل الوحدة الزائد)، فسيتم تصفير رؤوس PE. إذا تم استخدام وحدة خادعة، فسيتم استخدام رؤوس PE للوحدة الخادعة للكتابة فوق تلك الخاصة بوحدة الحمولة. وذلك لردع الكشف عن طريق مقارنة رؤوس PE للوحدات في الذاكرة مع الملف الداعم لها على القرص. يمكن للمستخدم أن يطلب الاحتفاظ بجميع رؤوس PE في حالتها الأصلية. هذا مفيد في السيناريوهات التي تحتاج فيها وحدة الحمولة إلى الوصول إلى رؤوس PE الخاصة بها، مثل عند البحث عن موارد PE المضمنة.
للحصول على جولة تفصيلية باستخدام المُولِّد وكيفية تأثير دونات على فنيات العمل، اقرأ دونات - حقن تجميعات .NET كشيل كود. للمزيد من المعلومات حول المُحمِّل، اقرأ تحميل تجميعات .NET من الذاكرة.
من يرغب في معرفة المزيد عن الدواخل الداخلية يجب أن يرجع إلى ملاحظات المطور.
هناك نوعان من البناء. إذا كنت ترغب في تصحيح أخطاء دونات، يرجى الرجوع إلى التوثيق هنا. إذا لم يكن الأمر كذلك، تابع القراءة للحصول على بناء الإصدار.
من موجه أوامر Windows أو محطة Linux، قم باستنساخ المستودع.
git clone http://github.com/thewover/donut.git
الخطوة التالية تعتمد على نظام التشغيل الخاص بك والمترجم الذي تقرر استخدامه. حاليًا، يمكن تجميع قالب المُولِّد والمُحمِّل الخاص بدونات بنجاح باستخدام كل من Microsoft Visual Studio 2019 وMingGW-64. لاستخدام المكتبات في مشروع C/C++ الخاص بك، يرجى الرجوع إلى الأمثلة المقدمة هنا.
لإنشاء قالب المُحمِّل، المكتبة الديناميكية donut.dll، المكتبة الثابتة donut.lib والمُولِّد donut.exe. ابدأ موجه أوامر مطور x64 لـ Microsoft Visual Studio، انتقل إلى الدليل حيث استنسخت مستودع دونات وأدخل ما يلي:
nmake -f Makefile.msvc
لفعل الشيء نفسه، ولكن باستخدام MinGW-64 على Windows أو Linux، انتقل إلى الدليل حيث استنسخت مستودع دونات وأدخل ما يلي:
make -f Makefile.mingw
لإنشاء المكتبة الديناميكية donut.so، المكتبة الثابتة donut.a والمُولِّد donut. انتقل إلى الدليل حيث استنسخت مستودع دونات واكتب make ببساطة.
يمكن تثبيت دونات واستخدامه كوحدة Python. للتثبيت من المصدر، يلزم pip لـ Python3. أولاً، تأكد من عدم تثبيت إصدارات أقدم من donut-shellcode عن طريق إصدار الأمر التالي على محطة Linux أو موجه أوامر Microsoft Visual Studio.
pip3 uninstall donut-shellcode
بعد التأكد من عدم تثبيت الإصدارات الأقدم، قم بإصدار الأمر التالي.
pip3 install .
يمكنك أيضًا تثبيت دونات كوحدة Python عن طريق الحصول عليه من مستودع PyPi.
pip3 install donut-shellcode
لمزيد من المعلومات، يرجى الرجوع إلى بناء واستخدام إضافة Python.
بناء حاوية docker.
docker build -t donut .
تشغيل donut.
docker run -it --rm -v "${PWD}:/workdir" donut -h
يتضمن دونات عدة ملفات تنفيذية أخرى يمكن بناؤها بشكل منفصل. وتشمل "hash.exe" و"encrypt.exe" و"inject.exe" و"inject_local.exe". يتم استخدام الأولين في توليد الشيل كود. يتم توفير الأخيرين للمساعدة في اختبار شيل كود دونات. سيقوم "inject.exe" بحقن ملف ثنائي خام (loader.bin) في عملية بواسطة معرف العملية أو اسم العملية. سيقوم "inject_local.exe" بحقن ملف ثنائي خام في عمليته الخاصة.
لبناء هذه الملفات التنفيذية الداعمة بشكل منفصل، يمكنك استخدام ملف make الخاص بـ MSVC. على سبيل المثال، لبناء "inject_local.exe" لاختبار شيل كود دونات الخاص بك، يمكنك تشغيل:
nmake inject_local -f Makefile.msvc
تم توفير علامات (Tags) لكل إصدار من إصدارات دونات تحتوي على الملفات التنفيذية المجمعة.
حاليًا، يوجد مولّدان آخران متاحان.
يسرد الجدول التالي المفاتيح التي يدعمها إصدار سطر الأوامر من المُولِّد.
هناك بعض المتطلبات المحددة التي يجب أن تستوفيها حمولتك لكي يتمكن دونات من تحميلها بنجاح.
تستخدم ملفات Cygwin التنفيذية إجراءات تهيئة تتوقع أن تكون العملية المضيفة قيد التشغيل من القرص. إذا تم التنفيذ من الذاكرة، فمن المحتمل أن تتعطل العملية المضيفة.
هناك أربعة مشاريع مصاحبة مقدمة مع دونات:
قد ترغب في إضافة دعم لمزيد من أنواع الحمولات، أو تغيير مجموعة الميزات لدينا، أو دمج دونات في أدواتك الحالية. لقد قدمنا توثيقًا للمطور. تُترك الميزات الإضافية كتمارين للقارئ. اقتراحاتنا:
إذا كانت لديك أي أسئلة أو تعليقات حول دونات، انضم إلى قناة #Donut في BloodHound Gang Slack
نحن لسنا مسؤولين عن أي إساءة استخدام لهذا البرنامج أو التقنية. يتم تقديم دونات كعرض توضيحي لحقن CLR والتحميل في الذاكرة عبر الشيل كود بهدف توفير وسيلة للفرق الحمراء لمحاكاة الخصوم ومرجع للفرق الزرقاء لبناء التحليلات والتخفيفات. هذا يحمل حتماً خطر إساءة استخدامه من قبل مؤلفي البرامج الضارة وممثلي التهديدات. ومع ذلك، نعتقد أن الفائدة الإجمالية تفوق المخاطرة. نأمل أن يكون ذلك صحيحًا. في حالة تمكن منتجات EDR أو AV من اكتشاف دونات عبر التوقيعات أو الأنماط السلوكية، لن نقوم بتحديث دونات لمواجهة التوقيعات أو طرق الكشف. لتجنب الإساءة، يرجى عدم السؤال.
| المفتاح | الوسيط | الوصف |
|---|---|---|
| -a | arch | الهيكل المستهدف للمُحمِّل: 1=x86، 2=amd64، 3=x86+amd64 (الافتراضي). |
| -b | level | سلوك تجاوز AMSI/WLDP: 1=لا شيء، 2=إحباط عند الفشل، 3=الاستمرار عند الفشل (الافتراضي). |
| -k | headers | الحفاظ على رؤوس PE: 1=الكتابة فوق (الافتراضي)، 2=الاحتفاظ بالكل |
| -j | decoy | المسار الاختياري للوحدة الخادعة لتحميل الوحدة الزائد. |
| -c | class | اسم الفئة الاختياري. (مطلوب لملفات .NET DLL) يمكن أن يتضمن أيضًا مساحة الاسم: على سبيل المثال namespace.class |
| -d | name | اسم نطاق التطبيق (AppDomain) المراد إنشاؤه لـ .NET. إذا تم تمكين الإنتروبيا، سيتم إنشاء واحد عشوائيًا. |
| -e | level | مستوى الإنتروبيا: 1=لا شيء، 2=توليد أسماء عشوائية، 3=توليد أسماء عشوائية + استخدام التشفير المتماثل (الافتراضي) |
| -f | format | صيغة الإخراج للمُحمِّل المحفوظ في ملف: 1=ثنائي (الافتراضي)، 2=Base64، 3=C، 4=Ruby، 5=Python، 6=PowerShell، 7=C#، 8=Hexadecيمال |
| -m | name | طريقة أو دالة اختيارية لملف DLL. (الطريقة مطلوبة لملف .NET DLL) |
| -n | name | اسم وحدة التحميل المتدرج عبر HTTP. إذا تم تمكين الإنتروبيا، يتم إنشاء واحد عشوائيًا. |
| -o | path | يحدد المكان الذي يجب أن يحفظ فيه دونات المُحمِّل. الافتراضي هو "loader.bin" في الدليل الحالي. |
| -p | parameters | معلمات/سطر أوامر اختيارية داخل علامات الاقتباس لدالة/طريقة DLL أو EXE. |
| -r | version | إصدار بيئة تشغيل CLR. يتم استخدام MetaHeader افتراضيًا أو v4.0.30319 إذا لم يكن متاحًا. |
| -s | server | عنوان URL لخادم HTTP الذي سيستضيف وحدة دونات. يمكن تقديم بيانات الاعتماد بالتنسيق التالي: https://username:[email protected]/ |
| -t | تشغيل نقطة الدخول لملف EXE غير مُدار/أصلي كخيط وانتظار انتهاء الخيط. | |
| -w | يتم تمرير سطر الأوامر إلى دالة DLL غير المُدارة بتنسيق UNICODE. (الافتراضي هو ANSI) | |
| -x | option | يحدد كيف يجب أن يخرج المُحمِّل: 1=إنهاء الخيط (الافتراضي)، 2=إنهاء العملية، 3=عدم الخروج أو التنظيف والمنع إلى أجل غير مسمى |
| -y | addr | ينشئ خيطًا جديدًا للمُحمِّل ويواصل التنفيذ في عنوان يمثل إزاحة نسبية للملف التنفيذي للعملية المضيفة. القيمة المقدمة هي الإزاحة. يدعم هذا الخيار المُحمِّلين الذين يرغبون في استئناف تنفيذ العملية المضيفة بعد اكتمال تنفيذ دونات. |
| -z | engine | حزم/ضغط ملف الإدخال: 1=لا شيء، 2=aPLib، 3=LZNT1، 4=Xpress، 5=Xpress Huffman. حاليًا، الثلاثة الأخيرة مدعومة فقط على Windows. |
| الأداة | الوصف |
|---|---|
| DemoCreateProcess | تجميعة .NET نموذجية لاستخدامها في الاختبار. تأخذ معلمتين لسطر الأوامر، كل منهما تحدد برنامجًا للتنفيذ. |
| DonutTest | أداة حقن شيل كود بسيطة بلغة C# لاستخدامها في اختبار دونات. يجب أن يكون الشيل كود مشفرًا بـ base64 ومنسوخًا كسلسلة نصية. |
| ModuleMonitor | أداة إثبات مفهوم تكتشف حقن CLR كما يتم بواسطة أدوات مثل دونات وCobalt Strike's execute-assembly. |
| ProcessManager | أداة اكتشاف العمليات التي يمكن للمشغلين الهجوميين استخدامها لتحديد ما يجب حقنه، ويمكن للمشغلين الدفاعيين استخدامها لتحديد ما يعمل، وما هي خصائص تلك العمليات، وما إذا كان CLR محملًا أم لا. |