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.
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.
-
İşlevine giriş istemini takip edin
Ajan → REAopen_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çlar0x102004 "What is the flag? " 0x10201c "Incorrect!" 0x102027 "Correct!" Prompt referenced at: 0x10126d Containing function: 0x10124dBaş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.
-
Denetleyiciyi ve iki yardımcısını okuyun
Ajan → REAanalyze_function {"procedure": "0x10124d"} analyze_function {"procedure": "0x101189"} analyze_function {"procedure": "0x101217"}REA → ajan * seçilen talimatlar0x1012c1: 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
0x180x180x270baytlı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.
Maskeyi ve hedefini ikiliden okuyun
{"address": "0x1040e0", "length": 624}
{"address": "0x104060", "length": 144}
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.
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
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.
02 * Maske hücresini kontrol edin. Sıfır değeri karakteri atlar; sıfır olmayan bir değer onu içerir.
03 * Bir karakter kodu ekleyin. Girdinin aynı ofsetteki tamsayı toplamına eklenir.
04 * Bir sonraki hücreye geçin. Orijinal döngü, tamsayı başına dört bayt ilerler ve altı hücreden oluşan altı satırı ziyaret eder.
05 * Saklanan hedefle karşılaştırın. Arayan, toplamı EAX cinsinden alır. Bir uyumsuzluk Incorrect!.
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.
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.
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
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.
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.
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.