استدعاء البرنامج النصي من برنامج جذر جذر SETUID - البرنامج النصي لا يعمل كجذر
سؤال
أحتاج إلى تشغيل برنامج نصي باش كجذر (Sudo غير قانوني أو SU غير قابل للتطبيق) وبما أنك لا تستطيع توصيل البرنامج النصي في Linux، فكرت في الاتصال به من قابل للتنفيذ وجعل هو - هي Setuid:
$ cat wrapper.c
int main(void)
{
system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ sudo chown root wrapper
$ sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$
يعمل هذا - كما هو الحال في البرنامج النصي بشكل صحيح - ولكن البرنامج النصي يعمل كمستخدم ينفذ "./wrapper".
لماذا ا؟ وكيف تنفذ هذا بشكل صحيح؟
شكرا!
المحلول
منذ suid
يتغير BIT على الملفات التنفيذية فقط OID الفعالة (EUID) سوف يعمل الملف القابل للتنفيذ كما، وليس UID الحقيقي (RUID) الذي getuid()
إرجاع، بالإضافة إلى تقييد suid
البرامج النصية المفسرة (أي بداية قابلة للتنفيذ مع "#!
")، بعض قذائف مثل bash
كإجراء أمان إضافي، سيعيد EUID إلى Ruid في هذه الحالة، ستحتاج إلى استخدام المكالمة setuid(0)
في رمز C قبل تنفيذ البرنامج النصي.
انظر man
صفحات setuid
, seteuid
, getuid
, ، و geteuid
لمعرفة الدلالات الدقيقة للخصوص الحقيقية والفعالة.
(تحذيربالطبع، هذه نقطة مناسبة لنذكر أن القيود على suid
البرامج النصية في العديد من أنظمة UNIX، القذائف والمترجمين الفوريين، هناك لسبب ما، وهذا هو أنه إذا كان البرنامج النصي دقيق للغاية حول تعقيم مدخلاته وحالة البيئة عندما يتم تنفيذها، فهي خطيرة ويمكن استغلالها لأصحاب التصعيد الأمني وبعد لذلك كن حذرا جدا عند القيام بذلك. قم بتعيين الوصول إلى البرنامج النصي والمجمع الخاص بك بشكل صارم كما يمكنك، السماح فقط بهذا البرنامج النصي المحدد للغاية الذي تنوي تنفيذه، ومسح البيئة ضمن برنامج C قبل بدء البرنامج النصي، ووضع متغيرات البيئة مثل PATH
لاحتواء ما هو ضروري بالضبط بالترتيب الصحيح ولا توجد أدلة قابلة للكتابة مع الآخرين.
نصائح أخرى
شيء آخر يلاحظ هنا هو أن القيد هنا هو من باش وليس النظام * NIX نفسه. باش جعل التحقق فعليا على البرامج النصية SUID لتنفيذها فقط مع جذر euID. إذا كنت تأخذ قذيرا أكبر سنا، فغالبا ما تحصل على ما تريد خارج الصندوق. على سبيل المثال، SH لا يجعل هذا النوع من التحقق:
$ cat wrapper.c
int main(void)
{
system("/bin/sh -c whoami");
}
$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:15 wrapper
$ ./wrapper
root
مع باش:
$ cat wrapper.c
int main(void)
{
system("/bin/bash -c whoami");
}
$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:18 wrapper
$ ./wrapper
skinp
ومع ذلك، فإن إجابة توم هي عموما هي الطريقة التي يجب أن تذهب لصنع غلاف لبرامج الجذر SOID
أضف SetUID (0) في البرنامج النصي ويكمله. انها shoudl العمل بعد هذا.
$ cat wrapper.c
int main(void)
{
setuid(0);
system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ sudo chown root wrapper
$ sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$
الأمثلة غير آمنة للغاية وتتيح لأي شخص لديه بتذعة من المعرفة لتشغيل أي برنامج يريدون كمستخدم SetUID.
لا تذهب أبدا من خلال قذيفة ما لم تقم بتعفيم البيئة أولا، فإن معظم الأمثلة المعروضة هنا عرضة لها إذا تم تعيين IFS ومسار قبل تشغيله.
لماذا سودو غير قابل للتطبيق؟ يتجنب ثقوب أمنية مستعرة مثل:
bash-3.2$ cat test
#!/bin/bash
echo ima shell script durp durp
bash-3.2$ chmod +x test
bash-3.2$ ./test
heh heh
bash-3.2$
نظرا للبيئة عدم تعقيمها بشكل صحيح، على سبيل المثال في هذه الحالة:
export echo='() { builtin echo heh heh; }'
SUDO تعقيم هذه الحالة، وربما حالات حافة أخرى و GOTCHAS ستكون على ما يرام لا تكتب في مجمع Suid مخصص.