Başlatılmamış Değişkenler

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Temel Bilgiler

Buradaki temel fikir, başlatılmamış değişkenlerin atandıkları bellekte önceden bulunan değeri alacaklarını anlamaktır. Örnek:

  • Function 1: initializeVariable: x değişkenini tanımlar ve örneğin 0x1234 değerini atarız. Bu işlem, bellekte bir yer ayırıp belirli bir değer koymaya benzer.
  • Function 2: useUninitializedVariable: Burada y adında başka bir değişken tanımlarız ama hiçbir değer atamayız. C’de başlatılmamış değişkenler otomatik olarak sıfırlanmaz. Bunun yerine, bellek konumlarında en son hangi değer varsa onu korurlar.

Bu iki fonksiyonu ardışık çalıştırdığımızda:

  1. initializeVariable içinde x’e (0x1234) bir değer atanır; bu belirli bir bellek adresini işgal eder.
  2. useUninitializedVariable içinde y tanımlanır ama değer atanmamıştır, bu yüzden x’in hemen ardından gelen bellek alanını kullanır. y başlatılmadığı için, o bellek konumunda en son bulunan değeri “miras” olarak alır; yani x tarafından kullanılan değeri.

Bu davranış, düşük seviyeli programlamanın önemli bir kavramını gösterir: Bellek yönetimi kritik öneme sahiptir, ve başlatılmamış değişkenler bellekten kazara kalan hassas verileri içerebileceği için tahmin edilemez davranışlara veya güvenlik açıklarına yol açabilir.

Başlatılmamış stack değişkenleri şu tür güvenlik riskleri oluşturabilir:

  • Data Leakage: Parolalar, şifreleme anahtarları veya kişisel bilgiler gibi hassas veriler başlatılmamış değişkenlerde bulunuyorsa açığa çıkabilir; bu, saldırganların bu verileri okuyabilmesine olanak tanır.
  • Information Disclosure: Başlatılmamış değişkenlerin içeriği programın bellek düzeni veya iç işleyişi hakkında bilgiler açığa çıkarabilir, bu da saldırganların hedefe yönelik exploit geliştirmesine yardımcı olur.
  • Crashes and Instability: Başlatılmamış değişkenlerle yapılan işlemler tanımsız davranışa yol açabilir, bu da program çökmesine veya öngörülemez sonuçlara neden olabilir.
  • Arbitrary Code Execution: Bazı senaryolarda, saldırganlar bu zayıflıkları programın yürütme akışını değiştirmek için kullanabilir ve keyfi kod çalıştırmalarına (örneğin remote code execution tehditleri) izin verebilir.

Örnek

#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;
}

Nasıl Çalışır:

  • initializeAndPrint Function: Bu fonksiyon bir integer değişkeni initializedVar olarak tanımlar, ona 100 değerini atar ve sonra değişkenin hem bellek adresini hem de değerini yazdırır. Bu adım basittir ve başlatılmış bir değişkenin nasıl davrandığını gösterir.
  • demonstrateUninitializedVar Function: Bu fonksiyonda, uninitializedVar adlı bir integer değişken tanımlanır ancak başlatılmaz. Değerini yazdırmaya çalıştığımızda çıktı rastgele bir sayı gösterebilir. Bu sayı, o bellek konumunda daha önce bulunan veriyi temsil eder. Ortama ve derleyiciye bağlı olarak gerçek çıktı değişebilir ve bazen güvenlik amacıyla bazı derleyiciler değişkenleri otomatik olarak sıfıra başlatabilir; fakat buna güvenilmemelidir.
  • main Function: main fonksiyonu yukarıdaki her iki fonksiyonu sırayla çağırır ve başlatılmış bir değişken ile başlatılmamış bir değişken arasındaki farkı gösterir.

Pratik istismar örüntüleri (2024–2025)

The classic “read-before-write” bug remains relevant because modern mitigations (ASLR, canaries) often rely on secrecy. Typical attack surfaces:

  • Partially initialized structs copied to userland: Kernel or drivers frequently memset only a length field and then copy_to_user(&u, &local_struct, sizeof(local_struct)). Padding and unused fields leak stack canary halves, saved frame pointers or kernel pointers. If the struct contains a function pointer, leaving it uninitialized may also allow controlled overwrite when later reused.
  • Uninitialized stack buffers reused as indexes/lengths: An uninitialized size_t len; used to bound read(fd, buf, len) may give attackers out-of-bounds reads/writes or allow bypassing size checks when the stack slot still contains a large value from a prior call.
  • Compiler-added padding: Even when individual members are initialized, implicit padding bytes between them are not. Copying the whole struct to userland leaks padding that often contains prior stack content (canaries, pointers).
  • ROP/Canary disclosure: If a function copies a local struct to stdout for debugging, uninitialized padding can reveal the stack canary enabling subsequent stack overflow exploitation without 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;
}

Önlemler ve derleyici seçenekleri (baypas ederken akılda tutulmalı)

  • Clang/GCC auto-init: Recent toolchains expose -ftrivial-auto-var-init=zero or -ftrivial-auto-var-init=pattern, filling every automatic (stack) variable at function entry with zeros or a poison pattern (0xAA / 0xFE). Bu, çoğu uninitialized-stack info leak’i kapatır ve gizli verileri bilinen değerlere çevirerek exploitation’ı zorlaştırır.
  • Linux kernel hardening: Kernels built with CONFIG_INIT_STACK_ALL or the newer CONFIG_INIT_STACK_ALL_PATTERN zero/pattern-initialize every stack slot at function entry, wiping canaries/pointers that would otherwise leak. Bu seçeneklerin etkin olduğu Clang ile derlenmiş kernel’leri gönderen dağıtımlara bakın (6.8+ hardening konfigürasyonlarında yaygın).
  • 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. Bu tür annotasyonları dikkatle inceleyin—genellikle side channels için kasıtlı bir attack surface işaret ederler.

Bir saldırgan açısından, ikilinin bu bayraklarla derlenip derlenmediğini bilmek, stack-leak primitives’in uygulanabilir olup olmadığını veya heap/data-section disclosures’a pivot etmeniz gerekip gerekmediğini belirler.

Finding uninitialized-stack bugs quickly

  • Compiler diagnostics: Build with -Wall -Wextra -Wuninitialized (GCC/Clang). For C++ code, clang-tidy -checks=cppcoreguidelines-init-variables will 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=yes reliably flag reads of uninitialized stack bytes during fuzzing. Test harness’larını bu araçlarla instrument ederek ince padding leak’lerini ortaya çıkarın.
  • Grepping patterns: In reviews, search for copy_to_user / write calls of whole structs, or memcpy/send of stack data where only part of the struct is set. Hata yollarında başlatmanın atlandığı durumlara özellikle dikkat edin.

ARM64 Example

This doesn’t change at all in ARM64 as local variables are also managed in the stack, you can check this example were this is shown.

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin