کلیه حقوق مطالب متعلق به Vulnerlab است. بازنشر با ذکر منبع مجاز است.

تحلیل آسیب‌پذیری CVE-2026-24061

CVE-2026-24061 - تزریق آرگومان - Argument Injection - دور زدن احراز هویت - Authentication Bypass - دور زدن احراز هویت از راه دور - Remote Authentication Bypass - پیش از احراز هویت - Pre-Authentication - اجرای کد از راه دور - Remote Code Execution -ارتقای سطح دسترسی - Privilege Escalation

۱. مقدمه

آسیب‌پذیری CVE-2026-24061 یکی از ضعف‌های امنیتی مهم شناسایی‌شده در سرویس GNU Inetutils Telnetd است که می‌تواند به مهاجم راه‌دور اجازه دهد سازوکار احراز هویت سیستم را دور بزند و بدون داشتن نام کاربری یا رمز عبور معتبر، به سطح دسترسی روت (Root) دست پیدا کند. این آسیب‌پذیری به‌دلیل مدیریت ناامن مقدار متغیر محیطی USER و انتقال آن به برنامه ورود سیستم به وجود آمده است. مهاجم می‌تواند با ارسال مقدار دست‌کاری‌شده، گزینه‌های خط فرمان مورد استفاده توسط برنامه login را تحت تأثیر قرار داده و فرایند احراز هویت را مختل کند.

اکسپلویت موفق این ضعف امنیتی می‌تواند به اجرای دستورات دلخواه، مشاهده یا تغییر فایل‌های حساس، نصب بدافزار، ایجاد دسترسی پایدار و در نهایت تصاحب کامل سیستم آسیب‌پذیر منجر شود. در این سند، نحوه شکل‌گیری آسیب‌پذیری، شرایط لازم برای بهره‌برداری، ساختار اکسپلویت، پیامدهای امنیتی و راهکارهای شناسایی و رفع آن بررسی می‌شود.

   ۱.۱ اطلاعات اجمالی آسیب‌پذیری

جدول ۱: اطلاعات اجمالی آسیب‌پذیری

 
 

 

 

شماره آسیب پذیری:

CVE-2026-24061

امتیاز (CVSS):

9.8

مولفه درگیر:

telnetd

نوع آسیب پذیری:

Argument Injection

Command-Line Argument Injection

قابلیت در صورت اکسپلویت:

دور زدن کامل احراز هویت و دریافت دسترسی Root از راه دور، با قابلیت اجرای دستورات دلخواه، مشاهده یا تغییر تمامی فایل‌های سیستم، نصب بدافزار، ایجاد دسترسی پایدار و تصاحب کامل سرور

   ۱.۲ تحلیلات از پیش ارائه شده

جدول ۲: تحلیلات از پیش ارائه شده

 
 

 

 

نام تحلیلگر

تاریخ انتشار

لینک

OffSec Team

Jan 30, 2026

https://www.offsec.com/blog/cve-2026-24061

   ۱.۳ وضعیت Patch و نسخه‌های آسیب‌پذیر

جدول ۳: وضعیت Patch و نسخه‌های آسیب‌پذیر

 
 

 

 

نسخه

وضعیت

قبل از 1.9.3

در رکورد CVE به عنوان بازه اصلی آسیب‌پذیر نیامده است.

1.9.3 تا 2.7

آسیب‌پذیر

2.8 و جدیدتر

مسیر رفع‌شده / نسخه پیشنهادی برای ارتقا

در محیط‌های عملیاتی باید نسخه بسته توزیع لینوکس هم بررسی شود. گاهی توزیع‌ها patch امنیتی را به نسخه قدیمی‌تر backport می‌کنند، بنابراین تنها عدد نسخه upstream همیشه برای تصمیم‌گیری کافی نیست.

۲. خلاصه اجرایی

سرویس telnetd هنگام آغاز یک نشست Telnet، فرایند مذاکره پروتکل (Protocol Negotiation) را با کلاینت انجام می‌دهد. در این مرحله، کلاینت می‌تواند با استفاده از گزینه‌های ENVIRON یا NEW-ENVIRON برخی متغیرهای محیطی را برای سرور ارسال کند. در نسخه‌های آسیب‌پذیر، متغیر USER نیز از طریق این سازوکار پذیرفته شده و در محیط اجرای فرایند قرار می‌گیرد.

