Örnek olay incelemesi * DownUnderCTF 2023

Bayrağı bulun
bir CTF ikilisi.

Küçük bir bayrak denetleyicisini incelemek, kurallarını denklemlere dönüştürmek ve orijinal program baskısını REArea'yıCorrect!.

maskeli kareler bayrak denetleyicisi * Kolay * Linux x86-64

Orijinal meydan okumayı görüntüle

Bir ikiliden doğrulanmış bir cevaba

  1. 01 * Kontrol Dizelerini Bulun → işlevleri kontrol etme REA, bir girişi kabul eden veya reddeden istemi, referanslarını ve kodu bulur.
  2. 02 * Kuralları ayıkla 36 karakter * 26 toplam REA, her çekin arkasındaki talimatları ve verileri döndürür. Ajan onları denklemlere dönüştürür.
  3. 03 * Kurtarılan bayrağı çözün ve çalıştırın → Düzeltin!Bir Python betiği denklemleri çözer. REA, sonucu kabul eden orijinal programı yakalar.
Zorluk, Downunderctf'nin resmi deposunda yayınlanan joseph tarafından.

Kontrol kodunu bulun

Bildiri 15 KB'lık bir yürütülebilir dosyadır. Bir bayrak ister, sonra Correct! veya Incorrect!. Temsilcinize basit bir istekle başlayın.

Kodlama aracınız

Ms_flag_checker'ı analiz etmek ve bayrağı bulmak için REA kullanın. Kontrollerin nasıl çalıştığını açıklayın, ardından cevabı orijinal programla doğrulayın.

İndirilen zorluğun yerel olarak kullanılabildiği ve makine kodu programlarının sağlayıcısına bağlı bir analizinin yapıldığı örnek bir bilgi istemi.

  1. İşlevine giriş istemini takip edin

    Ajan → REA
    open_binary
    {"path": "ms_flag_checker"}
    
    search_strings
    {"pattern": "flag|correct|wrong|input",
     "mode": "regex", "case_sensitive": false}
    
    xrefs
    {"address": "0x102004"}
    
    resolve_containing_procedure
    {"address": "0x10126d"}
    REA → temsilci * seçilen sonuçlar
    0x102004  "What is the flag? "
    0x10201c  "Incorrect!"
    0x102027  "Correct!"
    
    Prompt referenced at: 0x10126d
    Containing function: 0x10124d

    Başvuru, yürütülebilir dosyanın özgün işlev adları kaldırılmış olsa bile aracıya araştırılacak bir yer verir.

  2. Denetleyiciyi ve iki yardımcısını okuyun

    Ajan → REA
    analyze_function
    {"procedure": "0x10124d"}
    
    analyze_function
    {"procedure": "0x101189"}
    
    analyze_function
    {"procedure": "0x101217"}
    REA → ajan * seçilen talimatlar
    0x1012c1: CMP EDI, 0x24
    0x1012c6: LEA RBX, [0x1040e0]
    0x1012cd: LEA RBP, [0x104060]
    0x1012d4: LEA R13, [RBX + 0x270]
    0x1012e1: CALL 0x00101189
    0x1012ec: CALL 0x00101217
    0x1012f1: CMP dword ptr [RBP], EAX
    0x1012f4: JNZ 0x00101335
    0x1012f6: ADD RBX, 0x18

    İlk döngü 36 karakter kodunu kopyalar. Kontrol döngüsü bir maskenin kodunu çözer, seçilen kodları toplar ve sonucu saklanan bir sayı ile karşılaştırır. 0x270 bayttaki 0x180x180x270 baytlık adımları 26 maske verir.

Bunlar, yeni bir REA analizinden seçilen sonuçlardır. Yerel hedef yol görüntüleme için kısaltılmıştır; adresler REA içe aktarılan görüntüsü.

Bir kontrol bir karakteri ortaya çıkarır

Denetleyici, girişi 6 × 6 ızgarada düzenler. Bir maske, hangi hücrelerin bir miktara katkıda bulunduğunu seçer. Kompakt kodlaması, hücreleri atlamak için negatif sayılar ve bunları seçmek için pozitif sayılar kullanır.

Yedinci maske 21 hücreyi atlar, 21 konumunu seçer, ardından 14'ü atlar. Sadece bu hücre toplamına katkıda bulunur. Gerekli karakter kodu 55'tir, yani karakter 7'dir.
Yedinci kontrol sadece bir pozisyon seçer. Açık rakam.

Maskeyi ve hedefini ikiliden okuyun

Aracı → REA * read_bytes
{"address": "0x1040e0", "length": 624}
{"address": "0x104060", "length": 144}
REA → aracı * yedinci girişler
Mask at 0x104170:
eb 01 f2 00  →  -21, +1, -14, stop

Target at 0x104078:
37 00 00 00  →  55

