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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2023-4911 — ورشة عمل Looney Tunables لتصعيد الامتيازات المحلية (CVE-2023-4911) | Kitploit
أدوات/GitHubGitHub/kernelkrise/cve-2023-4911
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالالتعلم والتعليماستغلال الملفات الثنائيةمختبرات وتدريب عمليArchived
GitHubkernelkrise/cve-2023-4911

CVE-2023-4911

ورشة عمل Looney Tunables لتصعيد الامتيازات المحلية (CVE-2023-4911)

عرض المستودع
1839منذ 2 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2023-4911-Looney-Tunables

ورشة عمل Looney Tunables لتصعيد الصلاحيات المحلية (CVE-2023-4911) (لأغراض تعليمية فقط)

روابط:

  • فيديو IPPSEC
  • مقالة مدونة Qualsys
  • تفاصيل تقنية من Qualsys
  • سكربت بايثون لاستغلال POC
  • مصادر GLIBC
  • توثيق tunables في GLIBC

الوصف

ما هو ld.so؟

في الحوسبة، الموصِّل الديناميكي هو الجزء من نظام التشغيل الذي يقوم بتحميل وربط المكتبات المشتركة التي يحتاجها الملف القابل للتنفيذ عند تشغيله، عن طريق نسخ محتوى المكتبات من وحدة التخزين الدائمة إلى الذاكرة العشوائية (RAM)، وملء جداول القفز وإعادة توجيه المؤشرات.

على سبيل المثال، لدينا برنامج يستخدم مكتبة openssl لحساب تجزئة md5:``` $ head md5_hash.c #include <stdio.h> #include <string.h> #include <openssl/md5.h>

ld.so يحلل الملف الثنائي ويحاول العثور على مكتبة مرتبطة بـ <openssl/md5.h>```
$ ldd md5_hash                       
        linux-vdso.so.1 (0x00007fffa530b000)
        libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007f19cda00000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f19cd81e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f19ce032000)

كما نرى، يعثر على مكتبة التشفير اللازمة في /lib/x86_64-linux-gnu/libcrypto.so.3 أثناء بدء تشغيل البرنامج، يضع رمز هذه المكتبة في ذاكرة العملية ويربط جميع المراجع إلى هذه المكتبة.

ملخص

عند بدء تشغيل البرنامج، يفحص هذا المُحمّل أولاً البرنامج لتحديد المكتبات المشتركة التي يتطلبها. ثم يبحث عن هذه المكتبات، ويحمّلها في الذاكرة، ويربطها بالملف التنفيذي في وقت التشغيل. وفي هذه العملية، يحل المُحمّل الديناميكي مراجع الرموز، مثل مراجع الدوال والمتغيرات، مما يضمن تجهيز كل شيء لتنفيذ البرنامج. ونظراً لدوره، يُعد المُحمّل الديناميكي شديد الحساسية من ناحية الأمان، إذ يعمل كوده بصلاحيات مرتفعة عندما يشغّل مستخدم محلي برنامجاً بمعرّف مستخدم أو معرّف مجموعة مضبوطاً.

ما هي GLIBC Tunables؟

Tunables هي ميزة في مكتبة GNU C تتيح لمؤلفي التطبيقات والقائمين على صيانة التوزيعات تغيير سلوك مكتبة التشغيل ليتناسب مع عبء العمل لديهم. ويتم تنفيذها كمجموعة من المفاتيح التي يمكن تعديلها بطرق مختلفة. الطريقة الافتراضية الحالية للقيام بذلك هي عبر متغير البيئة GLIBC_TUNABLES عن طريق تعيينه إلى سلسلة من أزواج name=value مفصولة بنقطتين رأسيتين. على سبيل المثال، المثال التالي يفعّل فحص malloc ويضبط عتبة اقتطاع malloc على 128 بايت:``` GLIBC_TUNABLES=glibc.malloc.trim_threshold=128:glibc.malloc.check=3 export GLIBC_TUNABLES

تمرير --list-tunables إلى المُحمِّل الديناميكي لطباعة جميع الخيارات القابلة للضبط مع القيم الدنيا والقصوى:```
$ /lib64/ld-linux-x86-64.so.2 --list-tunables
glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10)
glibc.elision.skip_lock_after_retries: 3 (min: 0, max: 2147483647)
glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0xffffffffffffffff)
glibc.malloc.perturb: 0 (min: 0, max: 255)
glibc.cpu.x86_shared_cache_size: 0x100000 (min: 0x0, max: 0xffffffffffffffff)
glibc.pthread.rseq: 1 (min: 0, max: 1)
glibc.cpu.prefer_map_32bit_exec: 0 (min: 0, max: 1)
glibc.mem.tagging: 0 (min: 0, max: 255)

وصف الثغرة

