Cross-site scripting (XSS)
زمان مطالعه :6 دقیقه
XSS contexts: Between HTML tags, In HTML tag attributes, JavaScript, Client-side template injection
Cross-site scripting contexts
https://portswigger.net/web-security/cross-site-scripting/contexts
هنگام آزمایش XSS منعکس شده و ذخیره شده، یک کار کلیدی شناسایی XSS context است:
· مکانی در داخل پاسخ که دادههای قابل کنترل توسط مهاجم ظاهر میشود.
· هرگونه اعتبارسنجی ورودی یا پردازش دیگری که روی آن دادهها توسط برنامه انجام میشود.
بر اساس این جزئیات، میتوانید یک یا چند Payload کاندید XSS را انتخاب کنید و آزمایش کنید که آیا آنها مؤثر هستند یا خیر.
Note
ما یک Cheat Sheet جامع برای XSS ایجاد کردهایم تا به تست برنامههای وب و فیلترها کمک کند. شما میتوانید بر اساس رویدادها و تگها فیلتر کنید و ببینید که کدام بردارها نیاز به تعامل کاربر دارند. این Cheat Sheet همچنین شامل فرار از Sandbox در AngularJS و بسیاری از بخشهای دیگر برای کمک به تحقیقات XSS است.
XSS between HTML tags
وقتی XSS context متن بین HTML tag ها است، باید برخی HTML tag های جدید را معرفی کنید که برای اجرای JavaScript طراحی شده اند.
برخی روشهای مفید برای اجرای JavaScript عبارتند از:
<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
XSS in HTML tag attributes
وقتی زمینه XSS در مقدار یک مقدار مشخصه HTML tag است، گاهی اوقات میتوانید مقدار attribute را خاتمه دهید، tag را ببندید و یک tag جدید معرفی کنید. به عنوان مثال:
"><script>alert(document.domain)</script>
بیشتر در این موقعیت، علامتهای زاویهای (angle brackets)مسدود یا کدگذاری میشوند، بنابراین ورودی شما نمیتواند از tag که در آن ظاهر میشود، خارج شود. به شرطی که بتوانید مقدار attribute را خاتمه دهید، معمولاً میتوانید یک attribute جدید معرفی کنید که یک زمینه scriptable ایجاد کند، مانند یک Event Handler. به عنوان مثال:
" autofocus onfocus=alert(document.domain) x="
Payload فوق یک رویداد onfocus ایجاد میکند که JavaScript را زمانی که عنصر (element)تمرکز میگیرد، اجرا میکند و همچنین autofocus attribute را اضافه میکند تا سعی کند رویداد onfocus را به طور خودکار بدون هیچ تعامل کاربری فعال کند. در نهایت، x=" را اضافه میکند تا به طور ماهرانه Markup بعدی را تعمیر کند.
گاهی XSS context در نوعی HTML tag attribute است که خود میتواند یک زمینه scriptable ایجاد کند. اینجا، شما میتوانید بدون نیاز به خاتمه مقدار attribute، JavaScript را اجرا کنید. به عنوان مثال، اگر XSS context در href attributeیک anchor tag باشد، میتوانید javascript pseudo-protocol برای اجرای script استفاده کنید. به عنوان مثال:
<a href="javascript:alert(document.domain)">
ممکن است با وبسایتهایی مواجه شوید که علامتهای زاویهای (angle brackets)را کدگذاری میکنند اما همچنان به شما اجازه میدهند attribute ها را تزریق کنید. گاهی اوقات، این تزریقها حتی در داخل tag هایی که معمولاً به طور خودکار رویدادها را اجرا نمیکنند، مانند یک canonical tag امکانپذیر است. میتوانید از این رفتار با استفاده از access keys و تعامل کاربر در Chrome سوء استفاده کنید. Access keys به شما اجازه میدهند میانبرهای صفحهکلید ایجاد کنید که به یک عنصر خاص اشاره میکنند.attribute accesskey به شما اجازه میدهد حرفی را تعریف کنید که وقتی با کلیدهای دیگر (اینها در پلتفرمهای مختلف متفاوت هستند) فشار داده شود، باعث اجرای رویدادها شود. در آزمایشگاه بعدی میتوانید با access keys آزمایش کنید و یک canonical tag را Exploit کنید. میتوانید با استفاده از تکنیکی که توسط PortSwigger Research ابداع شده است، از XSS در فیلدهای input مخفی سوء استفاده کنید.
XSS into JavaScript
وقتی XSS context برخی از JavaScript های موجود در داخل پاسخ است، مجموعه گستردهای از موقعیتها میتواند رخ دهد که نیاز به تکنیکهای مختلف برای انجام یک Exploit موفق دارند.
Terminating the existing script
در سادهترین حالت، ممکن است بتوانید tag script که JavaScript موجود را احاطه کرده است، ببندید و برخی HTML tag های جدید معرفی کنید که باعث اجرای JavaScript میشوند. به عنوان مثال، اگر XSS context به صورت زیر است:
<script>
var input = 'controllable data here';
</script>
میتوانید از Payload زیر استفاده کنید تا از JavaScript موجود خارج شده و JavaScript خود را اجرا کنید:
</script><img src=1 onerror=alert(document.domain)>
دلیل اینکه این کار مؤثر است این است که مرورگر ابتدا تجزیه HTML را انجام میدهد تا عناصر صفحه از جمله بلوکهای script را شناسایی کند، و فقط بعد از آن تجزیه JavaScript را انجام میدهد تا script های تعبیهشده را درک و اجرا کند.Payload فوق script اصلی را خراب میکند، با یک رشته بدون پایان به معنای واقعی کلمه(string literal). اما این مانع از تجزیه و اجرای script بعدی به طور معمول نمیشود.
Breaking out of a JavaScript string
در مواردی که XSS context در داخل یک quoted string literal(یک رشته نقل قول به معنای واقعی کلمه) است، اغلب ممکن است از رشته خارج شده و مستقیماً JavaScript را اجرا کنید. ضروری است که script را پس از XSS context تعمیر کنید، زیرا هرگونه خطای syntax در آنجا مانع از اجرای کل script میشود.
برخی روشهای مفید برای خارج شدن از یک string literal عبارتند از:
'-alert(document.domain)-'
';alert(document.domain)//
برخی برنامهها تلاش میکنند از خروج ورودی از رشته JavaScript با escape کردن هر کاراکتر single quote با یک backslash جلوگیری کنند. یک backslash قبل از یک کاراکتر به JavaScript parser میگوید که کاراکتر باید به صورت literal تفسیر شود، و نه به عنوان یک کاراکتر خاص مانند یک string terminator. در این وضعیت، برنامهها اغلب اشتباه میکنند که خود کاراکتر backslash را escape نکنند. این بدان معنی است که مهاجم میتواند از backslash خود استفاده کند تا backslash اضافه شده توسط برنامه را بیاثر کند.
به عنوان مثال، فرض کنید ورودی:
';alert(document.domain)//
به این تبدیل میشود:
\';alert(document.domain)//
اکنون میتوانید از Payload جایگزین استفاده کنید:
\';alert(document.domain)//
که به این تبدیل میشود:
\\';alert(document.domain)//
اینجا، backslash اول به این معنی است که backslash دوم به صورت literal تفسیر میشود، و نه به عنوان یک کاراکتر خاص. این بدان معنی است که quote اکنون به عنوان یک string terminator تفسیر میشود، و بنابراین حمله موفق میشود.
برخی وبسایتها XSS را با محدود کردن کاراکترهایی که مجاز به استفاده از آنها هستید دشوارتر میکنند. این میتواند در سطح وبسایت یا با استفاده از یک WAF باشد که مانع از رسیدن درخواستهای شما به وبسایت میشود. در این موقعیتها، نیاز دارید با روشهای دیگری برای فراخوانی توابع که از این اقدامات امنیتی عبور میکنند، آزمایش کنید. یکی از روشهای انجام این کار استفاده از دستور throw با یک exception handler است. این به شما اجازه میدهد تا بدون استفاده از پرانتزها، آرگومانها را به یک تابع پاس کنید. کد زیر تابع alert() را به global exception handler اختصاص میدهد و دستور throw عدد 1 را به exception handler (در این مورد alert) پاس میکند. نتیجه نهایی این است که تابع alert() با آرگومان 1 فراخوانی میشود.
onerror=alert;throw 1
روشهای متعددی برای استفاده از این تکنیک برای فراخوانی توابع بدون پرانتز وجود دارد.
Making use of HTML-encoding
وقتی XSS context برخی از JavaScript های موجود در یک quoted tag attribute، مانند یک Event Handler است، ممکن است از HTML-encoding برای دور زدن برخی فیلترهای ورودی استفاده کنید.
وقتی مرورگر، HTML tag ها و attribute ها را در یک پاسخ تجزیه کرده است، HTML-decoding مقادیر attribute های tag را قبل از پردازش بیشتر انجام میدهد. اگر برنامه سمت سرور برخی کاراکترهایی که برای یک Exploit موفق XSS لازم است را مسدود یا sanitized کند، اغلب میتوانید اعتبارسنجی ورودی را با HTML-encoding آن کاراکترها دور بزنید.
به عنوان مثال، اگر XSS context به صورت زیر است:
<a href="#" onclick="... var input='controllable data here'; ...">
و برنامه کاراکترهای single quote را مسدود یا escape میکند، میتوانید از Payload زیر برای خارج شدن از رشته JavaScript و اجرای script خود استفاده کنید:
'-alert(document.domain)-'
توالی ' یک HTML entity نمایانگر یک apostrophe یا single quote است. زیرا مرورگر مقدار attribute onclick را HTML-decodes قبل از تفسیر JavaScript، entity ها به عنوان quote کدگذاری میشوند، که به delimiter های رشته تبدیل میشوند، و بنابراین حمله موفق میشود.
XSS in JavaScript template literals
قالبهای رشتهای (template literals) در JavaScript رشتههایی هستند که اجازه میدهند عبارات JavaScript در آنها جاسازی شوند. عبارات جاسازیشده ارزیابی میشوند و معمولاً به متن اطراف خود متصل میشوند. قالبهای رشتهای به جای علامتهای نقل قول معمولی در backticks قرار میگیرند و عبارات جاسازیشده با استفاده از سینتکس ${...} شناسایی میشوند.
به عنوان مثال، اسکریپت زیر یک پیام خوشآمدگویی را چاپ میکند که نام نمایشی کاربر را شامل میشود:
document.getElementById('message').innerText = Welcome, ${user.displayName}.;
وقتی XSS context در یک قالب رشتهای JavaScript است، نیازی به خاتمه دادن قالب رشتهای نیست. به جای آن، فقط نیاز دارید ازسینتکس ${...} برای جاسازی یک عبارت JavaScript استفاده کنید که زمانی که قالب رشتهای پردازش میشود، اجرا خواهد شد. به عنوان مثال، اگر XSS context به صورت زیر باشد:
<script>
var input = controllable data here;
</script>
سپس میتوانید از payload زیر برای اجرای JavaScript بدون خاتمه دادن قالب رشتهای استفاده کنید:
${alert(document.domain)}
XSS via client-side template injection
برخی وبسایتها از یک چارچوب قالبسازی سمت کاربر (client-side template framework)، مانند AngularJS، برای رندر پویا صفحات وب استفاده میکنند. اگر آنها ورودی کاربر را به صورت ناامن در این قالبها جاسازی کنند، یک مهاجم ممکن است بتواند عبارات قالب مخرب خود را تزریق کند که حمله XSS را راهاندازی میکند.
Read more
امیر رضا کبریادار
مشاهده مقاله های بیشتر
مقالات مرتبط
What is XSS, How does XSS work? Impact of an attack
زمان مطالعه :6 دقیقه
Reflected XSS, Impact, Contexts, Testing, FAQs
زمان مطالعه :5 دقیقه
.Stored XSS, Impact , Contexts, Testing for vulnerabilities
زمان مطالعه :3 دقیقه
DOM-based XSS, Testing, Exploiting
زمان مطالعه :8 دقیقه
Exploiting XSS vulnerabilities & Dangling markup injection
زمان مطالعه :4 دقیقه