【AlpacaHack】WriteUp for flag-obfuscation

問題概要

配布された obfuscator.c(難読化ツール)と data.h(難読化済みデータ)からフラグを取り出すことが目標です。

flag obfuscation - AlpacaHack
The flag checker has been obfuscated!

前提知識

IPv6アドレスとは?

IPv6は 2001:db8::1 のようなコロン区切りの16進数で表現されるネットワークアドレスです。 実体は 128ビット(= 16バイト) の数値です。

つまり「16バイトのデータ」は何でもIPv6アドレスとして表現できます。 この問題では、この性質を使ってバイナリデータを隠しています。


配布ファイルの確認

ファイル内容
obfuscator.cバイナリをIPv6アドレスに変換するCのソースコード
data.h変換済みのIPv6アドレス一覧(2464個)

data.h の中身はこのような形式です:

char *ipv6_data[] = {
"4d5a:9000:300:0:400:0:ffff:0",
"b800::4000:0:0:0",
"::",
...
};
int ipv6_count = 2464;

難読化の仕組みを読み解く

obfuscator.c のポイントとなる処理は以下の部分です:

for (int i = 0; i < size; i += 16)
{
    unsigned char chunk[16] = {0};   // 16バイトのバッファを用意
    memcpy(chunk, buf + i, ...);     // ファイルから16バイト読み込む
    inet_ntop(AF_INET6, chunk, ipv6, sizeof(ipv6));  // IPv6文字列に変換
    printf("\"%s\",\n", ipv6);       // 出力
}

流れ:

  1. 元のバイナリファイルを 16バイトずつ 切り出す
  2. inet_ntop(AF_NET6, ...) 関数で IPv6アドレス文字列に変換 する
  3. C言語の配列として出力する


解法

Step 1:逆変換スクリプトを作る

難読化の逆、つまり「IPv6アドレス → 16バイト」に変換すれば元のバイナリが復元できます。

Pythonの ipaddress モジュールを使うと簡単に実現できます。

import ipaddress
import re

# data.h を読み込む
with open("data.h", "r") as f:
    content = f.read()

# " " で囲まれたIPv6アドレスをすべて抽出
addresses = re.findall(r'"([^"]+)"', content)

buf = bytearray()
for addr in addresses:
    # IPv6アドレス → 16バイトに変換して結合
    buf += ipaddress.IPv6Address(addr).packed

# 元のバイナリとして保存
with open("output.bin", "wb") as f:
    f.write(buf)

実行すると output.bin が生成されます


Step 2:復元したバイナリを調べる

復元したファイルの先頭2バイトを確認すると

$ file output.bin 
output.bin: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

Windowsの実行ファイルということがわかります

まずフラグっぽい文字列を検索します:

$ strings output.bin | grep -i alpaca -A 10

断片的に以下のような文字列が見つかります:

Alpaca{iH
D$ H
pv6_obfuH
scation_H
T$(H
can_evadH
D$0H
e_signatH
T$8H
D$Hure}

フラグのフォーマット Alpaca{...} であることが確認できます。ただし文字列がバラバラに見えるため、バイナリをより詳しく解析する必要があります。


Step 3:バイナリ内でのフラグ構築方法を特定する

Decompiler Explorerででコンパイルしてみます

BinaryNinjaでAlpacaと検索するとフラグが出現しました。 https://dogbolt.org/

コメント

タイトルとURLをコピーしました