Unleash the Beast!

CTFなどのメモに使います

【備忘録】Windows上にangr環境を構築してみる

色々と事情があり、最近angrをいじる機会が多いです。

UbuntuとKali上にangrの解析環境を組んでるのですが、CTFの際はメインでWindowsを使うため、Windows上でもangrを使える方が色々と取り回しが楽だな、と考えていました。

ということでTry!!

angrの公式ドキュメントのIntallingの項を参考に進めてみます。

docs.angr.io

1. python3系のインストール

CTFの解析メインで使っているWindows10のVMにはpythonは入っているんですが、python2系です。

angrは現在python3系が必須となっています。

(1年ちょっと前まではpyton2系が必須だった気がするんですが)

そこで、python3系をインストールすることにします。最新版は3.7.4。

Python3のインストール - python.jp

Python Release Python 3.7.4 | Python.org

Windows x86-64 executable installerをダウンロードします。

インストーラをキックするとインストールが始まります。

f:id:imurasheen:20190719021931p:plain

コマンドプロンプトPowershellのウィンドウで"python"を実行した際にpython3が起動するようにしたいので、環境変数PATHにパスを加えるべく"Add Python 3.7 to PATH"にチェックを入れる必要があります。
それ以外は設定変更せずインストール。特に問題なくインストールが終わります。

これでpython3系が起動するぜ、と思ったんですが、残念ながらまだpython2.7が起動してしまいます。どうやら環境変数PATHにpython2系への参照が残っている模様。

環境変数エディタを起動し、環境変数Pathから"python27"を含むパスを削除し、python2系への参照を消してしまいます。

f:id:imurasheen:20190719022356p:plain

python2系を残したい場合は違う手順が必要になってくるかと思いますが、主にpythonのコーディングを行うのはLinux上になると思いますので一思いに消しました。

なお、環境変数には[ユーザー環境変数]と[システム環境変数]が存在しますが、両方チェックすることをお勧めします。私の環境では[システム環境変数]にpython2系のパスが、[ユーザー環境変数]にpython3系のパスが入った状態になっていました。

"python"コマンドでpython3.7.4が起動してくることが確認できます。

f:id:imurasheen:20190719022747p:plain

2. python仮想環境(virtualenv-win)のインストール

上記に挙げた、angr公式ドキュメントのInstallingの項のうち、「Windows」の項目を参照します。

angrをインストールする際は、python仮想環境を利用することを強く推奨されています。これは、angrが参照しているz3などの依存モジュールについて、公式ビルドではなくangrの独自ビルドを利用しているものがあるためです。

例えばangrの環境とz3の環境を共存させたい場合、z3のオリジナルバイナリをpipで取得してしまうとangrが動かなくなるかもしれません。

そのため、angrと依存モジュールを全てpython仮想環境内に構築する必要があります。

コマンドプロンプト上で、

> pip install virtualenvwrapper-win

と実行するだけでインストールに成功します。

3. angrのインストール

python仮想環境の作成⇒作成した仮想環境上にangrをインストール の手順です。

2つのコマンドを利用します。

> mkvirtualenv angr

angrという名前のpython仮想環境を作成します。

成功すると、作成した仮想環境(angr)に入った状態となります。

> pip install angr

angr本体および依存モジュールをインストールします。

インストールの様子

f:id:imurasheen:20190719024039p:plain

こちらも拍子抜けするほどすんなり入ります。

4. 動作検証

インストールはうまくいきましたが、ちゃんと動くかどうか確認するまで安心できません。ここでは2つのサンプルで動作を確認しました。

なお、作成したpython仮想環境内(angr)に入るには、コマンドプロンプト上で

> workon angr

と実行するだけです。

4.1 Windows DLLの解析

angr-doc/more-examples.md at master · angr/angr-doc · GitHub

実際のCTFで出題された問題のバイナリと、そのsolverのスクリプトが置いてあります。

こちらから、Windowsのバイナリで動きそうなものを探します。

⇒ReverseMe example: MMA CTF 2015 - HowToUse を採用します。

 下記を参照すると、DLL内の特定の関数(fnhowtouse@@YAHH@Z)を呼べば勝ちのようです。qiita.com

 置いてあったバイナリとスクリプトを実行すると、以下のように解析に成功します。

f:id:imurasheen:20190719030057p:plain

・・・中略・・・

f:id:imurasheen:20190719030120p:plain

 

4.2 ELF形式ファイルの解析

昨年のSECCON for Beginners 2018で出題されたcrackmeを解析して見ます。

競技時間中に解けず、競技終了後にangrで解いた問題です。

正しい引数を与えると実行が成功する問題でした、確か。(引数がフラグ)

旧solver

import angr
import claripy

key_length = 32

project=angr.Project('crackme',load_options={'auto_load_libs':False})
cfg = project.analyses.CFG(fail_fast=True)
argv = [project.filename] 
arg1 = claripy.BVS('arg1', key_length*8)
argv.append(arg1) #commandline arg

