Badi Ekrem Crackme

TARİH: 2026-05-14HEDEF: Badi Ekrem Crackme

Hedef: Binary dosyası içindeki Anti-Debugging ve SMC (Self-Modifying Code) korumalarını atlatarak gerçek flag’i elde etmek.

1. İlk İnceleme ve Sazan Avı

Dosyayı ilk incelediğimde, okunabilir metinleri bulmak ve ilk ipuçlarını yakalamak amacıyla strings komutunu çalıştırdım..

strings crackme2

Çıktıyı incelediğimde karşıma standart flag formatı (FLAG{...} çıkmadı ancak çıktıların arasında dikkat çekici birkaç satır yakaladım:

/proc/%d/comm
strace
ltrace
radare2

2. Dinamik Analiz ve GDB İllüzyonu

Binary dosyasının stripped olması ve Linux kütüphane yükleyicisinin IFUNC optimizasyonları, klasik strcmp breakpoint analizini atlatıyordu. Bu nedenle doğrudan programın bellek yönetimine odaklanmak için Stack Analizi yöntemini seçtim.

C dilinde yerel değişkenlerin stack üzerinde ardışık olarak tahsis edildiğini bilerek programın ekrana mesaj yazdırdığı anı yakalamak için write sistem çağrısına catchpoint koydum.

(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [1])
(gdb) run
#Gelen ilk write çağrılarını (Karşılama mesajları) 'continue' ile geçtim.
=== Trackbook Crackme 2 ===
Lutfen flag giriniz: AAAAAAAA

Test verisi olarak AAAAAAAA girdim. Program mesajını terminale basmak üzereyken GDB write syscall’ını yakaladı ve durdu. Tam bu esnada program sonlanmadığı için main fonksiyonunun stack alanı bellekte canlıydı. Unmapped sayfa hatalarına düşmemek için, doğrudan aktif Stack Pointer’dan ($rsp) başlayarak 4000 byte’lık kesin eşleşmiş RAM alanında kendi girdimi arattım:

(gdb) find (char*)$rsp, (char*)$rsp + 4000, "AAAAAAAA"
0x7fffffffd840
1 pattern found.

Kendi girdiğim metnin 0x7fffffffd840 adresinde olduğunu tespit ettim. İncelemelerim sonucunda, programın kullanıcı girdisini muhtemelen char input[64] gibi 64 byte’lık bir buffer içinde tuttuğunu gördüm. Çünkü benim girdiğim 8 karakterden (“AAAAAAAA”) sonraki kısımlar null-byte (\0) ile doluydu.

(gdb) x/20s 0x7fffffffd840
0x7fffffffd840: "AAAAAAAA"
0x7fffffffd849: ""
0x7fffffffd84a: ""
0x7fffffffd84b: ""
0x7fffffffd84c: ""
0x7fffffffd84d: ""
0x7fffffffd84e: ""
0x7fffffffd84f: ""
0x7fffffffd850: ""
0x7fffffffd851: ""
0x7fffffffd852: ""
0x7fffffffd853: ""
0x7fffffffd854: ""
0x7fffffffd855: ""
0x7fffffffd856: ""
0x7fffffffd857: ""
0x7fffffffd858: ""
0x7fffffffd859: ""
0x7fffffffd85a: ""
0x7fffffffd85b: ""

Programın bizim girdimizle karşılaştırdığı asıl şifreli metnin bu buffer’ın hemen bitiminde yer alacağını hesaplayarak girdimin bulunduğu adrese 64 byte (Hexadecimal: 0x40) ekledim ve o adresi string olarak okudum:

(gdb) x/10s 0x7fffffffd880
0x7fffffffd880: "FLAG{Tebrikler_Dogru_Flag}"
0x7fffffffd89b: ""
0x7fffffffd89c: ""
0x7fffffffd89d: ""
0x7fffffffd89e: ""
0x7fffffffd89f: ""
0x7fffffffd8a0: ""
0x7fffffffd8a1: ""
0x7fffffffd8a2: ""
0x7fffffffd8a3: ""

Bellek analizi ve buffer hesaplamam doğruydu! Kendi input değişkenimin 64 byte’lık sınırının hemen bitişiğinde, programın arka planda çözdüğü FLAG{Tebrikler_Dogru_Flag} metnini yakaladım. Statik analizde tamamen gizlenen bu sahte flag’i, IFUNC optimizasyonlarını atlatarak bellekten fiziksel olarak sökmüş oldum. Programı sonlandırıp normal akışta bu flag’i denedim:


Şekil 1: Fake flag

Program bana hababam sınıfındaki meşhur Badi Ekrem’in kiremit kırma sahnesinin YouTube linkini verdi. Yani kırabiliceğimi düşünerek ilerlediğim bu yolda kendi bacağımı kırmıştım. GDB üzerinden bizzat bellekten okuduğum verinin yalan olduğunu programın debugger’ı tespit edip bana bilerek fake bir flag ürettiğini fark ettim. Asıl mekanizmayı anlamak için Ghidra ile statik tersine mühendisliğe başladım.


Şekil 2: Badi Ekrem

3. Ghidra ve Algoritma Analizi

Ghidra ile programı decompile ettiğimde programın akışını tamamen değiştiren iki büyük koruma mekanizması tespit ettim.

Koruma 1: Parent Process Detection

İlk statik analizde bulduğum stringlerin kaynağı olan is_debugger_present() fonksiyonu, /proc/[pid]/comm dosyasını okuyarak programı gdb, strace veya ltrace gibi bir analiz aracının başlatıp başlatmadığını kontrol ediyordu. Debugger tespit edildiğinde fonksiyon çökmek yerine 1 döndürerek sessizce akışa devam ediyordu.

//is_debugger_present() fonksiyonu (FUN_001011f9) cagiriliyor 
  uVar1 = FUN_001011f9(); 
  
  //Donen sonuc (debugger var/yok durumu) dinamik shellcode'a parametre olarak veriliyor
  iVar2 = (*__addr)(uVar1);

Koruma 2: In-Memory Execution & Self-Modifying Code (SMC)

main fonksiyonunun devamında mmap ile bellekte çalıştırılabilir (bir alan açıldığını ve buraya enc_shellcode isimli şifreli bir hex dizisinin 0x55 XOR anahtarıyla çözülerek yazıldığını gördüm:

__addr = mmap((void *)0x0,6,7,0x22,-1,0);
  if (__addr == (code *)0xffffffffffffffff) {
    uVar5 = 1;
  }
  else {
    for (local_1bc = 0; local_1bc < 6; local_1bc = local_1bc + 1) {
      __addr[(int)local_1bc] = (code)((&DAT_00104078)[(int)local_1bc] ^ 0x55);
    }

4. Shellcode Analizi ve Gerçek Anahtarı Bulma

Ghidra üzerinden enc_shellcode dizisini çıkardım: DC AD D6 95 64 96.

Bu diziyi 0x55 ile XOR işlemine soktuğumda ortaya çıkan makine kodunu disassembler aracıyla Assembly diline çevirdim:

mov eax, edi    ;Parametreyi (Debugger durumunu) EAX registerına al
add eax, 0x31   ;EAX'in uzerine 0x31 ekle
ret             ;Degeri dondur

SMC Algoritmasının Çözümü:

GDB’de dinamik analiz yaparken programın 0x32 anahtarıyla çalışıp sahte flag’i bellekte çözdüğünü ve beni bir illüzyonun içine çektiğini bu noktada matematiksel olarak kanıtlamış oldum.

5. String Obfuscation ve Flag Elde Edinimi

Gerçek akış için anahtarın 0x31 olduğunu öğrendikten sonra, Ghidra’da flag_key == 0x31 bloğunun içinde kontrol edilen gerçek şifreli diziyi (enc_real_flag) buldum.

Gerçek flagi elde etmek için CyberChef aracını kullanarak statik hex dizisine 0x31 anahtarı ile XOR işlemi uyguladım:


Şekil 3: Gerçek flag'in CyberChef ile çözülmesi

Deşifre Edilen Gerçek Bayrak: MZVY{Badi_Ekrem}

6. Doğrulama

Elde ettiğim flag’i doğrulamak amacıyla programı bu kez herhangi bir debugger kullanmadan normal akışta çalıştırdım.


Şekil 4: Flag doğrulama

Program gerçek flag’i kabul etti ve arka planda 0x55 ile şifrelenmiş olan tebrik mesajını çözerek “Yaparsin anam yaparsin yavrucugum :)” mesajıyla birlikte İnek Şabanın kesitinin olduğu YouTube linkini ekrana yazdırdı. Hem dinamik analiz tuzağı hem de SMC koruması başarıyla atlatılarak flag elde edildi.


Şekil 5: İnek Şaban