کد چک کردن را پیدا کنید
این کتابچه یک فایل اجرایی 15 کیلو بایت است. پرچم ميخواد ، بعدش چاپ ميکنه Correct! یا Incorrect!. با یک درخواست ساده به نماینده خود شروع کنید.
از REA برای تجزیه و تحلیل ms_flag_checker و پیدا کردن پرچم استفاده کنید. نحوه کار چک ها را توضیح دهید ، سپس پاسخ را با برنامه اصلی تأیید کنید.
یک مثال سریع، با چالش دانلود شده در دسترس محلی و تجزیه و تحلیل ارائه دهنده برنامه های کد ماشین متصل شده است.
-
از دستور ورودی به تابع آن پیروی کنید
نماینده → 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 → عامل * نتایج انتخاب شده0x102004 "What is the flag? " 0x10201c "Incorrect!" 0x102027 "Correct!" Prompt referenced at: 0x10126d Containing function: 0x10124dمرجع به مامور جایی برای تحقیق می دهد ، حتی اگر نام های اصلی تابع اجرایی حذف شده باشند.
-
چک کننده و دو کمک کننده اش رو بخون
نماینده → REAanalyze_function {"procedure": "0x10124d"} analyze_function {"procedure": "0x101189"} analyze_function {"procedure": "0x101217"}REA → عامل * دستورالعمل های انتخاب شده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حلقه اول 36 کد کاراکتر را کپی می کند. حلقه چک کردن یک ماسک را رمزگشایی می کند ، کدهای انتخاب شده را جمع می کند و نتیجه را با یک عدد ذخیره شده مقایسه می کند. اون
0x18- گام های بایت در سراسر0x270بایت ها 26 ماسک می دهند.
این نتایج از تجزیه و تحلیل REA تازه انتخاب شده است. مسیر هدف محلی برای نمایش کوتاه می شود ؛ آدرس ها به تصویر وارد شده REA مراجعه می کنند.
یک چک یک شخصیت را نشان می دهد
چک کننده ورودی را در یک شبکه 6×6 مرتب می کند. ماسک انتخاب می کند که کدام سلول ها به جمع کمک می کنند. کدگذاری جمع و جور آن از اعداد منفی برای حذف سلول ها و اعداد مثبت برای انتخاب آنها استفاده می کند.
ماسک و هدف آن را از باینری بخوانید
{"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 بایت های ماسک را به عنوان مقادیر امضا شده می خواند. به همین دلیل است eb به معنی -21 هدف یک عدد صحیح اندکی است. با هم ، این بایت ها به عامل می گویند که code[21] = 55، پس اون شخصیت 7.
از دستورالعمل ها تا چک قابل خواندن
یک مرحله را برای اتصال کمک کننده جمع آوری و تماس گیرنده آن به همان قانون در C انتخاب کنید.
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 * از صفر شروع کنید. ECX مبلغ در حال اجرا را نگه می دارد.
02 * سلول ماسک را بررسی کنید. یک مقدار صفر کاراکتر را حذف می کند ؛ یک مقدار غیر صفر شامل آن است.
03 * یک کد کاراکتر اضافه کنید. عدد صحیح ورودی در همان جبران به مجموع اضافه می شود.
04 * به سلول بعدی بروید. حلقه اصلی چهار بایت در هر عدد صحیح را پیش می برد و شش ردیف از شش سلول را بازدید می کند.
05 * با هدف ذخیره شده مقایسه کنید. تماس گیرنده مبلغ را در EAX. عدم تطابق به Incorrect!.
دستورالعمل ها از طرف کمک کننده جمع آوری و تماس گیرنده اش می آید. C یک خلاصه توضیحی با نام های توصیفی و یک حلقه 36 سلولی مسطح است.
معادلات 26 را حل کنید
اکثر ماسک ها چندین سلول را انتخاب می کنند. به عنوان مثال ، اولین چک 16 کد کاراکتر اضافه می کند و در مجموع 1441 مورد نیاز دارد. انتخاب های همپوشانی معادلاتی را ارائه می دهند که یک اسکریپت کوچک پایتون می تواند با هم حل کند.
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 یک حل کننده است که مقادیر را برای برآورده کردن این معادلات پیدا می کند. این گزیده از چک های استخراج شده استفاده می کند و فرض می کند DUCTF{…} پرچم با حروف ، ارقام ، زیرنویس ها و بریس ها. دانلود کامل شامل تمام 26 ماسک و هدف است.
پاسخ را با برنامه اصلی بررسی کنید
ضبط فرآیند REA ، فایل اجرایی اصلی را که پرچم حل شده را قبول می کند ، ثبت می کند. تغییر یک کاراکتر انتخاب شده از z به y اولین مبلغ 1440 را به جای 1441 می سازد و برنامه آن را رد می کند.
| ورودی | خروجی مشاهده شده | کد خروج |
|---|---|---|
| پرچم حل کننده | Correct! |
0 |
| یک شخصیت تغییر کرد | Incorrect! |
255 |
نشان دادن پرچم بازیابی شده و خروجی گرفته شده
What is the flag? DUCTF{ezzzpzzz_07bcda7bfe81faf43caa}
Correct!
مقدار بازیابی شده همچنین با پرچم در متا داده های چالش منتشر شده سازمان دهندگان مطابقت دارد که پس از حل باینری بررسی شده است.
منبع ، هویت هدف و جزئیات تجزیه و تحلیل
تجزیه و تحلیل تازه و دو فرآیند ضبط در 8 اکتبر 2026 ، با استفاده از REA 4.1.0 با Ghidra 12.1.4 در Linux x64. باینری یک ELF x86-64 است که 15248 بایت است.
dcd3bec4f608e11f3a12ce461100aaf5f621851ee63a1f870d7c90d4e3dd51ae
مرجع های رشته ای ، توابع و ثابت ها قبل از خواندن منبع یا راه حل سازمان دهندگان بازرسی شدند. حل کننده پایتون و نمودار از نتایج REA ساخته شده است.
با منبع سازمان دهندگان مقایسه کنید · چالش متا داده ها و پرچم · یادداشت های شواهد REA
خودتان امتحان کنید
چالش اصلی و حل کننده را در یک پوشه دانلود کنید. از دستور بالا برای تحقیق با نماینده خود استفاده کنید یا اسکریپت همراه را اجرا کنید.
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
اسکریپت پرچم کاندیداها را چاپ می کند ؛ آن را در دستور برنامه چسبانید. حل نیازها پایتون و z3-solver. اجرای فایل اجرایی اصلی نیاز به Linux x86-64 دارد.