initial_state = project.factory.entry_state(args=argv)
pg=project.factory.simgr(initial_state)

print("explore start")
a=pg.explore(find=0x4009A2,avoid=(0x400951,0x4009BD,0x40081D,0x40086D,0x4008BD,0x40090D,0x40064D,0x40069D,0x400707,0x400757,))
print("explore end")

found = a.found

if ( len( found ) > 0 ):    #   Make sure we found a path before giving the solution
    found = pg.found[0]
    result = found.state.se.any_str(argv[1])
    try:
        result = result[:result.index('')]
    except ValueError:
        pass
else:   # Aww somehow we didn't find a path.  Time to work on that check() function!
    result = "Couldn't find any paths which satisfied our conditions."

print(result)

この時点ではangrはpython2系オンリーだったのと、当時からangrの構文がだいぶ変わってしまったので、上記solverでは解析時に例外が発生していしまいます。改めてsolverを組んでみます。

 新solver

import angr
import claripy

key_length = 32

project=angr.Project('crackme',load_options={'auto_load_libs':False})
#cfg = project.analyses.CFG(fail_fast=True)
argv = [project.filename] 
arg1 = claripy.BVS('arg1', key_length*8)
argv.append(arg1) #commandline arg

entry = project.factory.entry_state(args=argv)
simgr = project.factory.simgr(entry)

print("explore start")
#simgr.explore()
result=simgr.explore(find=0x4009A2,avoid=(0x400951,0x4009BD,0x40081D,0x40086D,0x4008BD,0x40090D,0x40064D,0x40069D,0x400707,0x400757,))
print("explore end")

found = simgr.found[0]

flag = found.solver.eval(arg1,cast_to=bytes).decode("utf-8", "ignore")
print(flag)

大枠は変わっていないんですが、だいぶ記述が変わっていますね。

(もう大幅な変更はやめてほしい)

上記solverを流すと、解析に成功します。

f:id:imurasheen:20190719031729p:plain

・・・中略・・・

f:id:imurasheen:20190719031755p:plain

 

まとめ

ということで、Windows上にangr環境を構築&バイナリ解析に成功しました。

Linux環境上にangrをインストールした際はいろいろ苦労したことがあったのですが、拍子抜けするほどあっさりインストールに成功しました。

angrも過渡期を抜けてこなれてきたということでしょうかね。

 

今回2パターンのバイナリを解析しましたが、その目的としては

Windows上でもLinuxのバイナリ(ELF形式ファイル)も解析できるんだよね??」

という点の裏付けが目的でしたので、目的が達成できて満足です。

もう少しangrへの理解を深めて、自動解析(Zeratoolのような)に踏み込んでいきたい所存です。

github.com

【追記】

この記事を参照して試してもらった同僚等からいただいた情報です。

① 使用するpython仮想環境について

 angr documentationのInstallingの項目には

 >You can use either the virtualenv-win or virtualenv packages for this.

 と記載されており、virtualenv-winかvirtualenvの使用が推奨されています。

 なので今回の記事ではvirtualenv-winを使った手法を試していたのですが、

 venv(python3.3以降に標準で組み込まれたpython仮想化パッケージ)でも同じ手順でインストールに成功したそうです。

 

② 関連パッケージのインストールに失敗する

 以下のような流れで苦労しつつなんとかangrで解析成功するところまでたどり着いた方が。

 pip install angrでインストール中に、unicornのインストールの箇所で固まる

 ⇒unicornをDLして無理やりインストール

 ⇒angrのインストールを継続し、完了

 ⇒angrで解析処理を試みると、z3を参照している箇所でエラー発生

  AttributeError: module 'z3' has no attribute 'lib'

 

 angr Documentationのinstalling->Troubleshootingの項目を見ると以下のような項目があります。 

https://docs.angr.io/introductory-errata/install#libgomp-so-1-version-gomp_-4-0-not-found-or-other-z3-issues

 z3絡みで問題が起きたら、z3をリコンパイルしてみろとのこと。

 コマンドは以下。

 >pip install -I --no-binary z3-solver z3-solver

  しかし以下のエラーが出て失敗したそうです。

******************************************

Makefile was successfully generated.
compilation mode: Release
platform: x64

To build Z3, open a [Visual Studio x64 Command Prompt], then
type 'cd G:\temp\pip-install-jn_u1qbw\z3-solver\core\build && nmake'

Remark: to open a Visual Studio Command Prompt, go to: "Start > All Programs > Visual Studio > Visual Studio Tools"
Building Z3
error: [WinError 2] 指定されたファイルが見つかりません。 

******************************************

 最終的には、Gitからz3を取得してビルドしたら動いたとのこと。

 何かしらの競合かもしれませんが、原因は不明です。