2014年7月6日日曜日

pwnium ctf 2014 reverse 150(Kernel Land) writeup

Pwnium CTF2014に参戦しました。

Pwn100な問題をやろうと思ってたんですが、Downしてました。
PwnがDown・・・

なんかもうアレだったので、やる問題を変更してreverse 150な問題やりました。


この問題を解くには多分相当なチャレンジ精神か
カーネルランド(特にカーネルの初期化部分)を普段から見ている事が必要だなと思いました。
結構特殊な問題でした。

(x86のハードウェアガシガシ叩いてるので、
CPUやチップセットの仕様とその設定がわからないとかなり時間がかかる問題かなと。)

んでは、バイナリを見てみます。


俺の作ってるカーネルより小さい!!!(狂喜)
----

まぁ、IDA Freeで開きます。
カーネルのmain関数ですね。
色々初期化処理しています。


[gdt_init関数]
GDT(Global Descriptor Table(メモリセグメント定義テーブル))を3つ設定しているだけですね。
設定しているセグメントは以下のとおり。
NULLセレクタ
コードセグメント(0~4Gバイト)
データセグメント(0~4Gバイト)
平たく言えば、x86でコードやデータを置くメモリ領域の設定です。
NULLセレクタはCPUがどこのセグメントも指さない時に使うもので、CPUには必要なものです。
(このカーネルで使っているのはコードセグメントとデータセグメントだけです。)
initのコード


[idt_init関数]
IDT(Interrupt Descriptor Table(割り込みベクタ)を幾つか設定しているらしいです。
割と大事な処理っぽいですが、まぁぶっちゃけ見ても分かりそうにないので飛ばします。
必要なら後で見ることにします。(※今回の解析では不要でした。)

[irq_init関数]
PIC(Programmable Interrupt Controller(割り込み制御装置))の初期化をしています。
8259A互換チップ(マスターとスレーブ)の初期化です。
さらに割り込みされた時に走らせる関数と8259Aのピンの対応付けをIDTに登録している感じです。



[timer_init関数]
この中ではタイマー割り込みされた時に実行したい関数(割り込みハンドラ)を登録してます。



この後はカーネルが何もしない無限ループ(hung)に落ちてるので

メインの処理はこれで終わりです。


問題文は 3回目のtick とか何とか書いてあったので
きっとflagはtimerに有って
timer割り込みが3回来た時のバッファの内容がflagになるんだろうなぁと。
というわけで timer_tick関数 を見て行きましょう。



flagっぽいものが有りました。(Itofrjxb2`..c.2.6031]g6b1gg0^)b11cb^^-])

この文字列が、何かにxorされて、tickが3回の時に本物の「flag」になるらしいです。


特に難しい処理やAPIが絡んでるわけでもないので
Windows上でもこの答えを出すプログラムができそうです。

タイマー割り込みが来た時 と言うのはループに置き換えられそうなので
Windows上ではタイマー割り込みをループで置き換えます。
そんな感じで作ったプログラムがこれ。


実行すると・・・

 flag: Pwnium{e5c11b1519328df9e8ff3a0e88beaa4d}

150点げっと。