はまやんはまやんはまやん

hamayanhamayan's blog

CTFのフォレンジックにおけるメモリフォレンジックまとめ [Volatility 3, Volatility 2]

親記事 → CTFにおけるフォレンジック入門とまとめ - はまやんはまやんはまやん

メモリフォレンジック

  • メモリダンプが与えられて解析をする問題
  • Volatility Foundation
    • メモリダンプ解析のスタンダード。これ以外で解析している記事を見たことが無い。(Redlineとか昔はあったぽいが)
    • Volatility2(無印)とVolatility3があるが、全くの別物。今から学習を始めるなら、絶対にVolatility 3から始めること
    • コマンド実行は結構時間かかるので、プロファイルの特定までは手動でやって、コマンド実行についてはよく使うコマンドを適当なシェルスクリプトで一括で持ってくるといい(その間にご飯)
    • Volatility使わなくてもバイナリ解析でやるようなことをやれば時間はかかるけど、使える情報が抜ける可能性は大いにある
      • 例えばFile Carvingを使ってファイルを抜き出したり、stringsでそこそこ有益な情報が得られたりもする

解く流れ

  1. メモリダンプがどのOSのものかを特定する
    • volatilityの解析機能ですぐに特定できるかも
    • できなければ、strings -n 10 mem.bin | grep "ubuntu"みたいに根性で種類とビルドバージョン(カーネルバージョン)を特定する
  2. シンボルテーブルがなければ作る(メモリのどこに何があるかをまとめたもの…だと思っているが)
    • なければ作るしかないが、想像よりも大変ではない
  3. 頑張って解析する
    • これは頑張る。メモリ解析は時間がかかるのでよく使うコマンドをシェルスクリプトにまとめて一括実行するのがおすすめ

Volatility 3(ちょっと情報薄い。ドキュメント見るといい)

  • https://qiita.com/ninja400/items/f3dd1e6eb80fd5b39ba9
  • windows
    • python3 /opt/volatility3/vol.py -f image.raw windows.info.Info WindowsInfoが読み取れる
      • NTBuildLab 7601.17514.amd64fre.win7sp1_rtm. -> win7sp1が入ってる
      • Is64Bit True -> 64bits
    • python3 /opt/volatility3/vol.py -f image.raw windows.pstree.PsTree プロセスツリーが見られる
      • cmd.exeが実行されているなら、コマンド系を深堀りしてみる
    • python3 /opt/volatility3/vol.py -f image.raw windows.netscan.NetScan ネットワークコネクションが見られる
      • 怪しいIPを見つけたらVirusTotalで確認
    • python vol.py -f image.raw windows.cmdline.CmdLine 現在実行中のプロセスがどのような引数で実行されたかが見られる
    • python vol.py -f image.raw windows.dumpfiles --pid="1676" メモリ上にあるpidが1676の関連ファイルをdumpしてくれる
    • python vol.py -f image.raw windows.mutantscan.MutantScan 使用されているミューテックスを出力する
      • 通常、悪意のあるプログラムの作成者は、そのプログラムが二重起動するを避けるためミューテックスを使用する
    • python3 /opt/volatility3/vol.py -f image.raw windows.filescan files scanning
    • python3 /opt/volatility3/vol.py -f image.raw windows.dumpfiles --pid="2760" Dump Files
    • python3 /opt/volatility3/vol.py -f physmemraw windows.hashdump.Hashdump hashdump
    • Volatility 3のWindows symbolic table
  • Linux

Volatility2