مشکل اصلی زمانی رخ می‌دهد که telnetd برای اجرای برنامه login یک رشته متنی شامل فرمان و آرگومان‌های آن ایجاد می‌کند. در شرایط عادی، مقدار USER باید صرفاً به‌عنوان یک داده، یعنی نام کاربری، پردازش شود؛ اما در پیاده‌سازی آسیب‌پذیر، این مقدار مستقیماً در رشته فرمان قرار می‌گیرد.

پس از ایجاد رشته فرمان، telnetd آن را با استفاده از تابع argcv_get تجزیه کرده و دوباره به آرایه‌ای از آرگومان‌ها یا argv تبدیل می‌کند. در نتیجه، اگر مقدار USER شامل فاصله، خط تیره یا رشته‌هایی مشابه گزینه‌های خط فرمان باشد، محتوای آن دیگر به‌صورت یک مقدار واحد باقی نمی‌ماند و می‌تواند به چند آرگومان اجرایی مستقل تبدیل شود. برای نمونه، در سناریوی آزمایشگاهی می‌توان مقدار متغیر را به‌صورت زیر تنظیم کرد:

				
					USER="-f root"
				
			

این مقدار در ابتدا تنها یک رشته ذخیره‌شده در محیط فرایند است؛ اما پس از قرار گرفتن در رشته فرمان و تجزیه‌شدن توسط argcv_get، به دو آرگومان جداگانه تبدیل می‌شود:

  1. -f
  2. root

از دید برنامه login، این مقادیر دیگر بخشی از یک نام کاربری نیستند. گزینه -f می‌تواند به‌عنوان درخواست ورود سریع یا اعلام انجام‌شدن قبلی احراز هویت تفسیر شود و مقدار root نیز نام حساب کاربری هدف را مشخص می‌کند. به این ترتیب، داده‌ای که باید صرفاً به‌عنوان نام کاربری پردازش می‌شد، به گزینه خط فرمان تبدیل شده و می‌تواند فرایند عادی احراز هویت را دور بزند. ریشه این آسیب‌پذیری، ترکیب ناامن داده‌های کنترل‌شده توسط کاربر با یک رشته فرمان و تجزیه مجدد آن به آرگومان‌های اجرایی است. این الگو از نظر مفهومی نوعی تزریق آرگومان (Argument Injection) خط فرمان محسوب می‌شود.

۳. توضیح فنی

Telnet client در مرحله مذاکره پروتکل (Protocol Negotiation)، با استفاده از گزینه‌های  TELOPT_NEW_ENVIRON یا TELOPT_OLD_ENVIRON مقدار متغیرهای محیطی را برای telnetd ارسال می‌کند. این داده‌ها در تابع suboption واقع در فایل telnetd/state.c پردازش می‌شوند. در سناریوی آسیب‌پذیر، مقدار ارسال‌شده برای متغیر USER با استفاده از فراخوانی زیر داخل محیط (Environment) فرایند قرار می‌گیرد:

				
					setenv("USER", "-f root", 1)
				
			

در ادامه، هنگام پردازش نگهدارنده مکان (Placeholder) مربوط به %U در تابع _var_short_name، مقدار USER از طریق getenv(“USER”) خوانده می‌شود. این مقدار سپس توسط تابع expand_line داخل login_invocation قرار می‌گیرد و بخشی از command string نهایی می‌شود. برای نمونه، اگر مقدار ‘USER’ برابر با f root- باشد، بخشی از command string ساخته‌شده به شکل زیر خواهد بود:

				
					-f root
				
			

پس از آن، telnetd این command string را با استفاده از تابع argcv_get دوباره پارس (Parse) کرده و به argc و argv تبدیل می‌کند:

				
					argcv_get(command, "", &argc, &argv)
				
			

در این مرحله، مقدار f root- دیگر یک string واحد محسوب نمی‌شود و به دو argument مستقل، یعنی f- و root، تقسیم می‌شود. در نهایت، برنامه مقصد با فراخوانی زیر اجرا می‌شود:

				
					execv(argv[0], argv)
				
			

