مرتضی ساکی
مرتضی ساکی
خواندن ۱۰ دقیقه·۵ سال پیش

انواع آسیب پذیری در PHP - چک لیست بررسی باگ در کد


در نوشته های قبلی در مورد مبانی امنیت برنامه‌های تحت وب و امنیت در PHP توضیحاتی رو ارائه دادم. در این پست قصد دارم نکات و آسیب پذیری‌هایی را که هنگام نوشتن کدهای PHP، امکان رخ دادنشان هست و نیاز به توجه و حساسیت بیشتری از جانب برنامه نویسان و توسعه دهندگان دارد را توضیح دهم.

زبان PHP محبوب‌ترین زبان برنامه نویسی سمت سرور است. بر اساس داده‌های سایت W3Techs در سال ۲۰۱۹، ۷۹ درصد از وب سایت‌ها، قدرت گرفته از PHP هستند. از آنجایی که PHP زبان محبوبی است، امنیت در PHP امری ضروری است. متاسفانه تعداد برنامه‌های آسیب پذیر نوشته شده با PHP بسیار زیاد است.

منابعی که این آسیب پذیری‌ها را شرح دادن اکثرا از mitre.org و OWASP هستند. اگر فرصتی باشه در مورد هر کدام از این آسیب پذیری‌ها در پست‌های جداگانه‌ای توضیحات بیشتری ارائه میدم. این نکته رو هم بگم که بعضی از آسیب پذیری‌ها انواع مختلفی دارند. ولی از آنجایی که هدف این پست تنها معرفی گونه‌های مختلف آسیب پذیری است، در اینجا ذکر نشدن. این پست فقط برای برنامه نویسان PHP نیست و می‌تواند برای همه برنامه نویسان وب مفید باشد. ممکن است خیلی از آسیب پذیری‌ها را فراموش کرده باشم که در این پست بیارم، اگر شما هم آسیب پذیری غیر از این موارد می‌شناسید و یا ایرادی می‌بینید خوشحال میشم تو نظرها اعلام کنید تا اعمال کنم. نکته بعدی اینکه، قطعه کدهایی که در زیر آسیب پذیری‌ها آورده شده، نمونه کدآسیب پذیر است و نباید به این فرم در برنامه استفاده شود. برای یادگیری نحوه صحیح نوشتن و جلوگیری از حمله، می‌توانید از مراجع کمک بگیرید.

آسیب پذیری در برنامه‌های تحت وب به ۴ دسته تقسیم می‌شود: Medium, High, Critical و Low:

۱. آسیب پذیری‌های با درجه اهمیت Critical

آسیب پذیری‌هایی با درجه اهمیت حیاتی که معمولا برای اکسپلویت کردنشان نیاز به استفاده از تکنیک‌های مهندسی اجتماعی نیست و می‌تواند منجر به آسیب دیدن زیرساخت و یا از دست رفتن اطلاعات حساس شود. در ادامه آسیب پذیری‌های این دسته رو به صورت مختصر توضیح میدم.

این حمله زمانی اتفاق می‌افتد که داده ورودی به عنوان یک دستور سیستمی تفسیر و اجرا شود:

$file=$_GET['filename']; system(&quotrm $file&quot);

زمانی رخ می‌دهد که داده ورودی به عنوان یک دستور SQL، تفسیر و اجرا شود:

$articleid = $_GET['article']; $query = &quotSELECT * FROM articles WHERE articleid = '$articleid'&quot

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

$myvar = &quotvarname&quot $x = $_GET['arg']; eval(&quot\$myvar = \$x;&quot);

زمانی که مهاجم بتواند هر فایل با هر پسوند دلخواهی را در سرور بارگذاری یا ایجاد کند این حمله صورت می‌گیرد:

$target_dir = &quotuploads/&quot $target_file = $target_dir . basename($_FILES[&quotfileToUpload&quot][&quotname&quot]); if(isset($_POST[&quotsubmit&quot])) { move_uploaded_file($_FILES[&quotfileToUpload&quot][&quottmp_name&quot], $target_file)}

با استفاده از include برنامه نویس قادر است تا یک فایل php را گرفته و از کدهای آن در فایل جاری استفاده کند. حالا چه اتفاقی می‌افتد اگر این فایل، یک فایل مخرب باشد:

$file = $_GET['file']; include($file);

این آسیب پذیری هم زمانی رخ می‌دهد که ورودی کاربر قبل از آنکه sanitize شود در اختیار تابع unserialize قرار گیرد:

$user_data = unserialize($_GET['data']);

۲. آسیب پذیری‌های با درجه اهمیت High

آسیب پذیری‌های این دسته معمولا اکسپلویت کردنشان سخت‌تر از دسته Critical است. مهاجم بعد از کسپلویت، می‌تواند سطح دسترسی خودش رو در سیستم افزایش، بخشی از داده‌ها را سرقت و یا باعث از کار افتادن سیستم شود.

شبیه آسیب پذیری File Inclusion است. با این تفاوت که مهاجم فقط قادر به اجرای فایل‌های محلی در سرور است:

$file = $_GET['file']; include('directory/' . $file);

