Snoozy

1.Sleep-inducing; tedious.

Volatilityを使ってみる

Volatilityを使ってみる

メモリフォレンジックフレームワークであるVolatilityを使ってみる.

Volatilityは現在Python3で記述されたものや,Windows上でスタンドアロンで動作するexe形式のものが配布されているが,この記事執筆時点ではプロファイルやコマンドの対応状況の点で,Python2製が最も充実しているようにみえる.

そのため,ここではPython2製のVolatilityを使用する.

github.com

Volatility使用にあたって不明点があれば,まず公式Wikiを確認することを推奨する.

github.com

Volatilityのインストール

GitHubからVolatilityをクローンする.

git clone https://github.com/volatilityfoundation/volatility.git

外部パッケージのインストール

Volatilityの使用前に,必要な外部パッケージをインストールしておく.

プロファイルの特定やプロセスリストの取得など使用頻度の高いコマンドがDistorm3を必要とするため,事前にpipでインストールしておく.

pip2 install distorm3

yarascanコマンドやlsadumpコマンドなどはまた別のパッケージを使用するため,必要に応じてインストールすること.

[2020/10/19 追記]

久しぶりにVolatilityをUbuntuにcloneして使おうとしたら,以下のようなインポートエラーが出てうまく動作しなかった.

f:id:snoozekvn:20201019162816p:plain

これを解消するためのメモを残しておく.

最初にPython2系のpipを取ってくる.

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
export PATH="$PATH:/home/<UserName>/.local/bin"

続いてリポジトリからVolatilityをcloneし,setup.pyを実行する.

git clone https://github.com/volatilityfoundation/volatility.git
cd volatility
python setup.py build install

その後,pycryptoとdistorm3をインストールする.

sudo apt install gcc python2.7-dev
pip install pycrypto
pip install distorm3==3.4.4

以上.

[2020/10/19 追記ここまで]

Volatility Quick Start

メモリダンプを解析し始める前に,インストールしたVolatilityのプロファイルやコマンドの対応状況を確認しておくとよいだろう.

f:id:snoozekvn:20200417080851j:plain

また,コマンドの一覧や詳細はWikiのCommand Referenceが助けになるだろう.

github.com

Volatilityを使ってみる

Volatilityのコマンドの基本的な使い方は以下である.

python vol.py [plugin] -f [image] --profile=[profile] 

コマンド名,メモリダンプファイルのパス,プロファイルが必要になるが,このうちプロファイルを求めておく必要がある. ダンプファイルのプロファイルを求めるには以下のようにすればよい.

python vol.py -f [image] imageinfo

ただし,imageinfoコマンドは結果を得るまでにかなり時間がかかるため,事前にダンプファイルがどのOSのものでバージョンはいくつなのか把握しておいたほうがよいだろう.

以下は,適切なプロファイルを設定してプロセスリストを取得するpslistコマンドを試した様子.

f:id:snoozekvn:20200417080823j:plain

ProcessHollowingの検出

もう少し実践的な使用方法をやってみる.

以前の記事で作成したProcessHollowingを行うプログラムを使って,Volatilityによる不正な活動の検出をやってみる.

snoozy.hatenablog.com

ProcessHollowingを行うプログラムの動作概要は以下のようなものだった.

  • ProcessHollowing.exeプロセスが,不正なコードの注入先となる子プロセスを作成
  • 作成された子プロセスの外装は電卓プロセスだが,ProcessHollowingにより実際に動作するコードは ProcessHollowing.exeプロセスが注入したもの
  • ProcessHollowing.exeプロセスは電卓プロセスに対して,メッセージボックスをポップアップする不正なコードを注入する
  • 処理が正常に完了すると,不正なコードを模したメッセージボックスがポップアップする

以下は実際に,ProcessHollowingプロセスが電卓プロセスをHollowingし,不正なメッセージボックスが立ち上がっている様子.この状態でFTK Imagerを起動しメモリダンプを取る.

f:id:snoozekvn:20200417080831j:plain

ProcessHollowingをVolatilityを使って検出する方法は大きく以下の3パターンが知られている.

  • 不審な親子関係の検出
  • PEBとVAD構造の比較による検出
  • 不審なメモリ保護領域の検出

以下それぞれやってみる.

まずプロセスリストからgrepでProcessHollowing.exeプロセスを見つける.

f:id:snoozekvn:20200417080827j:plain

この親子関係からProcessHollowing.exeプロセスがconhost.exe, cmd.exe, calc.exeプロセスのいずれか,または全てを不正な活動に利用している可能性がある.

不審な親子関係の発見は,SANSが公開しているポスターが参考になるだろう.

