ابحث عن رمز التحقق
النشرة هي ملف 15 كيلو بايت قابل للتنفيذ. يسأل عن العلم ، ثم يطبع Correct! أو Incorrect!. ابدأ بطلب بسيط إلى وكيلك.
استخدام REA لتحليل مس-فلاغ-تشيكر والعثور على العلم. اشرح كيفية عمل الشيكات ، ثم تحقق من الإجابة باستخدام البرنامج الأصلي.
مثال موجه ، مع التحدي الذي تم تنزيله متاح محليا وتحليل موفر برامج رمز الجهاز المتصل.
-
اتبع موجه الإدخال إلى وظيفته
وكيل → 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 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.
من التعليمات إلى فحص قابل للقراءة
حدد خطوة لتوصيل مساعد التلخيص ووظيفة الاتصال الخاصة به بنفس القاعدة في ج.
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!.
تأتي التعليمات من مساعد التلخيص ووظيفة الاتصال الخاصة به. ال ج هو ملخص توضيحي بأسماء وصفية وحلقة مسطحة من 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))
ض3 هو حلالا يجد قيما تفي بهذه المعادلات. يستخدم هذا المقتطف الشيكات المستخرجة ويفترض أ 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 64. ثنائي هو جردت س 86-64 قزم ، 15 ، 248 بايت.
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 س86-64.