امنیت, برنامه‌نویسی

حفره امنیتی در ای‌بی: اجرای کد از راه دور

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

EBay website

در ادامه مروری خواهیم کرد بر این نوشته این کارشناس.

یک درخواست قانونی شبیه این خواهد بود:

همونطور که از آدرس می شه حدس زد، با یک درخواست جستجو رو به روییم که “رشته متنی” مورد نظر از طریق متغیر q دریافت می شه. دیوید در قدم اول بررسی وب اپلیکیشن های PHP، مشکل type-cast رو چک می کنه. می دونیم که اگر متغیری از نوی string باشه ولی ورودی کاربر آرایه باشه، پی اچ پی مشکل ایجاد می کنه. برای کنترل این موضوع، آدرس زیر رو چک می کنیم:

می بینیم که سرور پاسخ مشابهی رو ارسال می کنه. بعدا به این مورد بر می گردیم.
می دونیم که پی‌اچ‌پی روش های متفاوتی برای کار با string ها داره. برای مثال اگر رشته متنی درون ” قرار بگیره (به جای ‘) در برخورد با کاراکترهای ویژه، امکان اجرای کد در شرایط خاصی به وجود میاد.

حالت هایی که امکان اجرا کد رو به وجود میاره:

  • قرار گرفتن ورودی کاربر در ” به جای ‘
  • استفاده از دستور eval برای ورودی کاربر
  • استفاده از دستور create_function برای ورودی کاربر
  • استفاده از دستور preg_replace برای ورودی کاربر (به همراه اصلاح کننده e/)
  • مقایسه رشته ای (با استفاده از <<< یا همون Heredoc) با ورودی کاربر

کدوم یک از موارد بالا در سایت eBay وجود داره؟ با توجه به اینکه تست به اصطلاح کور (blackbox) داره انجام می شه پس باید به حدس اکتفا کرد. حدس می زنیم اینجا از preg_replace برای فیلتر کردن ورودی ها استفاده شده و پس از اون از دستور eval.

چرا دیوید به این نتیجه رسیده؟

  • سایت ای‌بی از spellchecker (کنترل املا کلمات) استفاده می کنه. بسیاری از spellchecker ها از دستور eval استفاده می کنند.
  • یک سری فیلتر برای ورودی های کاربر استفاده می کنند. برای مثال وقتی کلمه secalert رو جستجو کنیم، بخش alert فیلتر شده و کلمه sec جستجو می شود. احتمالا alert رو جزو کلمات ممنوعه گذاشتن و برای جلوگیری از xss اون رو حذف کردن که البته کار اشتباهیه.

قبل از اینکه از دید یک هکر اقدام به اجرا کد کنیم، بهتره بدونیم که اگر رشته متنی درون ” قرار گرفته باشد، تجزیه شده و متغیر های درون آن شناسایی می شود.

به نظر ساده میاد. می تونیم با استفاده از ${ }  امتحان کنیم و ببینیم می تونیم دستور رو اجرا کنیم یا نه.

این کار جواب نداد و به نظر می رسه که رشته متنی رو در ” قرار نداده اند. چه کار می شه کرد؟

بذارید دوباره مروری بکنیم بر مشخصات PHP:
رشته های متنی در پی‌اچ‌پی آرایه ای از بایت ها است. بنابراین دسترسی و یا تغییر یک string با استفاده از براکت های آرایه، پارسر (تجزیه کننده) را فریب داده و منجر به اجرای کد دلبخواهی خواهد شد. مطابق اعلام سایت پی اچ پی، دسترسی و تغییر رشته متنی با استفاده از براکت، فقط در صورتیکه متن از نوع ISO-8859-1 باشد امن است.

خب حالا سعی می کنیم با ارسال آرایه به جای متن، مقادیر متفاوتی برای q به اسکریپت ارسال کنیم و نتیجه رو در صفحه ببینیم.

عمل کرد و نتیجه جستجو جواب هایی رو مطابق کلمه جستجو شده دوم یعنی sec پیدا کرد.

پیش از این حدس زدیم که از preg_replace برای فیلتر کردن کلمات ناخواسته استفاده شده و سپس روی متن به دست آمده از دستور eval استفاده می شود. چیزی که اینجا اتفاق می افته اینه که ورودی های کاربر باید از نوع string باشه و اگر از نوع دیگری بود، مثلا در اینجا آرایه، تبدیل نوع انجام شده (cast) و رشته متنی به دست آمده، با کلمات ممنوع مقایسه شده و فیلتر می گردد.

خب ببینیم چطور می تونیم استفاده کنیم از این حفره.