اِلدَپ یک پروتکل در لایه کاربرد، برای ارتباط با دایرکتوری سرویس است. در صورتی که ورودی کاربر sanitize نشود مهاجم قادر است که اطلاعات موجود در LDAP را مشاهده، تغییر و یا دستور مد نظرش را اجرا کند:

class LDAPAuthenticator { public $conn; public $host; function __construct($host = &quotlocalhost&quot) { $this->host = $host; } function authenticate($user, $pass) { $result = []; $this->conn = ldap_connect($this->host); ldap_set_option( $this->conn, LDAP_OPT_PROTOCOL_VERSION, 3 ); if (!@ldap_bind($this->conn)) return -1; $result = ldap_search( $this->conn, &quot&quot, &quot(&(uid=$user)(userPassword=$pass))&quot ); $result = ldap_get_entries($this->conn, $result); return ($result[&quotcount&quot] > 0 ? 1 : 0); } } if(isset($_GET[&quotu&quot]) && isset($_GET[&quotp&quot])) { $ldap = new LDAPAuthenticator(); if ($ldap->authenticate($_GET[&quotu&quot], $_GET[&quotp&quot])) { echo &quotYou are now logged in!&quot } else { echo &quotUsername or password unknown!&quot } }

اشاره به یک نوع حمله، که بخاطر sanitize نکردن ورودی، مهاجم را قادر می‌سازد که به فایل‌های غیر از آنچه برنامه نویس انتظار دارد دسترسی داشته باشد:

$file = $_GET['file']; file_get_contents('directory/' . $file);
  • Integer Overflow
  • زمانی رخ می‌دهد که در محاسبات اعداد، خروجی با چیزی که برنامه نویس انتظار دارد تفاوت داشته باشد. مثلا در جمع عدد ۱ با 9223372036854775807 ، انتظار می‌رود که حاصل یکی بیشتر شود، ولی در عمل اینگونه نیست. البته این مشکل در زبان‌هایی مثل C و C++ نمود بیشتری دارد.
var_dump(PHP_INT_MAX+1); //float(9.2233720368548E+18)
  • Type Confusion
  • زمانی که دو مقدار را با هم مقایسه می‌کنید، PHP نوع آنها را حدس و بر اساس آن مقایسه رو انجام می‌دهد. PHP یک زبان داینامیک است و معمولا به صورت خودکار بر روی داده‌ها تغییر نوع انجام می‌دهد. در کد زیر انتظار می‌رود که خروجی به ما False دهد، ولی اینگونه نیست:
var_dump(&quot0&quot == &quot-0&quot);
  • Phar Deserialization

این آسیب پذیری اولین بار در سال ۲۰۱۸ و در کنفرانس Black Hat معرفی شد. مشابه Object Injection است، با این تفاوت که نیازی به تابع unserialize برای اجرا ندارد. ولی نیاز به یک سری شرایط مثل تعریف magic methodها دارد که اگر فرصت کنم توی پست‌های بعدی مفصل‌تر توضیح میدم. مثال زیر دارای آسیب پذیری از این نوع است:

class AnyClass { function __destruct() { echo $this->data; } } include('phar://test.phar');

۳. آسیب پذیری‌های با درجه اهمیت Medium

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

  • Arbitrary File Deletion

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

unlink($_GET($file));
  • Data Manipulation

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

یک نمونه از حملات تزریق کد است که مهاجم کدهای مخرب خود را در یک وب سایت مطمئن تزریق می‌کند. هدف این گونه حملات، بازدیدکنندگان سایت است.

print &quotNot found: &quot . urldecode($_SERVER[&quotREQUEST_URI&quot]);
  • XQuery Injection

زبان XQuery (XML Query)، یک پرس و جو بر روی داده های ساخت یافته و غیر ساخت یافته مانند XML و فایل‌های متنی است. در این نوع حمله، مهاجم قادر به تغییر مفهوم پرس و جو است:

