CLPWN見聞録

picoCTF2024 Reverse Engineering Writeups

編集中

picoCTF 2024 Reversing Writeups

WinAntiDbg0x100

WinAntiDbg系の問題はまとめて解説する

問題文

This challenge will introduce you to 'Anti-Debugging.' Malware developers don't like it when you attempt to debug their executable files because debugging these files reveals many of their secrets! That's why, they include a lot of code logic specifically designed to interfere with your debugging process. Now that you've understood the context, go ahead and debug this Windows executable! This challenge binary file is a Windows console application and you can start with running it using cmd on Windows.

アンチデバッグに関する問題らしい、題材がWindowsなのでPEファイルを解析する必要がある。

利用ツール

  • IDA
  • Ghidra
  • PPEE : PEファイルの表層解析をGUIでできる。動的にリンクされるライブラリなどの内容が見れる
  • WinDbgMicrosoftが提供するデバッガ

解説

PPEEでリンクされているライブラリを調べるとIsDebuggerPresentなる怪しい関数がリンクされているので、IDAでこの関数をCtrl+lで検索しデバッガを検出するルーチンを探し出す。

その周辺を調べると、フラグを出力するらしいブロックを発見できる。IsDebuggerPresentをコールした後test eax, eaxでeaxレジスタに0が入っているかどうか調べていることから、IsDebuggerPresentはデバッガを検出したときに1,そうでないときに0を返す関数だと推測できる。

デバッガ検出の方法が分かったので、ブレークポイントを仕掛けて返り値を上書きする。

ここで利用する『WinDbg』で利用するコマンド一覧を上げる。「Command」から?を入力することでヘルプを起動することもできる。(ファイルを起動するかプロセスにアタッチしないと使えないため注意)

  • g [addr]ブレークポイントに当たるまでプロセスを実行するコマンド。アドレスを指定してその場所まで実行させることもできる
  • bp addr :アドレスにブレークポイントを設定する
  • rレジスタの内容を表示する。レジスタの名前を指定して値を上書きすることもできる
  • lm:モジュール(ロードされているライブラリ等)の状態をみる

まず初めに適切な場所にブレークポイントを仕掛ける必要がある。IDA上でIsDebuggerPresentが呼び出される 0x4015fcにブレークポイントを仕掛けて実行しようとしても上手くいかないと思われる。
これはPEファイルのOptional HeaderにImageBaseと呼ばれるファイルがロードされると想定されるアドレスが記述されていて、IDAなどはそれをもとに命令コードのアドレスを決定するが、実際にプロセスを起動するときに、必ずしもそのアドレスにロードされるとは限らないからである。

Optinal HeaderのImageBase

つまり、ファイルを実行したときどのアドレスに読み込まれているかはその都度知る必要がある。lmコマンドを用いるとリンクされたライブラリ含め、どこに実行ファイルが読み込まれているか知ることができる。

ある命令コードのアドレスを求めるには、
(IDAでのアドレス) - ImageBase + (ロードされるアドレス)
以下、0x1000000に読み込まれたとする。

改めてIsDebuggerPresentをコールする場所(=0x10015fc)にブレークポイントを仕掛けると今度は上手くいく。Step Overで関数のコールを飛ばして、次のtest命令でeaxに0が入っているか確認するのでr eax=0でeaxに0を代入した状態で実行するとフラグを出力する

WinAntiDbg0x200

問題文

If you have solved WinAntiDbg0x100, you'll discover something new in this one. Debug the executable and find the flag! This challenge executable is a Windows console application, and you can start by running it using Command Prompt on Windows. This executable requires admin privileges. You might want to start Command Prompt or your debugger using the 'Run as administrator' option.

引き続きアンチデバッグに関する問題。管理者として実行しないと動作しない。

解説

WinAntiDbg0x100同様、IsDebuggerPresentが存在するのでバイナリ内でサーチするとデバッグ検出のルーチンを発見できる。すると今度はIsDebuggerPresentで検出する前にedxに0が入っているかどうかも調べているのでこの二つにブレークポイントを仕掛けてレジスタの内容を書き換える。

2ヶ所でレジスタの値を書き換えた後実行するとフラグが出力される。

WinAntiDbg0x300

問題文

This challenge is a little bit invasive. It will try to fight your debugger. With that in mind, debug the binary and get the flag! This challenge executable is a GUI application and it requires admin privileges. And remember, the flag might get corrupted if you mess up the process's state.

今度はGUIアプリケーションでデバッガをアタッチさせるのが目的らしい。

解説

いつものようにPPEEの表層解析を行うとSection Headersの中に「UPX」という文字列が見られるので、UPXでパッキングされていることが分かる。アンパックしたのち再びインポートされるライブラリ一覧を覗くと三度IsDebuggerPresentが現れるので同じ方法で検出ルーチンを探す。

おそらく、この方法では検出ルーチンを特定できなかったと思う。そこで手法を変え、デバッガをアタッチしようとしたときの挙動を調べてみる。
無理やりアタッチしようとすると「WinAntiDbg0x300」のウィンドウに勝利を告げるかの如くデバッガを検出した旨のテキストボックスが現れる。これを利用してやろう。

Our process detected the debugger and was able to fight it. Don't be surprised if the debugger crashed.

この文字列を検索すると。少し離れたところにフラグを出力するブロックを発見できる。

このフローの元をたどるとIDAのアドレスで0x4037c0で明らかに右に飛びそうにない条件分岐命令が見つかるのでJZ命令をJNZ命令にパッチして起動するとデバッガをアタッチする前にフラグが出る。