آسیبپذیری Command Injection؛ دربست تا دروازهی بزرگ دسترسی
آسیبپذیری Command Injection شاید در نگاه اول آسیبپذیری پرخطری به نظر نیاید. اما Command Injection همان فلفلیست که نباید به ظاهرش نگریست و گولش را خورد، چراکه چه کارهایی که از این آسیبپذیری برنمیآید.
شاید آسیبپذیری Command Injection بهتنهایی ضرر خاصی برای سامانه به دنبال نداشته باشد و کمخطر به نظر برسد.
اما آنجا که مجاورت و همجواری با سایر آسیبپذیریها نصیبش گردد، سنسورها به صدا در میآیند.
و خبر از قرارگرفتن شکارچی در دوقدمی دسترسی به خط فرمان، ترمینال یا شل سامانهی هدف را میدهد.
در این مطلب به آسیبپذیری آبزیرکاه Command injection میپردازیم. این آسیبپذیری میتواند برای شکارچی و هکر کلاهسفید دسترسی مستقیمی به سرور قربانی ایجاد کند، امکان اجرای کد از راه دور را برایش فراهم آوَرَد و زمینهساز اکسپلویت و بهرهجویی از سایر آسیبپذیریهای موجود در سامانه شود.
آسیبپذیری Command Injection، از آن دسته آسیبپذیریهایی است که با عبور از مسیر ورودی کاربر میتوانیم به دسترسی مستقیم و غیرمستقیم به خط فرمان سامانهها دست پیدا کنیم. البته در مسیر باید تجهیزات پزشکی لازم را جهت تزریق دستورهای موردنظر به سیستمعامل بههمراه داشته باشیم تا بتوانیم به سرور قربانی در سطوح مختلف دسترسی پیدا کنیم.
مطلبی که با هم مطالعه میکنیم، برداشتی آزاد از چندین منبع معتبر است. بناست نگاهی به موارد مرتبط با آسیبپذیری Command Injection داشته باشیم. با ما همراه باشید ؛)
یک حملهی Command Injection مانند بسیاری از حملات دیگر، شامل سه مرحلهی "پیش از کشف"، "کشف" و "اکسپلویت" است؛ در مرحلهی پیش از کشف، از معرفی آسیبپذیری Command Injection شروع میکنیم و اطلاعاتی از قبیل نام و نوع سرویسهای در حال اجرای سامانه را به دست میآوریم. در مرحلهی کشف، وجود آسیبپذیری Command Injection را بررسی میکنیم و با روشهای کشف آسیبپذیری Command Injection آشنا میشویم. سپس، به این موضوع میپردازیم که پس از اطمینان از وجود آسیبپذیری Command Injection، چگونه آن را اکسپلویت کنیم؟ و از چه ابزاری میتوانیم برای کشف و اکسپلویت این آسیبپذیری کمک بگیریم؟
آسیبپذیری Command Injection چیست؟ و کیست؟
ماهیت آسیبپذیریهای دستهی Injection را میتوان ایجاد انحراف در روند عادی عملیاتهای یک سامانه دانست. عامل این انحراف نیز همان مواردی هستند که باید به سامانه و در روند عادی تزریق شوند. داستان حملهی مبتنی بر آسیبپذیری Command Injection از ارسال دستورهای خط فرمان مانند whoami و cp از سمت شکارچی به سمت سرور قربانی آغاز میشود. این کار معمولا از طریق برنامهای کاربردی مانند یک وبسایت که سرور بر روی آن درحالاجرا و آسیبپذیر است، انجام میشود. این حمله بر پایهی نقص در اعتبارسنجی یا Validation ورودیهای مختلف سامانه، از جمله فرمهای ورودی کاربر، استوار است. در حملهی Command Injection مهاجم میتواند با تزریق دستورهایی از طریق ورودیهای سامانه، به خط فرمان سرور قربانی دسترسی پیدا کند. به دنبال آن نیز امکان جمعآوری اطلاعات از سرور قربانی و همچنین اجرای کد از راه دور یا RCE بر روی سرور قربانی برایش فراهم میشود.
میتوانید دربارهی کنترل ورودیها، خطرات ناشی از عدم کنترل ورودیهای کاربر و چگونگی کنترل آنها در مطلب «کنترل ورودی کاربر، چرا و چگونه؟» بیشتر بخوانید.
آسیبپذیری Command Injection چه است؟ و چه نیست؟
آسیبپذیری Command Injection و آسیبپذیری Code Injection هر دو از خانوادهی آسیبپذیریهای تزریقی و Injection هستند. این دو نوع آسیبپذیری با وجود شباهتها، تفاوتهای مهمی با یکدیگر دارند:
در آسیبپذیری Code Injection، شکارچی میتواند کدی را لابهلای کدهای یک برنامهی عادی درحالاجرا در سرور قربانی تزریق کند. اما در آسیبپذیری Command Injection، شکارچی میتواند دستوری را لابهلای دستورهای عادی یک برنامهی درحالاجرا یا در حالت غیراجرا تزریق کند.
آسیبپذیری Command Injection دسترسی بهتر و بیشتری به سرور قربانی را برای شکارچی فراهم میکند؛ در آسیبپذیری Code Injection شکارچی ارتباط مستقیمی با کدمنبع یا Source Code سرویسها و برنامههای در حال اجرا یا در حالت غیر اجرا دارد ولی به دلیل قدرت و تاثیر کمتر تغییر کدها، نمیتواند طیف گستردهای از دستورهای مختلف را بر روی سرور موردنظر اجرا کند. در آسیبپذیری Command Injection شکارچی ارتباط مستقیمی با کدمنبع یا Source Code سرویسها و برنامههای در حال اجرا ندارد ولی به دلیل قدرت، تاثیر و وسعت اثرگذاری بیشتری که شکارچی با ارسال دستور در اختیار دارد، میتواند طیف گستردهای از دستورهای مختلف را بر روی سرور موردنظر اجرا کند.
در حملهی Command Injection شکارچی میتواند از دستورهای قابلاجرا برای انجام کارهایی مانند جمعآوری اطلاعات و دستکاری تنظیمات سرویسهای در حال اجرا بر روی سرور قربانی استفاده کند، به عنوان نمونه؛ دسترسی به سرویس مدیریت پایگاهداده و همچنین دسترسی به کدهایی که سرور قربانی میزبان آنهاست و در حالت عادی از بیرون قابلمشاهده نیستند. آسیبپذیریهای تزریقی یا Injection انواع مختلفی دارند. در مطلب «آسیبپذیری SQL Injection؛ راهبردها و ترفندها» میتوانید با عضو دیگری از خانوادهی آسیبپذیریهای تزریقی آشنا شوید.
آسیبپذیری Command Injection از چه میزان ارزش و جایگاهی در میان آسیبپذیریها برخوردار است؟
آسیبپذیری Command Injection به این دلیل که امکان اجرای دستور در خط فرمان سرور قربانی را برای شکارچی فراهم میکند، در دستهی آسیبپذیریهای خطرناک جای میگیرد. البته در چند سال اخیر و با ظهور معماریهای جدیدی مانند RESTFul، کشف این آسیبپذیری برای هکرها سختتر شده است. چراکه در اغلب معماریهای جدید، پردازشهای سمت کاربر مجزا در نظر گرفته شده اند و ارتباط بین سمت کاربر و سمت سرور از طریق ردوبدلکردن درخواستهای HTTP با یکدیگر انجام میشود. همچنین کدنویسی برنامهها به سمت استفاده از کتابخانههای عمدتا متنباز سوق داده شدهاند و دیگر کمتر پیش میآید که برنامهنویسی ورودی کاربر در فرم را به شکل مستقیم در سمت سرور به صورت دستور اجرا کند. اگر هم نیاز باشد که یک ورودی که از سمت کاربر آمده است اجرا شود، برنامهنویس این کار را به کتابخانههای مرتبط با کار با خط فرمان میسپارد و خیال خودش را راحت میکند؛ این کتابخانهها به طور خودکار اعتبارسنجیهای لازم را قبل از اجرا انجام میدهند. گرچه با این تفاسیر کشف این آسیبپذیری سختتر شده است، اما هنوز هم بسیاری از سامانهها با سهلانگاری در کنترل ورودیها، این امکان را در اختیار شکارچی قرار میدهند تا در نقش کاربر وارد شود و با دستورهای مختلفی که در ورودی وارد میکند، دسترسیهای سطح بالایی را از سرور قربانی بگیرد.
در ارزشگذاری آسیبپذیریهای مختلف، متغیرهای مختلفی موثرند. در مطلب «چگونه آسیبپذیری در راورو ارزشگذاری میشود؟» میتوانید دربارهی معیارهای ارزشگذاری آسیبپذیریهای مختلف بیشتر بخوانید.
چگونه میتوان وجود آسیبپذیری Command Injection را بررسی کرد؟
همانطور که پیشتر گفتیم: آسیبپذیری Command Injection، بر پایهی نفوذ شکارچی به سرور قربانی و اجرای دستور در خط فرمان سرور قربانی است. بنابراین، نیاز است که به عنوان شکارچی تمام تلاش خود را بر روی اجرای دستور خط فرمان از طریق ورودیهایی بگذاریم که حدس میزنیم در سمت سرور امکان اجرا، آن هم به صورت دستور را خواهند داشت.
معمولا عملگرهای منطقی (Logic Operators) و جداکنندهها (Separators) در این مواقع بسیار کاربردی هستند، چون امکان اجرای دستورهای دیگر را در ادامهی دستور قبلی برای ما فراهم میکنند. یا با کمک آنها میتوانیم دستوری را لابهلای دستورهای دیگر تزریق کنیم. بر این اساس کاراکترهای زیر میتوانند به ما کمک بسیاری بکنند:
• &
• &&
• |
• ||
همانطور که مشخص است با استفاده از مورد اول یکی از سادهترین راههای کشف آسیبپذیریای که میتوان امتحان کرد به صورت زیر است:
اگر دقت کنید یک جداکنندهی & در ابتدا و یکی در انتها قرار داده شده است. این کار بدین منظور است که این دستور تزریقشده را از دستورهای قبل و بعدش جدا کنیم تا مشکلی در اجرای دستورهای قبل و بعد از آن به وجود نیاید. در این دستور قصد داریم امتحان کنیم که با ارسال ping به خود سرور قربانی، آیا پاسخی دریافت میکنیم؟ یا خیر؟
اگر پاسخی دریافت نکنیم بدین معنی است که این ورودی آسیبپذیر نیست.
اما اگر پاسخی دریافت کنیم و آن پاسخ مشابه مثال زیر باشد، به ما خبر از وجود آسیبپذیری در سمت سرور قربانی را میدهد:
آیا همیشه واکنش سیستم قربانی به تزریق دستور توسط شکارچی قابلمشاهده است؟
در بعضی موارد، با تزریق یک دستور و اجرای آن در سمت سرور لزوما پاسخی برگردانده نمیشود. اما این به معنای عدم وجود آسیبپذیری Command Injection نیست. برای اینکه در این شرایط نیز بتوانیم این آسیبپذیری را اکسپلویت کنیم میتوانیم از روش عمومی معروف به blind استفاده کنیم. در این روش سعی میکنیم پاسخ دستورها را از روش دیگری مانند نوشتن پاسخ دستور در یک فایل قابلدسترس از بیرون و یا ایجاد یک dns lookup ببینیم
به عنوان نمونه، از آنجا که میدانیم پاسخ دستورهایی که تزریق میکنیم به سمت ما برگردانده نمیشوند، دستور whoami که نام کاربر را نمایش میدهد را، به صورت زیر تزریق میکنیم:
درواقع در این دستور، به کمک استفاده از کاراکتر < پاسخ دستور را در فایلی به نام whoami.txt ذخیره میکنیم.
اما حالا چگونه میتوانیم به این فایل دسترسی پیدا کنیم؟
برای پاسخ به این سوال، ابتدا باید بدانیم که در وبسرورهای مختلف، فولدری برای فایلهای ایستا یا ثابت مانند تصاویر و ... وجود دارد. اگر فایلی در این فولدر قرار داشته باشد، میتوان به عنوان نمونه به صورت زیر به آن دسترسی پیدا کرد:
بنابراین دلیل قرارگرفتن آدرس /var/www/static این است که این آدرس در سرور قربانی، همان آدرس فولدر فایلهای ایستای وبسرور فعال بر روی سرور قربانی است.
در روش دیگری نیز میتوانیم با ایجاد یک dns lookup پاسخ دستورهایی که تزریق میکنیم را ببینیم. توجه داشته باشید که در این روش نیاز داریم دامنهی ثبتشده و معتبری داشته باشیم.
در این روش، با تزریق دستوری به صورت زیر، یک dns lookup ایجاد کردهایم. حالا دستور مدنظر خود را به عنوان یک زیردامنه جایگذاری میکنیم. چه اتفاقی میافتد؟ پاسخ دستور جایگذاریشده به عنوان یک زیردامنه به سوی دامنهی ما روانه میشود و ما این امکان خواهیم داشت که پاسخ دستور را در قسمت زیردامنه مشاهده کنیم.
به عنوان نمونه، اگر ما یک دامنه به آدرس زیر داشته باشیم:
تزریق دستوری به شکل زیر میتواند پاسخ دستور whoami را به عنوان یک زیردامنه ارسال کند:
و بدین ترتیب میتوانیم پاسخ دستور را به شکل زیر ببینیم:
چگونه و تا چه میزان میتوان آسیبپذیری Command Injection را اکسپلویت کرد؟
اکنون، پس از کشف وجود آسیبپذیری نوبت اکسپلویت آن است.
یک فروشگاه اینترنتی یا Marketplace را فرض میکنیم که مشخصات محصولات عرضهشده توسط عرضهکنندههای مختلف را به کاربر نمایش میدهد. برای انجام این کار به صورت زیر دو پارامتر productID و storeID لازم است:
این فروشگاه اینترنتی اطلاعات لازم هر محصول را با فیلترهای تعیینشده با پرسش یا Query از چند سیستم نسبتا قدیمی متصل به سرور این فروشگاه اینترنتی به دست میآورد. این سیستمهای قدیمی به طور مستقیم به وسیله یک کد به زبان پرل از طریق خط فرمان اطلاعات پایگاهداده را به دست میآورند. به همین دلیل، سامانهی فروشگاه پارامترها را به ترتیب زیر به سمت آن سیستمها ارسال میکند، آن سیستمها موارد زیر را به صورت یک دستور اجرا میکنند و نتایج را به فروشگاه اینترنتی باز میگردانند:
از آنجا که ما این فروشگاه اینترنتی را بدون هیچگونه ابزار دفاعی برای مقابله با حملهی Command Injection در نظر گرفتهایم، پس دست شکارچی در تزریق دستور بازتر است.
شکارچی با ارسال مقدار زیر از طریق ورودی یک فرم، میتواند به سادگی دستور مدنظر خود را به دستور اصلی تزریق کند:
اگر این دستور را با دستور اصلی مقایسه کنیم، متوجه میشویم که:
میبینید؟ دستور مدنظر ما جایگزین 381 در دستور اصلی شده است و یا به عبارت دیگر ما دستور مدنظر خود را در محل پارامتر productID تزریق کردهایم.
پس از ارسال دستور، حالا پاسخی که دریافت کردهایم به صورت زیر است:
برای اینکه متوجه شویم که هرکدام از این سه خط به چه معناست و چرا ارزشمند است، با دقت بیشتر هر خط را بررسی میکنیم:
• در دستور اصلی برای پارامتر productID عدد 381 ارسال میشد که ما به جای آن دستور خود را تزریق کردیم و طبیعتا با خطای خط اول مواجه میشویم.
• در خط دوم، رشتهای که ما در دستور تزریقشده قرار داده بودیم تا نمایش داده شود، به درستی نمایش داده شده است. از این اتفاق نتیجه میگیریم که امکان تزریق دستورهای بیشتری نیز فراهم است.
• در خط سوم که پس از کاراکتر جداکنندهی & قرار گرفته است، عدد 29 که پارامتر storeID است به عنوان یک دستور اجرا کرده و چون 29 یک دستور نیست خطای «دستور یافت نشد» بازگشته است.
از چه ابزاری میتوان برای کشف و اکسپلویت Command Injection کمک گرفت؟
Commix
این ابزار به زبان پایتون نوشته شده است. شیوهی کار ابزار Commix به این صورت است که آدرس نقطهی آسیبپذیر را دریافت میکند. البته لازم است در آدرس نقطهی آسیبپذیر سامانه، محل تزریق مشخص شده باشد. سپس خود ابزار با استفاده از شگردهای مختلف، دستورهای خط فرمان گوناگونی را امتحان میکند و در صورت کشف، آسیبپذیری Command Injection را در هدف مشخصشده اکسپلویت میکند.
دانلود و راهنمای ابزار:
https://github.com/commixproject/commix
در اینجا نمونهی سادهای از استفاده از این ابزار را با هم بررسی میکنیم:
فرض کنید یک فایل به نام vulnerable.php با محتوای زیر وجود دارد:
این فایل در آدرسی مشابه آدرس زیر نیز قرار دارد:
حالا از ابزار Commix برای کشف و اکسپلویت آسیبپذیری Command Injection استفاده میکنیم و دستور زیر را در خط فرمان وارد میکنیم:
همانطور که میبینید برنامه Commix.py را با سوییچ url که آدرس نقطهی آسیبپذیر است اجرا کردهایم. برای مشخصکردن محل تزریق نیز عبارت INJECT_HERE را فراموش نکردهایم. پس از وارد کردن این دستور، ابزار سعی میکند که وجود آسیبپذیری را کشف کند، یک شِل یا خط فرمان ساده را در اختیار شکارچی قرار دهد و امکان اجرای هر دستوری را برایش فراهم کند. در حقیقت دستوری که در این خط فرمان ساده وارد میشود، در همان محل INJECT_HERE که مشخص کردهایم، تزریق میشود.
شایان ذکر است که دربارهی استفاده از ابزارها باید توجه داشت که همهی این ابزارها میتوانند در فرآیند کشف و قابل بهرهجوییبودن آسیبپذیری Command Injection مورداستفادهی شکارچی قرار گیرند اما استفاده از ابزارهای آماده در گزارش آسیبپذیری Command Injection فاقد ارزش است.
در مطلب «چگونه گزارش آسیبپذیری بنویسیم؟» میتوانید راجع به بایدها و نبایدهای یک گزارش آسیبپذیری بیشتر بخوانید.
روشهای رفع آسیبپذیری Command Injection کدامند؟
آسیبپذیری Command Injection همانطور که از نامش پیداست، امکان اجرای دستورهای گوناگون خط فرمان را در اختیار شکارچی قرار میدهد. یکی از راههایی که این دستورهای میتوانند در سرور قربانی اجرا شوند، همان ورودیهای فرمهای سامانههاست. اگر ورودیهای کاربران ( آنچه که کاربر در فیلدهای فرمهای ورودی وارد میکند) کنترل نشوند، شکارچی میتواند این فرصت را غنیمت بشمارد و دستور خط فرمان خود را در قالب یک دستور ساده به سرور ارسال کند.
حال سوالی که پیش میآید این است آیا در صورت عدم کنترل ورودیها، بروز آسیبپذیری Command Injection قطعی خواهد بود؟
خیر، فقط احتمال بروز این آسیبپذیری در کنار آسیبپذیریهای دیگری که از عدم کنترل ورودیها ناشی میشوند بالا خواهد رفت؛ با اینکه عدم اعتبارسنجی ورودیها، راه کشف و اکسپلویت آسیبپذیری Command Injection را باز میکند ولی تنها در صورتی امکان نفوذ وجود خواهد داشت که مقادیر ورودیهایی که به سرور قربانی میرسند به صورت خام یا با حداقل تغییر به عنوان یک دستور در سرور قربانی اجرا شوند. در این صورت، شکارچی به راحتی میتواند دستورهای خود را در لابهلای دستورهای اصلی تزریق کند.
بنابراین، روشهای رفع آسیبپذیری Command Injection عبارتند از:
• کنترل و اعتبارسنجی ورودیهای کاربر
• عدم اجرای مستقیم مقادیر ورودی کاربر به عنوان دستور در سمت سرور
میتوانید دربارهی کنترل ورودیها، خطرات عدم کنترل ورودیهای کاربر و چگونگی کنترل آنها در مطلب «کنترل ورودی کاربر، چرا و چگونه؟» بیشتر بخوانید.
سخن آخر
به طور کلی، ماهیت آسیبپذیریهای دستهی Injection را میتوان ایجاد انحراف در روند عادی عملیاتهای یک سامانه دانست. عامل این انحراف نیز همان مواردی هستند که باید به سامانه و در روند عادی تزریق شوند. آسیبپذیری Command Injection میتواند دروازهی ورودی آسیبپذیریهای ثانویهای مانند اجرای کد از راه دور و غیره باشد. بنابراین، این آسیبپذیری از این جهت که بتواند دسترسی با میزان بالایی را در سرور قربانی برای شکارچی فراهم کند حائز اهمیت است. اصولا هرچه شکارچی بر محیط خط فرمان احاطهی بیشتری داشته باشد، دستورهای بیشتری از محیط خط فرمان را بشناسد و بر استفاده از آنها مسلطتر باشد، در کشف و اکسپلویت آسیبپذیری Command Injection موفقتر خواهد بود. روشهای کشف و اکسپلویت آسیبپذیری Command Injection به صورت دستی قابلانجام است و در فرآیند کشف و اکسپلویت، ابزار معرفی شده در کنار نکات و نمونهها میتوانند یاریگر شکارچی باشند. امیدواریم که در کشف و اکسپلویت این آسیبپذیری موفق باشید ؛)
منابع:
https://resources.infosecinstitute.com/topic/what-are-command-injection-vulnerabilities
https://www.whitehatsec.com/glossary/content/os-command-injection
https://www.netsparker.com/blog/web-security/command-injection-vulnerability