$memstor = InMemoryStore::getInstance(); $z = Zorba::getInstance($memstor); try { // get data manager $dataman = $z->getXmlDataManager(); // load external XML document $dataman->loadDocument('users.xml', file_get_contents('users.xml')); // create and compile query $express = &quotfor \$user in doc(users.xml)//user[username='&quot . $_GET[&quotusername&quot] . &quot'and pass='&quot . $_GET[&quotpassword&quot] . &quot'] return \$user&quot $query = $zorba->compileQuery($express); // execute query $result = $query->execute();

زبان XPath یک پرس و جو برای انتخاب نود‌ها در یک سند XML است . این آسیب پذیری زمانی رخ می‌دهد که داده‌های ورودی از کاربر بدون sanitize کردن در در یک پرس و جو قرار داده شود:

&quot//Employee[UserName/text()='&quot & $_GET['UserName'] & &quot' And Password/text()='&quot & $_GET['Password'] & &quot']&quot

این آسیب پذیری هم زمانی رخ می‌دهد که به اشتباه از Reflection در برنامه استفاده کنید. مهاجم معمولا در صورت وجود این نوع آسیب پذیری قادر به کنترل جریان برنامه و تزریق کد است.

  • XSLT Injection

زبان XSLT مبتنی بر XML است و شیوه تبدیل از یک فایل XML به فایلی دیگر را توصیف می‌کند. در این نوع حمله مهاجم قادر است، ساختار و محتوای یک فایل XML رو تغییر دهد. که منجر به خواندن از یک فایل یا اجرای یک دستور دلخواه می‌شود:

$xml = new DOMDocument; $xml->load('local.xml'); $xsl = new DOMDocument; $xsl->load($_GET['key']); $processor = new XSLTProcessor; $processor->registerPHPFunctions(); $processor->importStyleSheet($xsl); echo $processor->transformToXML($xml);

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

  • NoSQL Injection

حمله‌ای مشابه SQL Injection، با این تفاوت که بر روی پایگاه داده‌های NoSQL است.

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

این حمله زمانی اتفاق می‌افتد که برنامه، ورودی را از مهاجم دریافت و به آن تغییر مسیر دهد. این کار می‌تواند کاربر را به یک سایت مخرب هدایت کند:

<?php header(&quotLocation: http://www.mysite.com&quot); exit; ?>

این حمله زمانی رخ می‌دهد که داده‌ از طریق یک منبع نامطمئن مانند HTTP Request به برنامه ارسال شود. و یا اینکه داده ارسال شده به کاربر نهایی، بدون هیچگونه اعتبار سنجی در کاراکترهایش، در HTTP response header قرار گیرد.

این حمله زمانی اتفاق که مهاجم با قرار گرفتن در بین کاربر نهایی و سرور، داده‌های ارسالی به سمت سرور را تغییر دهد. حمله Man In The Middle.

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

class User { private $userid; private $password; private $email; private $isAdmin; //Getters & Setters }

۴. آسیب پذیری‌های با درجه اهمیت Low

این دسته از آسیب پذیری‌ها اکسپلویت کردنشان مشکل و معمولا نیاز به دسترسی فیزیکی به سرور دارند. همچنین تاثیر کمی بر روی کسب وکار یک سازمان دارند.

این حمله هنگامی رخ‌ میدهد که مهاجم بتواند درخواستی را به سمت سرور ارسال و منابع داخلی سیستم که در حالت عادی امکان دسترسی به آنها از بیرون وجود ندارد، مانند فایل‌هایی پشت فایروال یا تنظیمات پیکربندی را بخواند. در قطعه کد زیر، مشاهده می‌کنید که مهاجم کنترل کاملی روی پارامتر url دارد:

<?php if (isset($_GET['url'])){ $url = $_GET['url']; $image = fopen($url, 'rb'); header(&quotContent-Type: image/png&quot); fpassthru($image);}
  • Memcached Injection

از Memcached برای انجام عملیات کش بر روی سرور به صورت داینامیک استفاده می‌شود. ولی در صورت استفاده نادرست می‌تواند منجر به نقص امنیتی شود. قطعه کد زیر این آسیب پذیری رو نشان می‌دهد:

<?php $m = new Memcached(); $m->addServer('localhost', 11211); $m->set(str_repeat(“a”,251),&quotset injected 0 3600 10\r\n1234567890&quot,30);?>

مشابه حمله Path Traversal، با این تفاوت که تمرکز اصلی آن دسترسی به منابع سیستم است. در مثال زیر نام فایل موقت از کاربر گرفته شده و سپس حذف می‌شود. ولی یک مهاجم با وارد کردن آدرس یا نام منبعی غیر از آنچه برنامه نویس انتظار دارد، موجب حذف شدن آن منبع می‌شود:

<?php $rName = $_GET['fileId']; $myfile = fopen('/log/'.$rName, &quotr&quot); unlink($myfile)?>

این آسیب پذیری از آنجا ناشی می‌شود که یک مهاجم بتواند به پیکربندی سیستم دسترسی و آنرا تغییر دهد.

  • HTTP Parameter Pollution

این آسیب پذیری زمانی رخ می‌دهد که برنامه چندین پارامتر با نام یکسان را پذیرش کند. زمانی که این داده‌ها به سرور ارسال می‌شوند، با توجه به تنظیمات و پیکربندی سرور، این داده‌ها به طرق مختلف پردازش می‌شوند. مثلا در سرور آپاچی تنها آخرین پارامتر پردازش می‌شود. مهاجم با بهره برداری از این آسیب پذیری قادر به تغییر رفتار برنامه و حتی دور زدن WAF است.

  • Weak Cryptography

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

function gen_uuid() { return sprintf( ' x x- x- x- x- x x x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ));}


در انتها جا داره دوباره بگم که این لیست کمبود‌های زیادی داره و جمع آوری این لیست حاصل تجربه شخصی خودم در بررسی کدهاست. اگر شما هم پیشنهادی دارید توی نظرها بگید تا اعمال کنم. اگر بتوانم و وقت کنم بعدا همچین پستی برای زبان‌های دیگه مثل پایتون، جاوا و سی هم می نویسم.

phpامنیتبرنامه نویسیهک
یه آدم معمولی
شاید از این پست‌ها خوشتان بیاید