به این ترتیب، مقداری که در ابتدا فقط به‌عنوان یک environment variable تحت کنترل کلاینت (Client) دریافت شده بود، پس از گسترش و پارس‌شدن مجدد، به آرگمان‌های کامندلاین (Command-Line Argument) برنامه login تبدیل می‌شود. این فرایند باعث می‌شود optionهایی مانند f- مستقیماً به login منتقل شوند و در شرایط آسیب‌پذیر، مسیر عادی احراز هویت (Authentication) را تحت تأثیر قرار دهند.

   ۳.۱ مسیر داده آسیب‌پذیر

				
					Telnet client
  TELOPT_NEW_ENVIRON / TELOPT_OLD_ENVIRON
  io_drain()                         [telnetd/utility.c]
  telrcv()                           [telnetd/state.c]
  suboption()                        [telnetd/state.c]
  setenv(varp, valp, 1)              [libc]
       USER="-f root"

  start_login()                      [telnetd/pty.c]
  expand_line(login_invocation)      [telnetd/utility.c]
      _expand_block()
      _expand_cond()
      _expand_var()
      _var_short_name()
      getenv("USER")                [libc, case 'U']

  expanded command:
       usr/bin/login ... -f root

  argcv_get(cmd, "", &argc, &argv)   [called from start_login()]
  execv(argv[0], argv)               [libc]

				
			

۴. آزمایشگاه

آزمایشگاه این پروژه، که همراه این گزارش ضمیمه شده، به صورت local-only طراحی شده است. هر دو سرویس داکر (Docker) فقط روی 127.0.0.1 بایند (Bind) می‌شوند و از بیرون میزبان قابل دسترسی نیستند. نسخه آسیب‌پذیر GNU Inetutils 2.7 از منبع (Source) بیلد گرفته می‌شود.

در این آزمایشگاه دو variant وجود دارد. variant اول recorder-telnetd است که مسیر login آن به باینری lab-login-recorder اشاره می‌کند و برای تایید (Verification) استفاده می‌شود و variant دوم original-login-telnetd است که از باینری login واقعی داخل کانتینر استفاده می‌کند.

جدول ۴: سرویس‌های آزمایشگاه

 
 

 

 

سرویس compose

پورت میزبان

مسیر login کامپایل‌شده

کاربرد

recorder-telnetd

127.0.0.1:2323

/usr/local/bin/lab-login-recorder

مسیر امن پیش‌فرض برای ثبت argv

original-login-telnetd

127.0.0.1:2324

/bin/login

مقایسه با login واقعی داخل کانتینر

   ۴.۱ نقشه فایل‌های آزمایشگاه

جدول ۵: نقشه فایل‌های آزمایشگاه

 
 

 

 

مسیر

نقش

evidence/

CVE metadata، hashها، diffها، disassembly و traceهای GDB

lab/Dockerfile

ساخت imageهای GNU Inetutils 2.7 با login path قابل تنظیم

lab/docker-compose.yml

تعریف دو سرویس local-only

lab/login-recorder.sh

ابزار امنی که فقط argv را چاپ و ثبت می‌کند

lab/entrypoint.sh

ثبت lab-info و اجرای telnetd پشت socat

scripts/local_verify.py

PoC

 
 

 

 

   ۴.۲ اجرای recorder

همان‌طور که گفته شد دو داکر ایمیج با دو باینری مختلف به‌عنوان باینری login در این آزمایشگاه قرار داده شده است. برای اجرای داکر ایمیج مربوط به recorder که صرفا اثبات کننده اجرای این اکسپلویت می‌باشد:

				
					cd lab
env -u LD_PRELOAD docker compose up --build recorder-telnetd
env -u LD_PRELOAD python3 scripts/local_verify.py

				
			

   ۴.۳ خروجی مورد انتظار

فایل lab/output/recorder/login-recorder.log فقط خط argv را نگه می‌دارد و پیام تایید LAB_CVE_2026_24061_CONFIRMED توسط verifier تولید می‌شود، نه توسط recorder. این تفکیک باعث می‌شود ابزار login آزمایشگاه فقط مشاهده‌گر باشد و منطق تایید در اسکریپت جدا بماند.

				
					argv: [-p] [-h] [container-hostname] [-f] [root]