本当は載せるべきではないんだろうけど、こっちじゃないとたまーに動かなくて未だに動かす。
今から始める人は絶対にVolatility3から始めること。

  • 情報セキュリティ技術のスキルアップ・イベント 仙台CTF 2017
    • よい日本語資料
  • 解析前にprofileを特定、または、用意する必要がある
  • python2 /opt/volatility/vol.py -f memory.raw --profile=Win7SP1x64 [command]みたいにプロファイルをつけてコマンド実行する
    • windows
      • プロセスを確認してみよう
        • pslist -P 実行中のプロセスリストが得られる
        • pstree 実行中のプロセスツリーが得られる
        • cmdline 動いているコマンドを一覧表示できる
      • 怪しいプロセスのpidが得られたら…
        • dumpfiles --pid="[pid]" --dump-dir=./で関連ファイルを抜き出してみる
          • stringsしてから関連キーワードでgrepしてやれば何か出てくるかも
        • procdump -p [pid] -D output pidのプロセスのexeを出力する
        • memdump --pid=[pid] -D . 指定pidのメモリダンプ
      • cmdscan cmd.exeで使用したコマンドが見られる(パスワードとか抜けたりするかも)
        • consoles よくわかってないけど、cmdscan使っておけばいいと思う
      • envars 環境変数が見られる
      • filescan 現在開かれているファイル一覧が得られる
        • grepをうまく使うといい もろもろ filescan | grep hostsみたいに
        • dumpfiles -D . --name -Q [offset] offsetのファイルをdumpする
          • offsetはfilescanで得られたオフセットを入れる ex.0x000000004fa23f0
      • hashdump ユーザーアカウントのパスワードハッシュを取得する
      • clipboard クリップボードを取得する
      • notepad ノートパッドにある文字列を抜き出してくる
      • screenshot -D screens/ スクリーンショットを持ってくることができる?
      • 通信系
        • まずはこれ 👉 netscan ネット通信関連のアーティファクト収集
        • sockets 確立しているTCP/UDPのソケット一覧取得(だけど--profile=Win7SP1x86_23418でやってみたら動かなかった
        • connections 通信の一覧を取得(だけど--profile=Win7SP1x86_23418でやってみたら動かなかった
        • connscan 通信の一覧を取得(だけど--profile=Win7SP1x86_23418でやってみたら動かなかった
      • iehistory IEの履歴を取得する
      • yarascan -Y "[keyword]" yaraを使ってキーワードスキャンする
      • レジストリ
        • hivelist レジストリハイブ一覧を取得する
          • dumpregistry -o [offset] -D output hivelistからoffset(0xXXXXXX)を持ってきて、これで出力する。Registry Explorerで中身を見ればいい。
        • userassist レジストリのUserAssis情報を見て、起動履歴などを確認する
        • printkey -K "Software\Microsoft\Windows\CurrentVersion\UnreadMail\[email protected]" レジストリを直接参照したいとき
      • lsadump LSAメモリをダンプしてくる
    • linux Linux Command Reference · volatilityfoundation/volatility Wiki
      • linux_bash bashの実行履歴を確認する
      • linux_enumerate_files ファイル列挙ができる
        • ここでメモリアドレスも一緒に得られるのでlinux_find_file -i [address] -O [output filename]で取り出せる
      • linuxのバージョンを把握するとき grep -a "Linux version" mem.limeのように関連ワードで直接grep
        • Welcome to Ubuntu 20.04.1 LTS
          • TAMU CTF 2021だと、ISOダウンロードしてきてvolatilityツールでdwarfとmapを取得してきて使っている。
      • linux_lsof lsofコマンドと同等の結果が得られる
        • すべてのプロセスがオープンしているディスク上のファイル、名前付きパイプ、ネットワークソケット、デバイスが含まれる
        • オープンしているものとしては
          • /dev/pts/0 ファイルか名前付きパイプ(?)
          • socket:[xxx] ネットワークソケット xxxにある数字はなんだろう
          • anon_inode:[xxx] わからん
          • pipe:[xxx] pipe?
          • :[xxx] anonymous file createdらしい
      • pidからメモリマップを取得 linux_proc_maps -p [pid]
        • 0xffff911935415b00 9260 bash 0x00005574f0196000 0x00005574f02a2000 rw- 0x0 0 0 0 [heap]
        • 0xffff911935415b00 9260 bash 0x00007ffc9446d000 0x00007ffc9448e000 rw- 0x0 0 0 0 [stack]
          • こんな感じでheap領域やらstack領域やらも表示してくれるので持ってきてstringsとかすると面白いデータが転がってるかも
          • linux_dump_map -p [pid] -s 0x00007ffc9446d000 -D .のような感じでstack領域をダンプしてこれる
      • linux_volshell pythonコンソールを起動して、色々やる
        • cc(pid=[pid])でコンテキストを指定pidに移す(色々やる前にやる)
        • 使用されている(いた?)inodeを抜き出す
          • for filp, fd in self._proc.lsof():として print("{}: {} (INODE: {})".format(fd, filp, filp.f_inode))として更に改行
          • 0: 18446622369272764928 (INODE: 18446622369302465544)という感じで色々出てくる。先頭の0:部分はファイルディスクリプタでlsofした結果と紐づく
          • linux_find_file -i [inode] -O out.binとしてファイルをダンプしてくる
      • OpenSSHのカギを取得するためのプラグインがある