Uninitialized Variables

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로부터 영웅이 되는 AWS 해킹을 배우세요**!

HackTricks를 지원하는 다른 방법:

기본 정보

여기서의 핵심 아이디어는 초기화되지 않은 변수가 할당된 메모리에 이미 있는 값으로 설정되는지 이해하는 것입니다. 예시:

  • 함수 1: initializeVariable: 변수 x를 선언하고 값 0x1234를 할당합니다. 이 동작은 메모리에 공간을 예약하고 특정 값을 넣는 것과 유사합니다.

  • 함수 2: useUninitializedVariable: 여기서 다른 변수 y를 선언하지만 값을 할당하지 않습니다. C에서 초기화되지 않은 변수는 자동으로 0으로 설정되지 않습니다. 대신, 그들은 메모리 위치에 마지막으로 저장된 값이 유지됩니다.

이 두 함수를 순차적으로 실행할 때:

  1. initializeVariable에서 x에 값(0x1234)이 할당되어 특정 메모리 주소를 차지합니다.

  2. useUninitializedVariable에서 y가 선언되지만 값이 할당되지 않으므로 x 바로 뒤의 메모리 위치를 차지합니다. y를 초기화하지 않았기 때문에, x가 사용한 메모리 위치에서 마지막으로 있던 값이 y에 "상속"됩니다.

이 동작은 저수준 프로그래밍의 중요한 개념을 보여줍니다: 메모리 관리가 중요하며, 초기화되지 않은 변수는 예측할 수 없는 동작이나 보안 취약점으로 이어질 수 있습니다. 왜냐하면 그들은 의도치 않게 메모리에 남아 있는 민감한 데이터를 보유할 수 있기 때문입니다.

초기화되지 않은 스택 변수는 다음과 같은 보안 위험을 야기할 수 있습니다:

  • 데이터 누출: 암호, 암호화 키 또는 개인 정보와 같은 민감한 정보가 초기화되지 않은 변수에 저장된 경우 노출될 수 있어 공격자가 이 데이터를 읽을 수 있게 됩니다.

  • 정보 노출: 초기화되지 않은 변수의 내용은 프로그램의 메모리 레이아웃이나 내부 작업에 대한 세부 정보를 드러낼 수 있어 공격자가 특정한 공격을 개발하는 데 도움이 됩니다.

  • 크래시 및 불안정성: 초기화되지 않은 변수를 사용하는 작업은 정의되지 않은 동작으로 이어져 프로그램 충돌이나 예측할 수 없는 결과를 초래할 수 있습니다.

  • 임의 코드 실행: 특정 시나리오에서 공격자는 이러한 취약점을 악용하여 프로그램의 실행 흐름을 변경하여 임의 코드를 실행할 수 있게 되어 원격 코드 실행 위협을 포함할 수 있습니다.

예시

#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에서는 전혀 변경되지 않습니다. 여기에서 이를 보여주는 이 예제를 확인하세요.

Last updated