MOVSX yönergesi, maske baytlarını imzalı değerler MOVSX okur. Bu yüzden eb -21 anlamına gelir. Hedef küçük endian bir tamsayıdır. Birlikte, bu baytlar aracıya code[21] = 55557 olduğunu söyler, böylece karakter 7olur.

Talimatlardan okunabilir bir kontrole

Toplama yardımcısını ve arayanını C'de aynı kurala bağlamak için bir adım seçin.

REA * seçilen orijinal talimatlar
0x10121c: MOV ECX, 0x0

0x10122c: CMP dword ptr [RSI + RAX*0x1], 0x0
0x101230: JZ 0x00101223

0x101232: ADD ECX, dword ptr [RDI + RAX*0x1]

0x101223: ADD RAX, 0x4

0x1012f1: CMP dword ptr [RBP], EAX
0x1012f4: JNZ 0x00101335
Okunabilir C * tek kontrol özeti
int check_one_mask(const int codes[36],
                   const int mask[36],
                   int target) {
    int total = 0;
    for (int i = 0; i < 36; ++i) {
        if (mask[i]) {
            total += codes[i];
        }
    }
    return total == target;
}

01 * Sıfırdan başlayın. ECX çalışan toplamı tutar.

Talimatlar toplama yardımcısından ve arayanından gelir. C, açıklayıcı adlara ve düzleştirilmiş 36 hücreli bir döngüye sahip açıklayıcı bir özettir.

26 Denklemi çözün

Çoğu maske birkaç hücre seçer. Örneğin, ilk kontrol 16 karakter kodu ekler ve toplam 1441 gerektirir. Örtüşen seçimler, küçük bir Python betiğinin birlikte çözebileceği denklemler verir.

Python * çözücü alıntı
from z3 import Int, Or, Solver, Sum, sat

codes = [Int(f"code_{i}") for i in range(36)]
solver = Solver()
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}"
for code in codes:
    solver.add(Or(*[code == ord(c) for c in alphabet]))
for code, char in zip(codes, "DUCTF{"):
    solver.add(code == ord(char))
solver.add(codes[-1] == ord("}"))

for selected, target in checks:
    solver.add(Sum([codes[i] for i in selected]) == target)

assert solver.check() == sat
model = solver.model()
print("".join(chr(model.eval(code).as_long()) for code in codes))

Z3, bu denklemleri karşılayan değerleri bulan bir çözücüdür. Bu alıntı, çıkarılan çekleri kullanır ve harf, rakam, alt çizgi ve parantez içeren bir DUCTF{…} bayrağı varsayar. Tam indirme, 26 maskenin ve hedefin tümünü içerir.

Tam çözücüyü indirin

Cevabı orijinal programla kontrol edin

REA işlem yakalama, çözülen bayrağı kabul eden orijinal yürütülebilir dosyayı kaydeder. Seçilen bir karakteri z y değiştirmek, ilk toplamı 1441 yerine 1440 yapar ve program bunu reddeder.

Giriş Gözlenen çıktı Çıkış kodu
Çözücünün bayrağı Correct! 0
Bir karakter değişti Incorrect! 255
Kurtarılan bayrağı ve yakalanan çıktıyı göster
REA * orijinal program çıktısı
What is the flag? DUCTF{ezzzpzzz_07bcda7bfe81faf43caa}
Correct!

Kurtarılan değer, ikili dosyayı çözdükten sonra kontrol edilen düzenleyicilerin yayınlanmış meydan okuma meta verilerindeki bayrakla da eşleşir.

Kaynak, hedef kimliği ve analiz detayları

Linux x64'te Ghidra 12.1.4 ile REA 4.1.0 kullanılarak 8 Ekim 2026'da yeni analiz ve iki işlem kaydı. İkili, soyulmuş bir x86-64 ELF, 15.248 bayttır.

Orijinal çalıştırılabilir * SHA-256
dcd3bec4f608e11f3a12ce461100aaf5f621851ee63a1f870d7c90d4e3dd51ae

Dize referansları, işlevler ve sabitler, düzenleyicilerin kaynağını veya çözümünü okumadan önce incelendi. Python çözücü ve diyagram bu REA sonuçlarından oluşturulmuştur.

Organizatörlerin kaynağıyla karşılaştırın * Meta verilere ve bayrağa meydan okuyun * REA kanıt notları

Kendin dene

Orijinal mücadeleyi ve çözücüyü tek bir klasöre indirin. Aracınızla araştırmak veya birlikte verilen komut dosyasını çalıştırmak için yukarıdaki istemi kullanın.

Terminal * çöz ve çalıştır
python3 -m venv .venv
.venv/bin/python -m pip install z3-solver
.venv/bin/python solve.py

chmod +x ms_flag_checker
./ms_flag_checker

Komut dosyası bir aday bayrağı yazdırır; Programın istemine yapıştırın. Çözmenin Python ve z3-solver ihtiyacı var. Orijinal yürütülebilir dosyayı çalıştırmak için Linux x86-64 gerekir.

Kodlama aracınızla REA'YU kurun

Üst