チェックコードを見つける
配布資料は15KBの実行可能ファイルです。 それはフラグを要求し、次に印刷します 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この参照は、実行可能ファイルの元の関数名が削除されていても、エージェントに調査する場所を提供します。
-
チェッカーとその2つのヘルパーを読む
エージェント→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*次のセルに移動します。 元のループは整数ごとに4バイト進み、6つのセルの6行を訪問します。
05*保存されたターゲットと比較します。 呼び出し元は、合計を受信します EAX. ミスマッチがジャンプします Incorrect!.
命令は、加算ヘルパーとその呼び出し元から来ています。 Cは、説明的な名前と平坦化された36セルループを持つ説明的な要約です。
26の方程式を解く
ほとんどのマスクは複数のセルを選択します。 たとえば、最初のチェックでは16個の文字コードが追加され、合計1441個が必要です。 重複する選択は、小さなPythonスクリプトが一緒に解くことができる方程式を与えます。
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は、これらの方程式を満たす値を見つけるソルバーです。 この抜粋は、抽出されたチェックを使用し、aを前提としています DUCTF{…} 文字、数字、アンダースコアと中括弧を持つフラグ。 完全なダウンロードには、26個のマスクとターゲットすべてが含まれています。
元のプログラムで答えを確認してください
REAのプロセスキャプチャは、解決されたフラグを受け入れる元の実行可能ファイルを記録します。 から選択した文字を変更する z に y 最初の合計を1441ではなく1440にし、プログラムはそれを拒否します。
| 入力 | 観測された出力 | 終了コード |
|---|---|---|
| ソルバーの旗 | Correct! |
0 |
| 一つの文字が変更されました | Incorrect! |
255 |
回収されたフラグとキャプチャされた出力を表示する
What is the flag? DUCTF{ezzzpzzz_07bcda7bfe81faf43caa}
Correct!
回復された値は、バイナリを解決した後にチェックされた、主催者の公開されたチャレンジメタデータのフラグとも一致します。
ソース、ターゲットの識別情報および分析の詳細
2026年10月8日に、REA4.1.0とGhidra12.1.4をLinux x64で使用して、新鮮な分析と2つのプロセスキャプチャを行いました。 バイナリは削除されたx86-64ELF、15,248バイトです。
dcd3bec4f608e11f3a12ce461100aaf5f621851ee63a1f870d7c90d4e3dd51ae
文字列参照、関数、定数は、主催者のソースまたはソリューションを読み取る前に検査されました。 Pythonソルバーとダイアグラムは、これらのREA結果から構築されました。
自分で試してみてください
元のチャレンジとソルバーを1つのフォルダにダウンロードします。 上記のプロンプトを使用してエージェントに調査するか、含まれているスクリプトを実行します。
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
スクリプトは候補フラグを出力します。プログラムのプロンプトに貼り付けます。 ニーズを解決するPythonと z3-solver. 元の実行可能ファイルを実行するには、Linux x86-64が必要です。