LAB_CVE_2026_24061_CONFIRMED
meaning=telnetd expanded remote USER data into login argv

				
			
CVE-2026-24061 - تزریق آرگومان - Argument Injection - دور زدن احراز هویت - Authentication Bypass - دور زدن احراز هویت از راه دور - Remote Authentication Bypass - پیش از احراز هویت - Pre-Authentication - اجرای کد از راه دور - Remote Code Execution -ارتقای سطح دسترسی - Privilege Escalation
تصویر ۱: اجرا و خروجی recorder

   ۴.۴ اجرای original-login

برای اجرای داکر ایمیج مربوط به original-login که نمونه واقعی از انجام حمله می‌باشد:

				
					cd lab
env -u LD_PRELOAD docker compose up --build original-login-telnetd	
env -u LD_PRELOAD python3 scripts/original_login_root_check.py

				
			


این سرویس روی 127.0.0.1:2324 در میزبان bind می‌شود و telnetd آن با PATH_LOGIN=/bin/login بیلد شده است. برای توقف آزمایشگاه، از env -u LD_PRELOAD docker compose down در مسیر lab استفاده می‌شود. پس از توقف، docker compose ps باید هیچ سرویس فعالی را نشان ندهد.

تصویر ۲: اجرا و خروجی original-login

۵. تحلیل کد و علت اصلی (Root Cause)

   ۵.۱ دریافت USER از Telnet ENVIRON

در نسخه 2.7، تابع suboption در telnetd/state.c گزینه‌های TELOPT_NEW_ENVIRON و TELOPT_OLD_ENVIRON را parse می‌کند. نام متغیر و مقدار آن از بافر suboption جدا می‌شوند و با setenv(varp, valp, 1) وارد محیط (Environment) فرایند می‌شوند. برای پیلود (Payload) آزمایشگاه، varp برابر USER و valp برابر f root- است. طبق ABI در معماری x86-64، فراخوانی setenv آرگومان اول را در rdi، آرگومان دوم را در rsi و آرگومان سوم را در edx دریافت می‌کند. بنابراین:

  • rdi به USER اشاره دارد.
  • rsi به f -rootاشاره دارد.
  • edx به 1 اشاره دارد.

نکته مهم این است که telnetd در شروع کار یک unsetenv(“USER”) انجام می‌دهد، اما این کار کافی نیست، چون مذاکره (Negotiation) تلنت بعدا دوباره می‌تواند USER را از شبکه وارد محیط کند.

   ۵.۲ قالب آسیب‌پذیر login

telnetd برنامه login را مستقیما اجرا نمی‌کند؛ بلکه ابتدا خط فرمان اجرای آن را از روی یک رشته قالب می‌سازد. این قالب در فایل telnetd/telnetd.c و در متغیر سراسری login_invocation تعریف شده است. مقدار پیش‌فرض آن به‌شکل زیر است:

				
					PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
				
			

این رشته یک قالب شبیه به printf است. همانطور که پیش‌تر توضیح داده شد، هنگامی که یک نشست جدید آغاز می‌شود، تابع expand_line توکن‌های موجود در قالب را با مقادیر واقعی جایگزین می‌کند. سپس رشته نهایی با استفاده از تابع argcv_get و بر اساس فاصله‌ها به آرایه‌ای از آرگومان‌ها، یعنی argv، تبدیل می‌شود. در پایان نیز telnetd با فراخوانی execv برنامه login را اجرا می‌کند.

      ۵.۲.۱ بخش‌های ثابت قالب
  • PATH_LOGIN: مسیر برنامه login است که هنگام build تعیین می‌شود. در آزمایشگاه recorder این مقدار برابر با مسیر زیر است:
				
					/usr/local/bin/lab-login-recorder
				
			

در آزمایشگاه original-login نیز مقدار آن برابر است با:

				
					/bin/login
				
			
