Hərkəsə salam, bu gündən artıq PortSwigger-d olan XSS lablarının izahını hissəli şəkildə verəcəm. Əvvəla xss haqqında məlumat alaq.
XSS nədir?
XSS (Cross-Site Scripting) — veb tətbiqlərdə istifadəçinin brauzerində icazəsiz kod işlətməyə imkan verən təhlükəsizlik boşluğudur.
- Hücumçu xüsusi hazırlanmış payloadı form, URL, cookie və ya digər giriş nöqtəsinə daxil edir.
- Əgər tətbiq bu girişi düzgün filtrləmədən istifadəçiyə göstərirsə, həmin payload birbaşa istifadəçinin brauzerində icra olunur.
XSS nəyə yarıyır?
Hücumçu XSS-dən istifadə etməklə bir çox təhlükəli əməliyyatlar apara bilər:
- Sessiya oğurluğu
- İstifadəçinin cookie/session ID-si oğurlanaraq hesabı ələ keçirilə bilər.
- Phishing / UI manipulation
- Səhifəyə saxta forma əlavə edərək istifadəçidən şifrə, kart məlumatı toplamaq mümkündür.
- Keylogger
- JavaScript ilə istifadəçinin yazdığı düymələri izləyib serverə göndərmək olar.
- İstifadəçi adından əmrlər icra etmək (CSRF ilə birlikdə)
- İstifadəçinin adından post atmaq, mesaj göndərmək və s. mümkündür.
- Malware yaymaq
- Zərərli script-lər yüklətmək və ya digər saytlarla əlaqə yaratmaq olar.
XSS niyə yaranır?
User İnput (İstifadəçi Girişi) — Düzgün idarə olunmayan user inputu XSS-in yaranmasına səbəb ola bilər.
Improper Handling (Səhv İdarəetmə) — Əgər vebsayt inputu düzgün şəkildə təsdiq etmirsə və ya filtirləmirsə, ona düz mətn əvəzinə kod kimi baxıla bilər, problem buradan başlayır.
Execution→ əgər payload istifadəçilərin brauzerində sanki qanuni veb-saytın bir hissəsi kimi icra edilirsə və user inputu əks etdirən səhifə varsa, bu kukilərin oğurlanması, istifadəçilərin fişinq səhifəsinə yönləndirilməsi kimi müxtəlif zərərli hərəkətlərə gətirib çıxara bilər.
Same Origin Policy Bypass → Adətən veb brauzerlərdə “Same Origin Policy Bypass” adlı təhlükəsizlik funksiyası var: o, bir vebsaytdan gələn kodun digəri ilə qarşılıqlı əlaqədə olmasına mane olur. Lakin XSS bu hissəni bypass edərək keçə bilər. Bu istifadəçilərə digər saytlardan verilənlərə daxil olmaq və manipulyasiya etmək imkanı verə bilər .
XSS-i necə tapmaq olar?
Siz öz brauzerinizin bəzi ixtiyari JavaScript icra etməsinə səbəb olan payload yeritməklə XXS zəifliyinin əksər növlərini təsdiq edə bilərsiniz. alert() funksiyasından istifadə etmək isə adi bir təcrübədir.
Demək olarki, bütün saytlarda məhz alert() əmrinin icra edilməsinin qarşısı alınıb. Amma təbiiki, digər yollarıda var. İndi daha çox payloadlarda print() funksiyasından istifadə etmək tövsiyə olunur.
XSS hücumlarının növləri hansılardır?
Reflected XSS
- Tətbiq HTTP sorğusunda istifadəçidən aldığı məlumatı dərhal cavabda təhlükəsiz olmayan formada əks etdirir.
- Yəni: Request → Response eyni HTTP sorğusunda baş verir.
Stored XSS
- Payload əvvəlcə veb-saytın verilənlər bazasına və ya digər daimi yaddaşına yazılır, daha sonra isə digər istifadəçilərə göstərilir.
- Bu daha təhlükəlidir, çünki birdən çox istifadəçiyə təsir edə bilər.
DOM-based XSS
- Burada zəiflik server tərəfdə deyil, müştəri tərəfində (client-side), yəni brauzerdə işləyən JavaScript kodunda olur.
- Server sorğuya zərərli kodu göndərsə də, onu birbaşa icra etmir. Kod yalnız DOM manipulyasiyası zamanı işləyir.
Gəlin labın izahına keçək.
1.Lab: Reflected XSS into HTML context with nothing encoded
Bu lab ən sadə labdır. Bu labda biz axtarış hissəsində hərhansı bir məlumat axtararaq arxada nə prosses getdiyinə baxırıq, koduna baxsaq görə bilərik ki, alınan inputu filtr etmir, birbaşa kodu icra edir.

