CTF問題集問1 メモ
考え方と具体的分析操作(★は自分が慣れていない考え方):
どんなファイルなんだろう。file Selfreferenceで調べてみよう。
32bitで動作する実行ファイルだ。今私が利用しているのは64bitのubuntuだから32bitファイルを実行できるようにする準備をしなければ。sudo apt-get install gcc-multilib g++-multilibを実行しよう。
今度はファイルの中に含まれている文字にヒントはないかを調べよう。
strings Selfreferenceを実行。すると、このファイルに含まれる関数とその関数が認識する引数(オプション)が表示された。
★試しに関数を動作させよう。実行形式を与えて実行。
結果、使い方が出てきた。ご丁寧にhexとか書いてあるから16進数(hexadecimal)を使って暗号化されているということも分かった。
★解析ツール(radare2等)を利用して、暗号化を行う関数を特定する。なぜなら今回の問題では暗号化関数は実装されているが、復号化関数は実装されていないから。つまり、暗号化の実装から、復号化の実装を推測しなければ(関数を自作するときの参考にしないと)いけないから。←自分で関数作ってしまうという考え方。
参考:
radare2についてのブログ
使えれば良いやradare2(静的解析編) - 拾い物のコンパス
radare2公式本
radare2の今回の流れを整理。
関数の一覧表示→main関数の逆アセンブル結果表示→暗号化関数のアドレス特定→
radare2 ./Selfreferenceして
aa
afl(関数の一覧表示)。
pdf @ main(main関数の逆アセンブル結果表示。@の後ろに関数名指定)
ltrace ./Selfreference -encrypt abcd (共通ライブラリ関数をトレースfor暗号化関数特定)
→この段階で「文字列比較の後に関数実行」という流れが把握できるから、この文字列の位置がわかれば関数はその近くにあるやろーってことがなんとなく推測できる。つまり関数の位置をダイレクトに把握しにいかなくても、オプション文字列がどこにあるか、もしくは比較関数どこにあるのかを把握すれば(それらのアドレスを見つけられれば)関数の位置わかるやんという考え方ができる。
まずオプション文字列を参照するアドレス探してみる。別端末でrabin2を実行。尚、この操作を別端末じゃなくてtmuxで別ウィンドウをだしてやろうとしたんだけど、tmuxでは画面スクロールが億劫な感じだったので素直に別端末起動して実行するのがお勧め。tmuxでのスクロールのコツがあったらコメントください。
rabin2 -z ./Selfreference
rabin2で得られた情報を基にradare2のaxtコマンドをつかってそのアドレスを参照しているのはどのアドレスか(どの関数か)というのを把握。
axt アドレス
===================
→したいのですが、私の環境では実行不可でした。arというコマンドと衝突(conflict)が発生します。
my実行環境:
Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
radare2のバージョン:
0.9.6-3.1ubuntu1
===================
得られた情報を基にそのアドレスからさらに詳細情報を取得してみます。
s アドレス
pd
「レジスタに文字列入れてる処理」と「比較処理がどこにあるか」を特定すること。そうすればその後に実行されてる関数がずばり「暗号化処理」。暗号化処理候補が見つかったところで、それらを一つ一つ見ていく。
s 関数名(←関数名では飛べなかった。※追記:radare2最新版では飛べました)
===閑話休題===
→関数内の処理に飛ぶことができない。ここから先は、radare2のバージョンを最新にしてから再トライする。(※追記済)
sudo apt-get purge radare2
適当にmkdirしてcd
git clone radare2公式repoURL(結構長い時間がかかる)
sudo sys/install.sh(便利ですね)
===
表示された情報から関数の実行内容を読み取る。特に「利用関数のアドレス」と「関数及びオプションのアドレス遷移」を理解することに努める。そして、理解できたらC言語でそれを復元する。
もう一つの関数も調べる
s 関数名
処理内容を理解できたら、それをC言語で復元してみる。インラインアセンブラの練習が必要。
ここまで理解できたらあとは復号化関数を作成する。
その他この問題を通して理解したこと。
movzx:代入する値が代入先レジスタの格納領域より小さい場合にゼロ拡張して入れてくれる便利命令。
ゼロ拡張:値の同一性を保ったままにする処理。空いてる領域にゼロを入れる。
謎:
・radare2コマンドのうち、axtを利用しようとすると、下記メッセージが表示され利用できない。
XXX: This command conflicts with 'ar'
←radare2のアップデートで解決
・fopen関数のアドレスがなぜ教科書で示されたアドレスなのか理解できない。
・calloc関数はどこで実行されたのか
・なぜ”排他的論理和をとった”ということになるのか。要排他的論理和の理解。