0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Day 5】Reversing の問題を解いてみる

Last updated at Posted at 2025-12-05

今日は Daily AlpacaHack の Day 4 である Reversing (rev) の問題を解きました!一応revは「コンパイルされたバイナリが与えられて、それを元に隠されたフラグを見つける」という問題であることは知っていましたが、実際にやってみるとめちゃくちゃ難しかったです。でも今まで (crypto, web) の中では一番好きな分野でした!

Screenshot 2025-12-05 at 12.23.30 AM.png

問題

与えられているもの

  • challenge というコンパイルされたバイナリファイル
  • challenge.c というC言語のソースコード (半年ぶりくらいにC言語触った...)

最初はソースコードを読んでフラグがどのような形式で保存されているかを考えていたのですが、ヒントをみたら「実際のrevではソースコードは与えられず、この問題も実はバイナリファイルだけから解ける」と書いてあったので、AIにその都度便利なバイナリ解析コマンドを教えてもらいながらソースコード話でフラグを探すことにしました!

聞かれていること

バイナリのどこかに含まれている、Alpaca{flag} という形式の文字列を探すこと。Alpacaというラッパーが分かっているのは大きくて、これを元に文字列検索のようなことをしていくらしいです。

解く

自分はバイナリ解析用のコマンドをまだ何も知らないので、取り組み方としては、「こういうことがしたいな」と思ったらその都度それを達成できるコマンドがあるかをAIに聞くという方法でした。

まず、基本となるよく使うコマンドの一覧を教えてもらいました:

コマンド名 説明 得られる情報 使用例 出力例
file ファイルの基本情報を確認 形式・アーキテクチャなど file challenge challenge: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked
strings バイナリ内の文字列を抽出 「文字列みたいなもの」のリスト strings challenge Enter flag:, Wrong length, ...
xxd バイナリを16進数で表示 16進数の値・対応するASCII文字 xxd challenge 00001160: 488d 3da9 2e00 0048 8d35 a22e 0000 4829 H.=....H.5....H)
grep データから入力のパターンを探す 見つかったパターンのバイトオフセット `grep -i "Fkwfdf" challenge 4614:Fkwfdf

次にメインの解いた流れですが、こんな感じです

1. (これは少しズルでソースコードから得た知識ですが) バイナリ内ではフラグが「xorエンコーディング」されていることが分かりました。これはどういうことかというと、フラグの文字列一つ一つのcharに対して、$^ 7 = ^ 000001111$ のようなxor演算を適用しているということです

フラグは絶対にAlpaca{...}で囲まれているため、"Alpaca" ^ 7 = "Fkwfdf" という文字列を探せば良いのだと分かりました

これは、Pythonの「ワンライナー」というのを用いて、コマンドラインで直接以下を実行して求めました。

python3 -c "print(''.join(chr(ord(c) ^ 7) for c in 'Alpaca'))"

2. 次に、この文字列を strings コマンドを使ってバイナリファイルの中から探します

strings ./challenge | grep "Fkwfdf"

出力は以下でした

Fkwfdf|kH

実際にこの文字列 ("Alpaca") が存在することが分かったので、フラグはこの辺りにありそうです!

3. grep を用いてこの文字列の出現するバイトオフセットを調べます

grep -aob "Fkwfdf" challenge

出力は

4614:Fkwfdf

ということで、4614バイト目くらいからこの文字列が始まることが分かりました。

4. ここで、dd という「どこからどれくらいの長さ」を指定しつつファイル内のデータを抜き出せる(コピーする)コマンドをAIに教えてもらったので、これを用いて4614バイト目から100バイト分のバイナリデータを取得し、これに xxd を適用することで周辺のASCII文字を取得しました

dd if=challenge bs=1 skip=4614 count=100 2>/dev/null | xxd

結果、ここら辺には Fkwfdf|kH.E.H.|krdl~z.H.E.H.E. というような文字列があることが分かりました。(H.E.H. みたいな部分は機械語というらしく、何らかの理由で紛れ込んでいて答えには関係ないらしいですが深くは分かりません)

5. 最後に、この文字列に再度 Python で 「^ 7」の xor 演算を適用し、元のフラグの文字列に戻してあげます (xorは2回適用すると元の値に戻るという性質がある)

python3 -c "print(''.join(chr(ord(c) ^ 7) for c in 'Fkwfdf|kH.E.H.|krdl~z.H.E.H.E.'))"

出力は

Alpaca{lO)B)O){lucky})O)B)O)B)

でした。変な文字 (機械語?) が紛れ込んでいて最初は混乱したのですが、もう疲れていたのでとりあえず答えっぽい lucky を提出してみたらあっていたので、とりあえず解けたということにします。

まとめ

今日はここまでです。revの問題は初めてでしたが、結構ハマりそうな予感がします。特に、中身の見えないバイナリファイルを、いろいろなコマンドの出力結果を観察しながら解剖していく感じが楽しいです (大学受験でやった化学の構造決定と似た雰囲気を感じます)
明日の Daily AlpacaHack は難易度 Hard らしいので、できる限り頑張ってみたいと思います!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?