<script>alert(1)</script> yazaraq görə bilərik ki, input validation yoxlanılmır deyə avtomatik reflected xss yaranır.

2.Lab: Stored XSS into HTML context with nothing encoded
Bu labda artıq bizə axtarış hissəsi yox, comment hissəsində verilib. Payload yazmazdan əvvəl həmişə normal html kodlarının icra olunub olunmadığına baxmaq lazımdır.

Commentlərə baxaq.

Deməli yazdığımız html kodu icra olunub. Bu da o deməkdir ki, payloadı yoxlaya bilərik.

3.Lab: DOM XSS in document.write sink using source location.
DOM xss document.write və ya location.search ilə əlaqəlidir, yəni qısa desək DOM xss-də errorlu bir şeyi serverə upload etmək kimi başa düşmək olar, ama bu bütün domlara aid deyil. Bu labda hər hansı script payloadı icra olunmur. Olunmadığına görədə dom payloadlar yazmalıyıq. Yazdığımız payload bu işi görür, svg ilə olmayan bir şəkili qarşı tərəfə yükləyirmiş kimi görsənir, amma yüklənən kimi ekranda alert(1) deyə cavab çıxmalıdır. Bunu onmouseover, onerror, onmousedown və.s formalarda yazmaq olar. Lakin bir problemimiz var ki, hələdə bu payload icra olunmur, səbəbi isə input hissəsinin dırnaq işarəsi və buna aid olan teqi “>” işarəsinin qoyulmamasıdır. Gəlin düzəldək.


4.Lab: DOM XSS in innerHTML sink using source location.search
Bu labda biz innerHTML-in nə qədər təhlükəli olduğuna şahid olacağıq. JavaScript-də DOM elementlərinin məzmununu dəyişmək üçün geniş istifadə olunan metodlardan biri innerHTML funksiyasıdır. Bu funksiya elementin məzmununu HTML kodu kimi qəbul edir və brauzer tərəfindən render olunmasına səbəb olur.
Məhz bu xüsusiyyət innerHTML metodunu təhlükəli edir. Əgər tətbiqdə istifadəçi daxil etdiyi məlumat heç bir filtrasiya və ya kodlaşdırma olmadan innerHTML vasitəsilə DOM-a yerləşdirilirsə, bu zaman DOM XSS zəifliyi yaranır. Məsələn aşağıdakı misala baxaq.

İnput hissəsinə yazılan payloadı daha əvvəl qeyd etdiyim payload kimi işləyir. Məhz burda da innerHTML olduğu üçün filtrasiya etmir və konkret olaraq render edir.

Labı bitirmək üçün məhz bu payloaddan istifadə edirik. Aşağıdakı şəkil isə labın source kodudur.

bundan sonra isə sadəcə axtarış hissəsinə payload yazmağımız kifayətdir.

5.Lab: DOM XSS in jQuery anchor href attribute sink using location.search source
Bu labda jQuery haqqında məlumat alacağıq. Dom xss hücumu server tərəfində deyil, birbaşa brauzerdə Dom manipulyasiyası zamanı baş verir. Bu tip xss-də source istifadəçi tərəfindən idarə olunan məlumatdır, icra mühiti isə kodun yerləşdiyi Dom elementi (sink) olur.

