초기화되지 않은 변수
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
핵심 아이디어는 초기화되지 않은 변수는 해당 메모리 주소에 이미 있던 값을 갖게 된다는 사실을 이해하는 것이다. 예:
- Function 1:
initializeVariable: 변수x를 선언하고 값(예:0x1234)을 할당한다. 이 동작은 메모리의 한 자리를 예약하고 특정 값을 넣는 것과 같다. - Function 2:
useUninitializedVariable: 여기서는 또 다른 변수y를 선언하지만 값을 할당하지 않는다. C에서는 초기화되지 않은 변수가 자동으로 0으로 설정되지 않는다. 대신 해당 메모리 위치에 마지막으로 저장되어 있던 값을 그대로 유지한다.
이 두 함수를 순차적으로 실행하면:
initializeVariable에서x에 값(0x1234)이 할당되며, 이는 특정 메모리 주소를 차지한다.useUninitializedVariable에서는y가 선언되지만 값이 할당되지 않아x바로 다음 메모리 위치를 차지한다.y를 초기화하지 않았기 때문에 그 메모리 위치에 마지막으로 남아 있던 값(즉x가 사용한 값)을 ’상속’받게 된다.
이 동작은 저수준 프로그래밍의 핵심 개념을 보여준다: 메모리 관리가 중요하다는 것. 초기화되지 않은 변수는 메모리에 남아 있던 민감한 데이터를 의도치 않게 보유할 수 있어 예측 불가능한 동작이나 보안 취약점으로 이어질 수 있다.
초기화되지 않은 스택 변수는 다음과 같은 여러 보안 위험을 초래할 수 있다:
- Data Leakage: 비밀번호, 암호화 키 또는 개인 정보 같은 민감한 정보가 초기화되지 않은 변수에 남아 있으면 노출될 수 있으며, 공격자가 해당 데이터를 읽을 수 있다.
- Information Disclosure: 초기화되지 않은 변수의 내용은 프로그램의 메모리 레이아웃이나 내부 동작에 대한 정보를 드러내어 공격자가 표적화된 익스플로잇을 개발하는 데 도움을 줄 수 있다.
- Crashes and Instability: 초기화되지 않은 변수를 사용하는 연산은 정의되지 않은 동작을 일으켜 프로그램 충돌이나 예측 불가능한 결과를 초래할 수 있다.
- Arbitrary Code Execution: 특정 시나리오에서는 공격자가 이러한 취약점을 이용해 프로그램의 실행 흐름을 변경하여 임의의 코드를 실행할 수 있으며, 이는 원격 코드 실행 위협을 포함할 수 있다.
예제
#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;
}
How This Works:
initializeAndPrintFunction: 이 함수는 정수 변수initializedVar를 선언하고 값100을 대입한 뒤, 변수의 메모리 주소와 값을 출력합니다. 이 단계는 단순하며 초기화된 변수가 어떻게 동작하는지 보여줍니다.demonstrateUninitializedVarFunction: 이 함수에서는 정수 변수uninitializedVar를 초기화하지 않고 선언합니다. 값을 출력하려 하면 출력이 무작위 숫자를 보일 수 있습니다. 이 숫자는 해당 메모리 위치에 이전에 있던 데이터를 나타냅니다. 환경과 컴파일러에 따라 실제 출력은 달라질 수 있고, 일부 컴파일러는 안전을 위해 변수를 자동으로 0으로 초기화할 수도 있지만, 이를 신뢰해서는 안 됩니다.mainFunction:main함수는 위 두 함수를 순서대로 호출하여 초기화된 변수와 초기화되지 않은 변수의 차이를 보여줍니다.
Practical exploitation patterns (2024–2025)
고전적인 “read-before-write” 버그는 여전히 유효합니다. 현대의 완화책(ASLR, canaries)이 종종 비밀 유지에 의존하기 때문입니다. 일반적인 공격 표면:
- Partially initialized structs copied to userland: 커널이나 드라이버는 종종 길이 필드만
memset하고copy_to_user(&u, &local_struct, sizeof(local_struct))를 호출합니다. 패딩과 사용되지 않은 필드는 stack canary halves, saved frame pointers 또는 kernel pointers를 leak 합니다. 구조체에 function pointer가 포함되어 있다면, 이를 초기화하지 않으면 나중에 재사용될 때 controlled overwrite를 허용할 수도 있습니다. - Uninitialized stack buffers reused as indexes/lengths: 초기화되지 않은
size_t len;가read(fd, buf, len)의 경계를 정하는 데 사용되면, 해당 스택 슬롯이 이전 호출의 큰 값을 유지하고 있을 때 공격자가 범위를 벗어난 읽기/쓰기(out-of-bounds reads/writes)를 하거나 크기 검사를 우회할 수 있습니다. - Compiler-added padding: 개별 멤버가 초기화되어 있어도 그 사이의 암묵적 패딩 바이트는 초기화되지 않습니다. 구조체 전체를 userland로 복사하면 이전 스택 내용(canaries, pointers)을 포함하는 패딩이 leak 됩니다.
- ROP/Canary disclosure: 함수가 디버깅을 위해 로컬 구조체를 stdout으로 복사하면, 초기화되지 않은 패딩이 stack canary를 드러내어 이후의 stack overflow 공격을 brute-force 없이 가능하게 할 수 있습니다.
Minimal PoC pattern to detect such issues during review:
struct msg {
char data[0x20];
uint32_t len;
};
ssize_t handler(int fd) {
struct msg m; // never fully initialized
m.len = read(fd, m.data, sizeof(m.data));
// later debug helper
write(1, &m, sizeof(m)); // leaks padding + stale stack
return m.len;
}
완화책 및 컴파일러 옵션 (우회 시 염두에 둘 것)
- Clang/GCC auto-init: Recent toolchains expose
-ftrivial-auto-var-init=zeroor-ftrivial-auto-var-init=pattern, filling every automatic (stack) variable at function entry with zeros or a poison pattern (0xAA / 0xFE). 이는 함수 진입 시 모든 자동(stack) 변수를 0 또는 패턴으로 채워 대부분의 uninitialized-stack info leaks를 차단하고, 비밀값을 알려진 값으로 바꿔 exploitation을 더 어렵게 만듭니다. - Linux kernel hardening: Kernels built with
CONFIG_INIT_STACK_ALLor the newerCONFIG_INIT_STACK_ALL_PATTERNzero/pattern-initialize every stack slot at function entry, wiping canaries/pointers that would otherwise leak. 이러한 옵션으로 빌드된(특히 Clang으로 빌드된) 커널을 배포하는 배포판을 찾아보세요(6.8+ 하드닝 구성에서 흔함). - Opt-out attributes: Clang now allows
__attribute__((uninitialized))on specific locals/structs to keep performance-critical areas uninitialized even when global auto-init is enabled. 이러한 어노테이션은 성능 상 중요한 영역을 의도적으로 초기화하지 않기 위해 사용되므로 주의 깊게 검토하세요—종종 side channels을 노린 공격 표면을 표시합니다.
공격자 관점에서는 바이너리가 이러한 플래그로 빌드되었는지 여부가 stack-leak primitives가 실용적인지, 아니면 heap/data-section disclosures로 전환해야 하는지를 결정합니다.
Finding uninitialized-stack bugs quickly
- 컴파일러 진단(Compiler diagnostics): Build with
-Wall -Wextra -Wuninitialized(GCC/Clang). For C++ code,clang-tidy -checks=cppcoreguidelines-init-variableswill auto-fix many cases to zero-init and is handy to spot missed locals during audit. - 동적 도구(Dynamic tools):
-fsanitize=memory(MSan) in Clang or Valgrind’s--track-origins=yesreliably flag reads of uninitialized stack bytes during fuzzing. 테스트 하니스에 이 도구들을 적용하면 미세한 padding leaks를 드러낼 수 있습니다. - Grepping 패턴(Grepping patterns): 코드 리뷰 시 전체 구조체를 대상으로 하는
copy_to_user/write호출이나, 구조체의 일부만 설정된 상태에서의memcpy/send같은 stack 데이터 전송을 검색하세요. 초기화가 건너뛰어지는 에러 경로에 특히 주의하세요.
ARM64 예시
ARM64에서는 로컬 변수가 역시 stack에서 관리되므로 전혀 달라지지 않습니다. 이는 check this example에서 확인할 수 있습니다.
References
- CONFIG_INIT_STACK_ALL_PATTERN documentation
- GHSL-2024-197: GStreamer uninitialized stack variable leading to function pointer overwrite
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


