mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
67 lines
4.9 KiB
Markdown
67 lines
4.9 KiB
Markdown
# 초기화되지 않은 변수
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## 기본 정보
|
|
|
|
여기서 핵심 아이디어는 **초기화되지 않은 변수가 할당된 메모리에 이미 존재하는 값을 가지게 된다는 것을 이해하는 것입니다.** 예를 들어:
|
|
|
|
- **함수 1: `initializeVariable`**: 우리는 변수 `x`를 선언하고 값을 할당합니다. 예를 들어 `0x1234`라고 합시다. 이 작업은 메모리에서 자리를 예약하고 그 안에 특정 값을 넣는 것과 같습니다.
|
|
- **함수 2: `useUninitializedVariable`**: 여기서 우리는 또 다른 변수 `y`를 선언하지만 값은 할당하지 않습니다. C에서는 초기화되지 않은 변수가 자동으로 0으로 설정되지 않습니다. 대신, 마지막으로 해당 메모리 위치에 저장된 값을 유지합니다.
|
|
|
|
이 두 함수를 **순차적으로** 실행할 때:
|
|
|
|
1. `initializeVariable`에서 `x`는 값(`0x1234`)이 할당되어 특정 메모리 주소를 차지합니다.
|
|
2. `useUninitializedVariable`에서 `y`는 선언되지만 값이 할당되지 않으므로 `x` 바로 뒤의 메모리 자리를 차지합니다. `y`를 초기화하지 않음으로써, `x`가 사용한 동일한 메모리 위치에서 마지막 값인 "상속"을 받게 됩니다.
|
|
|
|
이 행동은 저수준 프로그래밍의 핵심 개념을 설명합니다: **메모리 관리가 중요하며**, 초기화되지 않은 변수는 예측할 수 없는 행동이나 보안 취약점을 초래할 수 있습니다. 왜냐하면 이들은 메모리에 남아 있는 민감한 데이터를 의도치 않게 보유할 수 있기 때문입니다.
|
|
|
|
초기화되지 않은 스택 변수는 여러 보안 위험을 초래할 수 있습니다:
|
|
|
|
- **데이터 유출**: 비밀번호, 암호화 키 또는 개인 정보와 같은 민감한 정보가 초기화되지 않은 변수에 저장될 경우 노출될 수 있으며, 공격자가 이 데이터를 읽을 수 있는 가능성이 있습니다.
|
|
- **정보 공개**: 초기화되지 않은 변수의 내용은 프로그램의 메모리 레이아웃이나 내부 작업에 대한 세부 정보를 드러낼 수 있으며, 이는 공격자가 표적 공격을 개발하는 데 도움을 줄 수 있습니다.
|
|
- **충돌 및 불안정성**: 초기화되지 않은 변수를 포함하는 작업은 정의되지 않은 행동을 초래할 수 있으며, 이는 프로그램 충돌이나 예측할 수 없는 결과를 초래할 수 있습니다.
|
|
- **임의 코드 실행**: 특정 시나리오에서 공격자는 이러한 취약점을 악용하여 프로그램의 실행 흐름을 변경하고 임의 코드를 실행할 수 있으며, 이는 원격 코드 실행 위협을 포함할 수 있습니다.
|
|
|
|
### 예시
|
|
```c
|
|
#include <stdio.h>
|
|
|
|
// Function to initialize and print a variable
|
|
void initializeAndPrint() {
|
|
int initializedVar = 100; // Initialize the variable
|
|
printf("Initialized Variable:\n");
|
|
printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar);
|
|
}
|
|
|
|
// Function to demonstrate the behavior of an uninitialized variable
|
|
void demonstrateUninitializedVar() {
|
|
int uninitializedVar; // Declare but do not initialize
|
|
printf("Uninitialized Variable:\n");
|
|
printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar);
|
|
}
|
|
|
|
int main() {
|
|
printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n");
|
|
|
|
// First, call the function that initializes its variable
|
|
initializeAndPrint();
|
|
|
|
// Then, call the function that has an uninitialized variable
|
|
demonstrateUninitializedVar();
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
#### 이 작동 방식:
|
|
|
|
- **`initializeAndPrint` 함수**: 이 함수는 정수 변수 `initializedVar`를 선언하고, 그 값에 `100`을 할당한 다음, 변수의 메모리 주소와 값을 출력합니다. 이 단계는 간단하며 초기화된 변수가 어떻게 작동하는지를 보여줍니다.
|
|
- **`demonstrateUninitializedVar` 함수**: 이 함수에서는 초기화하지 않은 정수 변수 `uninitializedVar`를 선언합니다. 그 값을 출력하려고 시도할 때, 출력은 무작위 숫자를 보여줄 수 있습니다. 이 숫자는 해당 메모리 위치에 이전에 있던 데이터를 나타냅니다. 환경과 컴파일러에 따라 실제 출력은 달라질 수 있으며, 때때로 안전을 위해 일부 컴파일러는 변수를 자동으로 0으로 초기화할 수 있지만, 이는 신뢰해서는 안 됩니다.
|
|
- **`main` 함수**: `main` 함수는 위의 두 함수를 순차적으로 호출하여 초기화된 변수와 초기화되지 않은 변수의 차이를 보여줍니다.
|
|
|
|
## ARM64 예제
|
|
|
|
ARM64에서는 로컬 변수가 스택에서 관리되므로 전혀 변경되지 않습니다. 여기에서 [**이 예제를 확인할 수 있습니다**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) .
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|