۵.۲.۲ آرگومان‌های فرمتینگ
  • p- به برنامه login می‌گوید environment فعلی را حفظ کند.
  • h %h- نام میزبان راه‌دور را به برنامه loginارسال می‌کند. در این عبارت، h% هنگام اجرای expand_line با نام واقعی میزبان جایگزین می‌شود.
  • u{-f %u}{%U}?% ساختار کلی این عبارت به‌شرح زیر است:
				
					%?متغیر{اگر مقدار داشت}{اگر مقدار نداشت}
				
			

بررسی می‌کند که آیا متغیر داخلی %u، یعنی user_name، مقدار دارد یا خیر:

  • اگر داشت:
				
					-f %u
				
			
  • اگر نداشت:
				
					%U
				
			

و U% با مقدار متغیر محیطی USER  جایگزین می‌شود.

جدول ۶: معنای توکن

Token

معنا

u%

نام کاربر احراز شده یا autologin معتبر

U%

مقدار environment با نام  USER

u{A}{B}?%

اگر %u موجود باشد A، وگرنه  B

 
 

 

 

در مسیر آزمایشگاه، autologin معتبر وجود ندارد. پس شرط %u برابر با false می‌شود و شاخه {U%} اجرا می‌شود. چون USER برابر f root- است، command string نهایی شامل همین دو token می‌شود. منظور از دو توکن دو آرگومان f- و root- می‌باشد.

   ۵.۳ تبدیل command string به argv

تابع start_login در telnetd/pty.c ابتدا scrub_env را اجرا می‌کند، سپس expand_line(login_invocation) را صدا می‌زند. خروجی expand_line یک رشته (String) است. قطعه کد زیر، شامل تابع مربوط به انجام فرایند لاگین به‌واسطه command line آلوده لاگین می‌باشد.

				
					void
start_login (char *host, int autologin, char *name)
{
	char *cmd;
	int argc;
	char **argv;

(void) host;	/* Silence warnings. Diagnostic use? */
(void) autologin;
(void) name;

scrub_env ();	/* Set the environment variable "LINEMODE" to indicate our linemode */
if (lmodetype == REAL_LINEMODE)
	setenv ("LINEMODE", "real", 1);
else if (lmodetype == KLUDGE_LINEMODE || 1modetype == KLUDGE_OK)
	setenv ("LINEMODE", "kludge", 1);

cmd = expand_line (login_invocation);
if (!cmd)
	fatal (net, "can't expand login command line");
argcv_get (cmd, "", &argc, &argv);
execv(argv[0], argv);
syslog (LOG_ERR, "%s: %m\n", cmd);
fatalperror (net, cmd);
}
				
			

سپس:

				
					argcv_get(cmd, "", &argc, &argv)
				
			

اجرا می‌شود و رشته (String) ساخته‌شده با قواعد whitespace به argv تبدیل می‌شود. در نهایت execv(argv[0], argv) اجرا می‌شود. مشکل اصلی این است که مقدار USER بدون ساختار محافظتی وارد رشته شده و سپس دوباره پارس می‌شود. اگر مقدار USER شامل فاصله باشد، فاصله به جداکننده argv تبدیل می‌شود. 

جدول ۷: مراحل آسیب‌پذیری

 
 

 

 

مرحله

مقدار

قبل از argcv_get

یک string شامل f root-

بعد از argcv_get

دو token جدا: f- و root

قبل از execv

argv آماده است و اثر USER کامل شده است

۶. اثر روی حافظه و وضعیت فرایند

این آسیب‌پذیری تخریب حافظه (Memory Corruption) نیست. هیچ بازنویسی (Overwrite) کنترل‌شده‌ای روی آدرس بازگشتی (Return Address)، rbp ذخیره‌شده (Saved rbp) یا اشاره‌گر تابع (Function Pointer) دیده نشده است. جریان کنترلی (Control Flow) طبیعی باقی می‌ماند و مسیر زیر طی می‌شود.

				
					 start_login -> expand_line -> argcv_get -> execv 
				
			

جدول ۸: نقش هر بخش در این آسیب‌پذیری

 
 

 

 

بخش

نقش

environment

نگهداری USER=-f root

login_invocation

تمپلیت اجرای login

remote_hostname

مقدار h%

user_name

