読者です 読者をやめる 読者になる 読者になる

crackmeのリバースエンジニアリング2

リバースエンジニアリング

今日は次の課題に挑戦。
昨日のはgdbで動かすことができたけど今回のはアンチデバッガの処理が入ってるので昨日と同じ手法が使えない。

普通に動かすと・・・
bt Cyrex_LinuxCrackme2 # ./crackme
-[ Linux CrackMe (Level:3) by cyrex ]-
-[ TODO: Get the valid password     ]-
-[ Enter Password: aaaa
-[ Checking Stage 1 Now.....
-[ GameOver

gdbで動かすと・・・
bt Cyrex_LinuxCrackme2 # gdb -q ./crackme
gdb $ r
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Are you trying to Debug me?   <---- デバッガを検知している

Program exited with code 01.
-------------------------------------------------------------------------[ regs]
Error while running hook_stop:
No registers.
gdb $ q
bt Cyrex_LinuxCrackme2 # 

int3の割り込みをsignal()使って検知しているのかと思ったけどobjdumpの出力を見た感じ違う方法を取っているようだ。
ptraceが怪しい感じなのでNOPでptrace呼び出し箇所を埋めてみたけど上手くいかなかった。
どうしたもんかってことで、きっとパスワードは自動生成ではなく定数として埋め込まれていると思ったのでもう一度objdumpでバイナリの内容を出力する。

アセンブラコードは必要ないのでオプションは-sのみ。

bt Cyrex_LinuxCrackme2 # objdump -s crackme
 8048840 2d5b2054 4f444f3a 20476574 20746865  -[ TODO: Get the
 8048850 2076616c 69642070 61737377 6f726420   valid password
 8048860 20202020 5d2d0a00 2d5b2045 6e746572      ]-..-[ Enter
 8048870 20506173 73776f72 643a2000 2573002d   Password: .%s.-
 8048880 5b20456e 74657265 64205061 7373776f  [ Entered Passwo
 8048890 72643a20 25730a00 2d5b2043 6865636b  rd: %s..-[ Check
 80488a0 696e6720 53746167 65203120 4e6f772e  ing Stage 1 Now.
 80488b0 2e2e2e2e 0a003767 6235666a 66387634  ......7gb5fjf8v4
 80488c0 62673866 62333466 002d5b20 53746167  bg8fb34f.-[ Stag
 80488d0 65203120 436c6561 7265640a 002d5b20  e 1 Cleared..-[
 80488e0 47616d65 204f7665 720a002d 5b204368  Game Over..-[ Ch
 80488f0 65636b69 6e672053 74616765 2032204e  ecking Stage 2 N
 8048900 6f772e2e 2e2e0a00 72000000 00000000  ow......r.......
 8048910 00000000 00000000 00000000 00000000  ................
 8048920 2f746d70 2f637261 636b6d65 5f38396e  /tmp/crackme_89n
 8048930 666e6a66 69656668 65756665 75650000  fnjfiefheufeue..
 8048940 2d5b2042 61642064 69642079 6f752066  -[ Bad did you f
 8048950 6f72676f 7420736f 6d657468 696e673f  orgot something?

アドレス80488b0付近に怪しい文字列(7gb5fjf8v4bg8fb34f)がある。
strcmpを呼び出している付近のアセンブラコードを見ると$0x80488b6をstrcmpの引数に渡しているので
さっき見つけた文字列がほぼパスワードってことだろう。

 80485d1:	68 b6 88 04 08       	push   $0x80488b6    <--- ここ
 80485d6:	8d 85 00 fc ff ff    	lea    0xfffffc00(%ebp),%eax
 80485dc:	50                   	push   %eax
 80485dd:	e8 de fd ff ff       	call   80483c0 <strcmp@plt>

では、早速実行してみる。

bt Cyrex_LinuxCrackme2 # ./crackme
-[ Linux CrackMe (Level:3) by cyrex ]-
-[ TODO: Get the valid password     ]-
-[ Enter Password: 7gb5fjf8v4bg8fb34f
-[ Entered Password: 7gb5fjf8v4bg8fb34f
-[ Checking Stage 1 Now.....
-[ Stage 1 Cleared
-[ Checking Stage 2 Now....
-[ Bad did you forgot something?

パスワードは合ってたけど何かを忘れているって!?

もう一度objdumpの出力を良く見てみるとさらに怪しい文字列があることに気づく。

 8048920 2f746d70 2f637261 636b6d65 5f38396e  /tmp/crackme_89n
 8048930 666e6a66 69656668 65756665 75650000  fnjfiefheufeue..
 8048940 2d5b2042 61642064 69642079 6f752066  -[ Bad did you f
 8048950 6f72676f 7420736f 6d657468 696e673f  orgot something?

アセンブラコードの方ではfopen()を至る所で呼んでいる。

 80485e5:	89 c0                	mov    %eax,%eax
 80485e7:	85 c0                	test   %eax,%eax
 80485e9:	75 15                	jne    8048600 <fopen@plt+0x1d0>
 80485eb:	83 c4 f4             	add    $0xfffffff4,%esp
 80485ee:	68 c9 88 04 08       	push   $0x80488c9
 80485f3:	e8 18 fe ff ff       	call   8048410 <printf@plt>
 80485f8:	83 c4 10             	add    $0x10,%esp
 80485fb:	eb 17                	jmp    8048614 <fopen@plt+0x1e4>

/tmp/crackme_89nfnjfiefheufeueは間違いなくファイル名だし取り合えずtouchでこのファイルを作って実行してみる。

bt Cyrex_LinuxCrackme2 # ./crackme
-[ Linux CrackMe (Level:3) by cyrex ]-
-[ TODO: Get the valid password     ]-
-[ Enter Password: 7gb5fjf8v4bg8fb34f
-[ Entered Password: 7gb5fjf8v4bg8fb34f
-[ Checking Stage 1 Now.....
-[ Stage 1 Cleared
-[ Checking Stage 2 Now....
-[ You have successfully reversed/cracked/sniffed This Crackme
-[ Email me your solution to XXXX <- メールアドレス消した
bt Cyrex_LinuxCrackme2 # 

OK! crackmeのレベル1はクリアできた。
ほんとはアンチデバッガの処理を回避できる方が良いんだろうけど、まあ今回は良しとしておく。