Bu nümunədə saytda axtarış hissəsi olduğunu düşünək. Biz sadə olaraq url-in sonuna ?javascript:alert(1) desək avtomatik olaraq query dəyişənin dəyərini ?javascript:alert(1) dəyərinə mənimsədilmiş olacaq və jQuery href atributunu bu dəyərlə dolduracaq. Bu isə JavaScript protokolunun icrasına imkan verir və nəticədə XSS baş verir. Təbiiki təkcə bu payloadla demək olmaz ki, bütün jQuerylərdə belə bir xss tapmaq olar. Bypass metodlarından Advanced SQL injection məqaləsində danışmışdıq, qısa olaraq üstündən keçək. Case-insensitiv, jAvAsCrİpT, url encoded, ?data:text/html,<script>alert(1)</script> əvəzinə, ?data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== yazmaq olar, spacebar və tabları url encoded ilə dəyişdirmə və.s texnikalar ilə bypass etmək olar. İndi isə laba baxaq.

Əvvəlcə kodu analiz etsək görə bilərik ki, window.location.search ilə url-in query hissəsini götürür. new URLSearchParams(window.location.search)).get(‘returnPath’) query string-dən returnPath parametrini oxuyur. $('#backLink').attr("href", ...) oxunan dəyəri #backLink adlı <a> elementinin href atributuna yazır. Yəni istifadəçi returnpath hissəsini tamamilə idarə edə bilir. Normalda back düyməsi bizi başa aparmalıdır, amma gördüyümüz kimi istifadəçi olaraq buna müdaxilə edə bilirik. Burda müxtəlif payloadlar istifadə edə bilərik, amma çox vaxt sadə olan script alert(1) payloadı filtr olunur, bunun əvəzinə hazır script teqimiz acıq ikən javascripti çağırıb alert(1) pop-up çıxarda bilərik. Payload isə budur, javascript:alert(1).

6.Lab: DOM XSS in jQuery selector sink using a hashchange event
Bu labı kodu analiz edərək həll etməyə çalışaq. Bizə lazım olan script teqindəki dəyərlərdir.