مقدار u%؛ وقتی NULL باشد شاخه U% انتخاب می‌شود.

subpointer/subend

بافر suboption در parser تلنت

cmd

رشته ساخته‌شده پیش از split

argv

آرایه نهایی آرگومان‌ها برای execv

 

۷. اصلاحات نسخه ۲.۸

در نسخه ۲.۸ چند دفاع هم‌زمان اضافه شده است. تمپلیت اجرای login تغییر کرده و از جداکننده — استفاده می‌کند. این جداکننده پایان گزینه‌ها را مشخص می‌کند تا مقدارهای بعدی، حتی اگر با – شروع شوند، به عنوان operand تفسیر شوند نه option. علاوه بر این، تابع پالایش داده (Sanitize Function) در utility.c اضافه شده است. این تابع مقدارهایی را که با – شروع می‌شوند یا شامل کاراکتر‌های فاصله‌ای (Whitespace) و متاکاراکتر (Metacharacter) حساس هستند، به رشته (String) خالی تبدیل می‌کند. همچنین محیط (Environment) پیش‌فرض محدودتر شده و setenv فقط برای متغیرهای allowlist شده با گزینه accept-env– انجام می‌شود.

جدول ۹: اصلاحات انجام شده

 
 

 

 

حالت

2.7

2.8

autologin دارد

f %u-

-f — %u

autologin ندارد

U%

U%–

پذیرش environment

بدون allowlist پیش‌فرض

فقط با accept-env

sanitization

ناکافی برای این مسیر

sanitize برای چند توکن حساس

 

۸. منابع

				
					1.	https://cveawg.mitre.org/api/cve/CVE-2026-24061
2.	https://lists.gnu.org/archive/html/bug-inetutils/2026-01/msg00004.html
3.	https://www.openwall.com/lists/oss-security/2026/01/20/2
4.	https://www.openwall.com/lists/oss-security/2026/01/22/1
5.	https://ftp.gnu.org/gnu/inetutils/
6.	https://codeberg.org/inetutils/inetutils/commit/fd702c02497b2f398e739e3119bed0b23dd7aa7b
7.	https://codeberg.org/inetutils/inetutils/commit/ccba9f748aa8d50a38d7748e2e60362edd6a32cc

				
			

مقالات مرتبط

CVE-2026-2757 Mozilla Firefox Firefox ESR Mozilla Thunderbird WebRTC WebRTC GMP Video Decoder H.264 Decoder Out-of-Bounds Read

تحلیل آسیب پذیری CVE-2026-2757

۱. مقدمه مرورگرهای مدرن فقط نمایش‌دهنده صفحات HTML نیستند؛ آن‌ها مجموعه‌ای پیچیده از تجزیه‌کننده‌ها (Parser)، رمزگشاها (Decoder)، سندباکس (Sandbox)، کامپایلرهای JIT، رابط‌های برنامه‌نویسی کاربردی سیستم‌عامل (API) و مسیرهای شبکه‌ای هستند

والنرلب - vulnerlab - تحلیل آسیب‌پذیری - Vulnerability analysis -

آسیب پذیری‌های تحلیل شده سال ۲۰۲۴

هدف از تحلیل آسیب‌پذیری شناسایی، ارزیابی و اولویت‌بندی نقاط ضعف در سامانه‌ها، نرم‌افزارها و زیرساخت‌های فناوری است تا پیش از آن‌که مهاجمان بتوانند از آن‌ها سوءاستفاده کنند، اقدامات پیشگیرانه و

FFmpeg - CVE-2026-8461 - PixelSmash - libavcodec - Out-of-Bounds Write - آسیب‌پذیری FFmpeg آسیب‌پذیری PixelSmash آسیب‌پذیری FFmpeg MagicYUV

تحلیل آسیب‌ پذیری CVE-2026-8461

۱. مقدمه (Introduction) آسیب‌پذیری CVE-2026-8461 که با نام PixelSmash نیز شناخته می‌شود، یک آسیب‌پذیری نوشتن خارج از محدوده حافظه (Out-of-Bounds Write) با شناسه CWE-787 در کتابخانه libavcodec نرم‌افزار FFmpeg است.

wpChatIcon
wpChatIcon