Puzzle:[HackThisSite! 攻略 Reverse編]

リバースエンジニアリングの問題。

Reverse.1 A Toe in the Water

バイナリエディタで調べると、メッセージとともに怪しい文字列が見つかる。

Right ! Wrong !
Ndg6kP BabyGeek

これらを手がかりに、OllyDbgで周囲を調べる。

Reverse.2 Spot the difference

OllyDbgに通すと、怪しい文字列と英数字一式が見つかる。

J#ki80Ys"
abcdefghijklmnopqrstuvwxyz
1234567890ABCDEFGHIJKLMNOP
QRSTUVWXYZ

上の2つの文字列から正解を作っているのだろう。

Reverse.3 Your first patch

可能性はいくつかある。WindowClass,Titleは正解を作るのに必要だろうから変えない。 また、最後に実行しなければならないcallでClass,Titleとも必要らしいから、 ClassとTitleの値は変更しないほうがいいだろう。ここで必要とされるEAXの値は その前のGetClassNameAで与えられている。つまり、Classの文字数にあたる。

あとは以上の条件で最後のcallを呼べばいい。

Reverse.4 Patience is a virtue

Nameがどのように変形されてSerialになるのか注意すれば解ける。

さらに、最後のメッセージから答えがひとつに定まる。

Reverse.5 Reverse Thinking Jr.

少しずるい方法をつかっても解けるかな。

96c4dda0c4a0b34262b1d91d47056f9e

正解のMD5値が分かっているので、MD5 Searchで調べてしまってもいい。

Reverse.6

ここまでの「まとめ」らしい。目的は登録すること。

外部参照の関数を調べると、DragQueryFileAが見つかる。ファイルをドラッグ&ドロップが重要なようだ。

しかし、下の(lstrcmpAに与えられる引数は、どんな名前、内容のファイルを渡しても変わらない。ファイル名に条件でもあるのだろうか?

DragQueryFileAのすぐ下にあるcallをたどると、ファイル名らしき文字列を作っている。さらに、比較している部分も見つかる。

EAX 00403264 ASCII "Z:\file/.geek"

Zドライブなんて持ってない。(´・ω・`)

C:\file/.geek

を作って、ZをCへ書き換えることにする。まぁ、ドライブレターを変えてしまってもよいけれどさ。あと、file/.geek の / を \ へ変更する。

'Z' => 'C'
00401209 MOV BL,BYTE PTR DS:[4032F4] => [4032DE]

'/' => '\\'
00401247 MOV BL,BYTE PTR DS:[4032C9] => [4032F6]

ファイルの内容でString1が変化するが、String2は変わらないらしいことが分かった。

/String2 = "e5da338b3cf14e0205e56dec92a5c347"

さらに、.geekファイルの初め5byteだけしかString1に反映されない。つまり、アルファベットと記号5文字でString2と同じになる組み合わせを探せばいい。

変換アルゴリズムを追いかけるのは激しくだるいので、2つの方法を試す。

方法1:ドラッグ&ドロップを繰り返すプログラムを作る。

ひたすらマウスを動かさせるのもうっとおしいしなぁ。とりあえず流れだけ。

対象ウィンドウが UNREGISTER であることを確認する
もしもREGISTERなら
  .geekファイルの中身を表示して終了
もしもUNREGISTERなら
  .geekファイルの中身を変更する
  .geekファイルをドラッグ&ドロップ
これを繰り返す

方法2:プログラムの余分なところに文字列更新用ループをつくる

問題の5byteが、どのアドレスにあるかは分かっている。

004012E9  BytesToRead = 21 (33.)
004012EB  Buffer = g6_mod2.00403271

また、比較に失敗したあとはファイル名や読み込んだ内容を0で埋めているだけだから、比較失敗のときだけ更新処理へ飛ばせば、REGISTERになったときの.geekの中身が手に入るはず。

手順は、プログラムの余分な場所(nopとかいっぱいあるとこ?)を探す。なければヘッダをいじる。つぎに比較失敗のjmp命令(jnz)のジャンプ先を書き換える。更新用コードを加えて、ReadFileよりもあとにjmpする。

ちなみに、[403271]はString1で更新されてしまうため、先に別の場所へ退避させておく必要がある。今回はステータスバーの表示に使われる[403040]へ移すことにする。表示も一緒にできるし。

比較が成功して、表示がREGISTERになればjmp命令に入らないので、アドレスに目的の5文字が入っている・・はず。

戻る

2007-07-15 公開 2007-09-06 更新 Copyright(C) 2007 tar0t All rights reserved.