از مجموع بررسی های بالا استفاده می کنیم و متن جستجو رو در قالب آرایه می فرستیم و یکی از اندیس های آرایه رو  با استفاده از ${ } ارسال می کنیم تا به هدف برسیم.

و می بینیم که دستور با موفقیت انجام شد.

phpinfo

می تونیم دستورهای دیگه ای رو هم به همین طریق ارسال کنیم

phpcredit

 دیوید در این مرحله، ضعف امنیتی رو به eBay گذارش می کنه اما یک هکر می تونست با اجرای دستورات سیستمی به کل سرور دسترسی پیدا کنه. برای مثال با این دستور {${ls -al}}  می تونست لیتس از فایل ها و فولدرهای موجود در فولدر اسکریپت پی اچ پی رو ببینه.

چگونه می شه از اینجور حمله جلوگیری کرد؟

  • به هیچ عنوان از دستورات eval و create_function روی ورودی های کاربر استفاده نکنید.
  • به جای استفاده از ترکیب preg_match و اصلاح کننده e/ ، از preg_match_callback استفاده کنید.
  • اجازه استفاده از Escape sequences در ورودی های کاربر را ندهید.

منبع

Standard
امنیت, برنامه‌نویسی

تزریق دستور و کد

این پست در مورد یکی دیگه از اشتباهات برنامه نویسیه که می تونه نتایج مهلکی داشته باشه.

تزریق کد و تزریق دستور دو نمونه از روش های هک برنامه های تحت وبه که خیلی شبیه به هم اند و از چک نشدن ورودی ها استفاده می کنن. پیش از این در مورد چک نشدن صحیح ورودی ها گفتم. یه ضرب المثل در امنیت Web Application هست که می گه “اطلاعات ورودی کاربر غیرقابل اعتماده”.

بذارید یه سری نمونه از تزریق کد رو با هم ببینیم. فرض کنیم قراره در یک کد PHP با دریافت متغیر arg در url یه عملی روش انجام بدیم و یه خروجی برای کاربر داشته باشه.

همونطور که در کد بالا می بینید هیچگونه بررسی روی متغیر انجام نمی شه و مقدارش رو توی x می ریزه. نمونه ای از حمله می تونه شبیه زیر باشه

دستور سیستم در PHP یک کامند رو در سطح سیستم عامل اجرا می کنه. اینجا هکر می تونه با اجرای ls (با فرض لینوکسی بودن سرور) لیستی از فایل ها و فولدرهای فولدری که index.php قرار داره رو به دست بیاره.

بیاید دستورات PHP که می تونن در کنار “عدم بررسی ورودی” ترکیب خطرناکی رو به وجود بیارند با هم مرور کنیم.

اونهایی که کامندها رو اجرا می کنند:

و اونهایی که کدهای PHP رو اجرا می کنند:

اینکه کدهای بالا چطور می تونه در ترکیب با کدهای دیگه و یا در یک الگوریتم اشتباه تبدیل به یک نقطه ضعف بشه خودش یه مبحث جداگانه است ولی چیزی که مهمه اینه که زمان به کار بردن این دستورات حساسیت بیشتری به خرج بدیم.

یه نمونه واقعی می تونه کد زیر باشه. می بینید که این پروژه در گیتهاب همچین ضعفی رو داره

01what-is-pino

حالا روی لوکال هاست این پروژه رو بالا میاریم و نتیجه حمله رو چک می کنیم:

02-rce-pino

کافیه یه جستجو در گیتهاب بکنیم و ببینیم چند کد مشابه پیدا می کنیم.

و در آخر هم برای اینکه بدونید یک هکر با استفاده ازاین اشتباه برنامه نویسی می تونه تا کجا پیش بره تصویر زیر رو ببینید که همین یکی دو روز اخیر گرفتم. می بینید که موفق شدم یک PHP Shell Script روی سرور آپلود کنم و از این به بعد به کل فایل های سرور دسترسی داشته باشم و کل دیتابیس رو به دست بیارم. می تونم با توجه به ویندوزی بودن سرور سعی کنم پسورد هش شده ادمین رو به دست بیارم و در صورت باز بودن پورت، باRemote Desktop Connection وارد سیستم بشم و راحت تر هر کاری رو بخوام روش انجام بدم.

rce

اطلاعاتی که می تونست منجر به شناسایی سایت بشه رو پاک کردم و کارهای بالارو هم انجام ندادم. در تماس با مدیر سایت مشکل رو بهش اطلاع دادم.

در منابعی که لینکشون رو می ذارم می تونید اطلاعات بیشتر و نمونه های مشابه رو ببینید.

منبع / منبع / منبع / منبع

Standard