$(window).on(‘hashchange’, …) bu sətirdə window.location.hash dəyişəndə (# ilə başlayan hissə dəyişəndə) işə düşür. Yəni biz url-də #salam yazsaq event trigger olacaq. Məsələn, https://portswigger.com/blog#ms yazsaq ms hissəsi heşlənir. window.location.hash.slice(1) location.hash dəyəri #ms olacaq, slice(1) isə ilk simvolu silir yəni # simvolunu, nəticədə isə təkcə “ms” qalır. decodeURIComponent(…) əgər heş url-encoded formada gəlsə, normal mətnə çevirir, məsələn “salam%20mein” olsa, bunun vasitəsiylə “salam mein” olacaq. $(‘section.blog-list h2:contains(‘ + … + ‘)’) section.blog-list içində olan <h2> teqlərini seçir. :contains(“…”) isə yalnız həmin mətn olan <h2>-ni götürür. Yəni əgər url #Salam mein olarsa, h2:contains(“Salam mein”) formasında olacaq. if (post) post.get(0).scrollIntoView(); Əgər belə <h2> varsa, .get(0) ilk DOM elementini götürür. .scrollIntoView() həmin elementi ekrana gətirir. Nəticədə isə bu kod URL-dəki #hash hissəsinə görə section.blog-list içində uyğun <h2> başlığını tapır və avtomatik scroll edir. Labın yuxarı hissəsindəki go to exploit hissəsinə keçid edək, body hissəsinə <img src=x onmouseover=alert(1)> yazanda xss olacaq, amma labın məqsədi bunda deyil, hash hissəsi ilə xss yaratmağımızı istəyir, bunun üçün bu payloadı yazırıq.
<iframe src=”https://0a09006f031829888081bdf4004b007f.web-security-academy.net/#” onload=”this.src+='<img src=x onerror=alert(1)>'”</iframe>
iframe ilə labı yeni bir səhifəyə yükləyirik, onload atributu → iframe tam yüklənəndə trigger olur.

Amma bizdən istəyirki, alert yerine həmin səhifəyi çap etsin, bunun üçün sadəcə alert(1) yerinə print() yazırıq və bu labı bitiririk.
7.Lab: Reflected XSS into attribute with angle brackets HTML-encoded
Bu labda da koda baxaraq analiz etməyə çalışaq.

js fayllarında innerHTML olmasından əlavə, axtarış hissəsinidə yoxlamalıyıq.

value=”mein” ////onmouseover=”alert(1)”> (// yazılan hissəyə sonra gələcəm) əvvəla işimiz odurki, value=”” hissəsindən bir yolla çıxmalıyıq, bu ya teqi bağlayıb script teqi açıb xss yaratmaq olar, ya da teqdən çıxmadan value hissəsini bypass etmək. Bu labda ikinci seçimlə getməliyik. value=”mein” əgər mən “mein yazsam avtomatik olaraq value hissəsindəki ” işarəsindən çıxır, bir növ “mein hissəsindəki ilk dırnaq valuenin son dırnaq işarəsi olur (ama bu tam olaraq belə deyil). Sonra isə onmouseover=”alert(1) yazaraq xss yarada bilərik. Bəs sual oluna bilər ki, niyə alert-dən sonra dırnaq işarəsi yazmadım? Çünki əvvəl vurğuladığım value hissəsindəki dırnaq məsələsidir, həm valuedən çıxırıq həmdə valuenin son dırnağını payloadımızı bağlamaq üçün istifadə edirik. Lakin url parce olduğuna görə inspect ilə sadəcə value görsənir, daha detallı olaraq edit html deyib baxsaq value=”” olduğunu görə bilərik.
8.Lab: Stored XSS into anchor href attribute with double quotes HTML-encoded
Bu labda stored xss-in href atributu ilə yaranmasından danışacağıq. Laba daxil olduğumuzda comment hissəsinə keçid edirik, website yerine istənilən web sayt yazırıq.

Daxil olduğumuzda görürük ki, bizi qeyd etdiyimiz sayta göndərir. Source kodu isə belədir.

Deməli biz sadəcə javascript:alert(1) yazsaq işləyə bilər, yəni server avtomatik olaraq onu execute oluna bilən bir sayt kimi görür.

Payloadın işləməsini başa düşmək üçün isə bu koda və portswiggerin xss cheat sheetinə baxmağı tövsiyə edirəm.

9.Lab: Reflected XSS into a JavaScript string with angle brackets HTML encoded
Arxada gedən əməliyyata baxaq.

Deməli verdiyimiz input avtomatik olaraq searchTerms dəyərinə mənimsədilir, heç bir filtr olmadan. Bu halda da ən çox tanınan payloaddan istifadə edə bilərik.

‘-alert(1)-‘ o deməkdir ki, birinci tək dırnaq searchTerms dəyərinin ilk dırnağını, ikinci dırnaq isə bu dəyərin son dırnağını bağlayır, -alert(1)- isə artıq real JavaScript ifadəsi kimi işləyir.

“APPRENTICE” dərəcəsində olan ilk 9 labı bitirdim, təbiiki sonrakı hissələrdə hamısını bitirməyə çalışacağam. Oxuduğunuz və həll etdiyiniz üçün təşəkkürlər!
Ümidvaram faydalı olmuşdur.
Bizi izləyin:
Telegram (Kanal): https://t.me/xakeraz_official
Paylaşımların səliqəli yığılmış halı: https://t.me/xakerazgroup
Fikir və şərhləriniz : https://t.me/xakerazchat