https://www.sans.org/security-resources/posters/dfir-find-evil/35/download

今回は,calc.exeプロセスがhollowing対象だと分かっており,恣意的ではあるが以降calc.exeプロセスを対象に話を進める.

calc.exeプロセスに対して,PEBとVADの差異からProcessHollowingの検出を試みる.

Volatilityのdlllistコマンドは,プロセスのPEBから,そのプロセスにロードされているモジュールのリストを読み取る.このモジュールにはDLLやそのプロセス自身のEXEも含まれる.

f:id:snoozekvn:20200417080835j:plain

一方,ldrmodulesはカーネルのVADから,そのプロセスにロードされているモジュールのリストを出力する.

f:id:snoozekvn:20200417080823j:plain

ProcessHollowingが行われた場合,この結果に差異がある. 今回の例でいえばcalc.exeのイメージパスがldrmodulesでは表示されなくなる. これはProcessHollowingの内部で使用されるNtUnmapViewOfSectionAPIによるものだ.

VADは,メモリマネージャが,あるプロセスのどの仮想アドレスが予約されどの仮想アドレスが予約されていないか追跡するために使用されるツリー構造のデータ構造体だ.

プロセスがアドレス領域を予約したり予約領域を削除した場合,メモリマネージャはVADのツリー構造を都度更新する.対してPEBのモジュールリストの更新はそれに対して比較的遅い.

ProcessHollowingの内部で使用されるNtUnmapViewOfSectionAPIにより,VADが更新されるためこのような結果になる.

たしかに,dlllistで表示されていた電卓のイメージパスが表示されておらず,ProcessHollowingの痕跡が見つかったといえる.

次に不審なメモリ領域の検出を試みる. malfindコマンドはVADやページ保護を検査し,不正に注入されたDLLやEXEを検出する.

f:id:snoozekvn:20200417080814j:plain

実行ファイルの通常の実行において,DOSヘッダはPAGE_READONLYなメモリ属性を持つ.

malfindコマンドから得られた領域はPAGE_EXECUTE_READWRITEになっており,これは不審とみなしてよい.

hollowfindプラグインによる自動化

これら一連の処理を自動化してくれる便利なプラグインが公開されているため使ってみる.

github.com

公開されているリポジトリからクローンして,volatilityのpluginsディレクトリにコピーすればよい.

~/volatility$ git clone https://github.com/monnappa22/HollowFind.git
~/volatility$ cp HollowFind/hollowfind.py volatility/volatility/plugins/

以下は実際に使用してみた様子.

f:id:snoozekvn:20200417080844j:plain

確かに検知できているようだ.

不審なプロセスや注入されたコードが,どういった処理をするのかはVolatilityからは分からない. 以降はプロセスをダンプしてIDAなどで解析する段階になる.

プロセスをダンプするにはprocdumpコマンドを使えばよい.

f:id:snoozekvn:20200417080840j:plain

これをIDAに読み込ませると以下のように注入されたコードを見ることができる.

f:id:snoozekvn:20200417080847j:plain

コマンド実行の自動化

Volatilityのコマンドはものによってはかなり時間を取られるものがある.

またgrepなどで不審な部分を探していくことになるのだが,そのたびに手動でコマンドを実行していては手間である.

そこで一度すべてのコマンドを実行してファイルとして保存しておき,これをgrepなどでみていくのが得策だ.

以下はそれをやってくれるシェルスクリプト

# Full Credits to: Gabriel Pirjolescu
# https://medium.com/@gabriel.pirjolescu/demystifying-windows-malware-hunting-part-2-detecting-execution-with-volatility-1a139b194bfc

#!/usr/bin/env bash
profile="Win10x64_18362"
file="memdump.mem"
cmds=(
    #processes
    "pslist"
    "psscan"
    "pstree"
    "pstotal"
    "psxview"
#DLLs and handles
    "dlllist"
    "getsids"
    "handles"
    "filescan"
    "mutantscan"
    "cmdscan"
    "consoles"
    "scvscan"
    "cmdline"
#network
    "connections"
    "connscan"
    "sockets"
    "sockscan"
    "netscan"
)
echo "[+] File: $file"
echo "[+] Profile: $profile"
for i in "${cmds[@]}"; do
    echo "[+] Command: $i"
        vol.py --profile=$profile --output-file=$i -f $file $i
done

以上.

参考

http://dione.lib.unipi.gr/xmlui/bitstream/handle/unipi/11578/Balaoura_MTE1623.pdf?sequence=1&isAllowed=y

https://digital-forensics.sans.org/media/volatility-memory-forensics-cheat-sheet.pdf

cysinfo.com

volatilityfoundation.github.io