امنیت

شناسایی درهای پشتی در کدهای PHP

چند وقته که در کنار کتاب و مقاله هایی که می خونم و کارهایی که می کنم، علاقه زیادی به آنالیز کدهای مخرب پیدا کردم. یکی از این علاقه ها، شناسایی درهای پشتی در کدهای PHP است. در ادامه اشاره کوتاهی خواهم کرد به نشونه هایی که می تونه منجر به شناسایی کدهای مخرب بشه و البته روش های بدافزارنویس ها برای دور موندن از چشم کارشناس های امنیتی.

phpbackdoor

backdoor یا درپشتی در واقع یک تکه کده که به هکر امکان دسترسی مجدد به سایت هک شده رو می ده حتی اگه ادمین تموم پسوردها رو تغییر بده. این تکه کد می تونه ۱۰۰خط باشه یا یکی دو خط.  یکی از ابتدایی ترین شیوه ها گذاشتن یک درپشتی واضح و سر راسته:

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

به دلیل پیشرفته تر شدن کارشناسان امنیتی و نرم افزارهاشون، هکرها هم به سمت آموزش و استفاده از روش های جدیدتر رفتن. روش هایی که بعضی مواقع زمان زیادی رو از کارشناسان امنیتی می گیره تا بتونن کشفش کنن. مثلا با استفاده از یک سری توابع PHP کدشون رو ناخوانا می کنند. کد زیر در واقع همون درپشنی در مثال قبله با این تفاوت که کل کد با متد base64 رمز شده.

در این روش هسته PHP ابتدا با دستور base64_decode این کاراکترهای به هم ریخته رو به کد اصلی برمی گردونه و سپس اجراش می کنه. این روش نیز به راحتی قابل پیدا کردنه. کافیه توی تموم کدهای سایتمون دنبال یک استرینگ رمز شده بگردیم و بعد ببینیم چکار می کنه.

روش دیگه ناخوانا کردن یک در پشتی می تونه مثال زیر باشه. این روش هم هرچند قابل پیدا شدنه اما با کمی خلاقیت می شه اون رو از چشم افزونه های امنیتی دور کرد و یا حداقل کاری که می کنه رو مخفی کرد:

همونطور که در کد بالا می بینید حتی اسامی توابع نیز رمز شده و به اون هم اکتفا نشده و با جایگذاری کاراکترهای رندوم در بین استرینگ به دست اومده، اون رو هم ناخواناتر کرده. زمان اجرا ابتدا PHP کاراکترهای جایگذاری شده رو حذف می کنه و بعد نتیجه را رمزگشایی می کنه و کد اجرا می شه.

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

در این نمونه نویسنده درپشتی، از فراخوانی توابع در تابع های عادی PHP استفاده کرده:

کاری که array_diff_ukey می کنه اینه که دوتا آرایه رو بر اساس کلید ها مقایسه می کنه و تفاوت ها رو بر می گردونه. یه گزینه دیگه هم داره که می تونه یک تابع دیگه رو فرابخونه و  این تفاوت های پیدا شده رو به اون بده و اون تابع رو اجرا کنه. مثلا تصویر زیر می تونه جمله All your data belong to me! رو در خروجی نشون بده

array_diff_ukey

در کد اصلی سه متغیر از  کاربر گرفته می شه که تفاوت دو تا به عنوان ورودی تابع عمل خواهد کرد و خود تابع نیز از طریق متغیر سوم مشخص می شه.

می بینید که هیچ نکته غیر عادی در کد وجود نداره. ضمن اینکه این شیوه محدود به تابع array_diff_ukey نیست و با همین شیوه می شه از همه توابعی که تابع دیگه ای رو فراخوانی می کنن، استفاده کرد. باید پترنی رو پیدا کرد که تشخیص خودکار این روش رو ممکن کنه.

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

 

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

دانلود از یوتوب

این یه پروژه شخصیه. زیاد پیش میومد که فیلمی رو از یوتوب بخوام ببینم یا دانلود کنم و به هر دلیلی نخوام از فیلتر شکن استفاده کنم. فرض کنید فیلم های بلند. مثلا چند مورد از فیلم های ریچارد داوکینز بود که حجم بالایی داشتن می خواستم توی زمان دانلود مجانی بگیرمشون. 🙂

تا یه جایی از سرویس های آنلاین تبدیل فرمت استفاده می کردم و یا یکی دو تا سایت که کارشون گرفتن فیلم های یوتوب و دادن یه لینک مستقیم بود. بعد کم کم همشون رفتن سراغ جاوا و می گفتن اجازه بده یه چیزی رو سیستمت نصب کنیم تا ما هم اجازه بدیم تو فیلم دانلود کنی. این شد که بی خیالشون شدم و تصمیم گرفتم کارم رو خودم انجام بدم.

این مورد همزمان بود با شروع یادگیری PHP، بنابراین سعی کردم این پروژه رو با PHP پیاده کنم. برای انجامش از کلاس PHPtube استفاده کردم که خب مدت ها بود به روز نشده بود. یه فورک ازش گرفتم ولی تنبلی کردم و توی گیتهاب تغییرات و اضافه ها رو آپلود نکردم.

با یه سری مشکلات رو به رو شدم. این کلاس، لینک فایل رو بر می گردوند و حالا باید فکری به حال دانلود می کردم. اول اینکه محدودیت زمان اجرای PHP رو باید برمی داشتم یا حداقل به زمان منطقی می رسندمش. من از این دستور استفاده کردم:

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

و خب مورد بعدی این بود که ترجیح می دادم به جای اجرای همه کارها در یک فایل، دستورات رو تقسیم کنم و هر فایل کار به خصوصی رو انجام بده و که بعدها گسترشش برای خودم و دیگران راحت تر باشه. این شد که رسیدم به استفاده از require و require_once برای خوندن فایل های جداگانه و دسترسی به فانکشن هاشون. شاید تنها کمبودشون الان ناقص بودن کامنت ها باشه.

برای دانلود هم همونطور که خواهید دید پس از انتخاب کیفیت وسیله کاربر، مشخصات فایل مثل آدرس و نام از طریق سشن به فایل دانلود منتقل می شه. در واقع اطلاعات کیفیت های مختلف در سشن قرار می گیره و به دانلودر می گم که کدوم اطلاعات رو مبنای کار قرار بده. مقادیری که به صورت GET به دانلودر منتقل می شه شامل اسم سشن انتخابی، اسم فایل و تایپشه.

آدرس دسترسی به دموی این پروژه هم اینه که البته فقط تا قبل از دانلود رو جلو می ره. محدودیت IP براش گذاشتم چون سرور محدودیت حجمی و ترافیک داره 🙂

ایده های زیادی که برای تکمیلش دارم. بعضی هاش رو اینجا می نویسم و بعد در بخش پروژه ها یه سرفصل براش در نظر می گیرم.

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

البته این لیست می تونه بیشتر بشه. هدف از این پروژه هم تمرین عملی PHP و کانکت شدن با MySql است.

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

خوشحال می شم اگر ایده، پیشنهاد و یا انتقادی دارید بگید. یا جایی فکر می کنید کدها رو اشتباه نوشتم بهم خبر بدید.

استاندارد