chouett0's note

掃きだめ的なsomething

Crackme Writeup

はじめに

Crackmeという名前の問題というのはやたらといろいろありますが、今回僕が挑戦したのは「Crackme doomo」という問題。

Crackme doomo : http://doomo.main.jp/crack/

全部で20問くらいあるらしいですが、その中でようやく10問目まで終わったのでその備忘録。
一応これから始める方のために一部を除いて最終的な答えは見えにくくしてあります。
また、今回解析に用いたツールはは主にOllydbgですが、たまにx32dbg使ったりPEiDとか使ったりしました。 あと一応パッキングも施されていたのでupxでアンパックを行いました。

問題を配布しているサイトのほうにちゃんとした解答があるので間違いだったり説明が足りない場合はそちらを参考にしてください。

0x1

まず、Ollyの場合はCtrl+Nでこのプログラムで使われている関数を列挙し、その中からMessageBox関数を見つけだして
ブレイクポイント(以下BP)を仕掛けると、以下のような処理があることがわかります。

f:id:chouett0:20170711110742p:plain

この処理は、おそらくlstrcmp関数がわかる人なら察しが付くと思いますが、まずGetWindowText関数をcallして
入力された文字列を取得し、比較用文字列と入力文字列をpushしてlstrcmp関数で比較し、その結果に応じてメッセージボックスを
表示しているようです。なので、この問題の答えは「doomo」となります。 おそらくPE解析入門者向けの問題だったのかなと思うくらいそのままの問題でした。

0x2

この問題でも0x1と同じように、まずはMessageBox関数にBreakPointを仕掛けると、以下のようになっています。
ちなみに、本家(?)様のWriteupにはGetWindowTest関数にBPを設定していますが、この関数が呼ばれている
プログラムしかないということはないので、MessageBox関数に仕掛ける方が確実に目的の関数に近づけると思ったからです。

f:id:chouett0:20170711112333p:plain

話を戻しまして、どうやら前回のようにそのまま答えがあるわけではないようです。 GetWindowText関数直下にEAXレジスタと「8」をcmpしている処理がありますが、
EAXレジスタにはGetWindowText関数で 取得した文字列の文字数が格納されているため、
8文字である必要があるようです。
004011FF番地のcall命令が怪しいのでステップインで潜ってみると、
次のような処理が行われていました。

f:id:chouett0:20170711134858p:plain

0040123A番地でmov命令によりESIレジスタにコピーされているのは今回ダミーとして入力した文字列(abcdefgh)です。
そしてESI、つまりは入力した文字列のなかから一文字ずつ取り出し、数値と比較しているのが見て取れます。
ここが文字列比較の処理であり、オンラインのASCII変換器に投げると、
5EH9V3QW という文字列が現れます。つまり、これが答えとなります。

0x2a

この問題は今までとは違い、BPを仕掛けたことを検知する機能があるため、
ただセットしただけでは f:id:chouett0:20170711150938p:plain

このように、BPがセットされていることを警告するメッセージを表示して強制終了してしまいます。
そこで、文字列を実際に比較するルーチンのある部分へBPを仕掛けました。 f:id:chouett0:20170720112059p:plain

ここなら検知されないようです。そして、文字列を一文字ずつDLというレジスタ(正確にはEDXレジスタの下位部分)と比較しているようですので、実際にFLAGを操作しながら
中身を調べていけば答えとなる文字列がわかります。
また、DLに格納される値は疑似乱数を使っているらしく内部処理を追ってみると、Data Segmentに値を保持してxorなどの命令を用いて数値を算出したものをASCIIに変換して使っているようです。(あくまで個人的な見解なので合っている確証はありません)

この続きは随時更新していきたいと思います

たぶん0x10まで更新するのに半年くらいかかると思います…