في بداية تنفيذه مباشرةً، يستدعي ld.so الدالة __tunables_init() لاجتياز البيئة (في السطر 279)، بحثًا عن متغيرات GLIBC_TUNABLES (في السطر 282)؛ ولكل GLIBC_TUNABLES يعثر عليه، يقوم بنسخ هذا المتغير (في السطر 284)، ثم يستدعي parse_tunables() لمعالجة هذه النسخة وتنقيتها (في السطر 286)، وأخيرًا يستبدل GLIBC_TUNABLES الأصلي بهذه النسخة المنقّاة (في السطر 288):```C // (GLIBC ld.so sources in ./glibc-2.37/elf/dl-tunables.c) 269 void 270 __tunables_init (char **envp) 271 { 272 char *envname = NULL; 273 char *envval = NULL; 274 size_t len = 0; 275 char **prev_envp = envp; ... 279 while ((envp = get_next_env (envp, &envname, &len, &envval, 280 &prev_envp)) != NULL) 281 { 282 if (tunable_is_name ("GLIBC_TUNABLES", envname)) // searching for GLIBC_TUNABLES variables 283 { 284 char new_env = tunables_strdup (envname); 285 if (new_env != NULL) 286 parse_tunables (new_env + len + 1, envval); // 287 / Put in the updated envval. */ 288 *prev_envp = new_env; 289 continue; 290 }

الوسيطة الأولى لدالة parse_tunables() (tunestr) تشير إلى النسخة التي سيتم تعقيمها قريبًا من GLIBC_TUNABLES، بينما تشير الوسيطة الثانية (valstring) إلى متغير البيئة الأصلي GLIBC_TUNABLES (في المكدس). لتعقيم نسخة GLIBC_TUNABLES (والتي يجب أن تكون بالشكل "tunable1=`aaa:tunable2=bbb"`), تزيل parse_tunables() جميع الـ tunables الخطرة (أي tunables SXID_ERASE) من tunestr، مع الإبقاء على tunables SXID_IGNORE وNONE (في الأسطر 221-235):```C
// (GLIBC ld.so sources in ./glibc-2.37/elf/dl-tunables.c)
162 static void
163 parse_tunables (char *tunestr, char *valstring)
164 {
...
168   char *p = tunestr;
169   size_t off = 0;
170 
171   while (true)
172     {
173       char *name = p;
174       size_t len = 0;
175 
176       /* First, find where the name ends.  */
177       while (p[len] != '=' && p[len] != ':' && p[len] != '\0')
178         len++;
179 
180       /* If we reach the end of the string before getting a valid name-value
181          pair, bail out.  */
182       if (p[len] == '\0')
183         {
184           if (__libc_enable_secure)
185             tunestr[off] = '\0';
186           return;
187         }
188 
189       /* We did not find a valid name-value pair before encountering the
190          colon.  */
191       if (p[len]== ':')
192         {
193           p += len + 1;
194           continue;
195         }
196 
197       p += len + 1;
198 
199       /* Take the value from the valstring since we need to NULL terminate it.  */
200       char *value = &valstring[p - tunestr];
201       len = 0;
202 
203       while (p[len] != ':' && p[len] != '\0')
204         len++;
205 
206       /* Add the tunable if it exists.  */
207       for (size_t i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++)
208         {
209           tunable_t *cur = &tunable_list[i];
210 
211           if (tunable_is_name (cur->name, name))
212             {
...
219               if (__libc_enable_secure)
220                 {
221                   if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE)
222                     {
223                       if (off > 0)
224                         tunestr[off++] = ':';
225 
226                       const char *n = cur->name;
227 
228                       while (*n != '\0')
229                         tunestr[off++] = *n++;
230 
231                       tunestr[off++] = '=';
232 
233                       for (size_t j = 0; j < len; j++)
234                         tunestr[off++] = value[j];
235                     }
236 
237                   if (cur->security_level != TUNABLE_SECLEVEL_NONE)
238                     break;
239                 }
240 
241               value[len] = '\0';
242               tunable_initialize (cur, value);
243               break;
244             }
245         }
246 
247       if (p[len] != '\0')
248         p += len + 1;
249     }
250 }

لسوء الحظ، إذا كان متغير البيئة GLIBC_TUNABLES بالشكل "tunable1=tunable2=AAA" (حيث "tunable1" و"tunable2" هما وحدتا ضبط من نوع SXID_IGNORE، على سبيل المثال "glibc.malloc.mxfast")، فإن:

  • أثناء التكرار الأول لـ "while (true)" في parse_tunables()، يتم نسخ السلسلة بأكملها "tunable1=tunable2=AAA" في مكانها إلى tunestr (في الأسطر 221-235)، مما يملأ tunestr؛

  • في الأسطر 247-248، لا يتم زيادة p (p[len] هو '\0' لأنه لم يتم العثور على : في الأسطر 203-204) وبالتالي لا تزال p تشير إلى قيمة "tunable1"، أي "tunable2=AAA"؛

تنزيل الأداة