メモリフォレンジックCTF「MemLabs」Lab3にVolatility3で挑戦してみた

この記事は[NTTテクノクロス Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ntt-tx)の15日目の記事です。

NTTテクノクロス セキュアシステム事業部 兼 情報セキュリティ推進部 TX-CSIRT 兼 クロステックセンター の大塚です。

所属部署が多いですが、普段は「セキュリティ業務のPoC」「インシデントハンドリング」「Elastic Stackの社内技術支援」等を行っています。

2021年2月にVolatility3が正式にリリースされましたが、日本語記事が少なかったので、なにかの助けになればと思い本記事を執筆しました。

https://github.com/volatilityfoundation/volatility3/releases/tag/v1.0.0

Volatility3の利用には以下のチートシートがVolatility2との対比がありわかりやすく書いてあり参考になります。

https://blog.onfvp.com/post/volatility-cheatsheet/

Volatility2と比べると、 プロファイルの指定が不要になっていたり、Progressが表示されたりと、便利になった印象を受けました。

## メモリフォレンジックとは？

メモリフォレンジックとは、メモリイメージを解析し、不審なプロセス、通信先を探すことで、攻撃者(マルウェア)の痕跡を見つけることを指します。

なお、メモリフォレンジックの上位概念であるデジタル・フォレンジックはデジタル・フォレンジック研究会によって以下の通り定義されておりますので、気になる方はご参照ください。

>インシデントレスポンス*や法的紛争・訴訟に際し、電磁的記録の証拠保全及び調査・分析を行うとともに、電磁的記録の改ざん・毀損等についての分析・情報収集等を行う一連の科学的調査手法・技術を言います。
>*インシデントレスポンス＝コンピュータやネットワーク等の資源及び環境の不正使用、サービス妨害行為、データの破壊、意図しない情報の開示等、並びにそれらへ至るための行為（事象）等への対応等を言う。

https://digitalforensic.jp/home/what-df/

## MemLabsとは？

[@stuxnet999](https://github.com/stuxnet999)が作成した、CTF形式でメモリフォレンジックが学ぶことができる教材で、Github上に公開されています。

https://github.com/stuxnet999/MemLabs

## 環境構築

メモリフォレンジックの環境として `Remnux` を使用しました。

https://remnux.org/

`Remnux` はマルウェア解析に特化した Linuxのディストリビューションであり、メモリフォレンジックに使用する `Volatility3` も標準でインストールされています。

環境構築も簡単にできるようになっており、今回は下記からVirtual Applianceをダウンロードして構築しました。

https://docs.remnux.org/install-distro/get-virtual-appliance

起動直後は`v2021.15.2`と、少し古かったので更新をしました。

```
$ remunx upgrade
$ remnux version
> remnux-cli@1.3.3.0.g1df38b1
> remnux-version: v2021.45.1
```

## Writeup: Lab3

Lab3は以下で公開されています。

https://github.com/stuxnet999/MemLabs/tree/master/Lab%203

### 問題

A malicious script encrypted a very secret piece of information I had on my system. Can you recover the information for me please?

Note-1: This challenge is composed of only 1 flag. The flag split into 2 parts.

Note-2: You'll need the first half of the flag to get the second.

You will need this additional tool to solve the challenge,

```
$ sudo apt install steghide
```

The flag format for this lab is: inctf{s0me_l33t_Str1ng}

> 悪意のあるスクリプトにより、私のシステムにある非常に重要な情報が暗号化されてしまいました。その情報を復元してもらえますか?
> 
> Note-1: この課題は、1つのフラグで構成されています。フラグは2つの部分に分かれています。
> 
> Note-2: 2つ目のフラグを手に入れるには、1つ目のフラグが必要になります。
> 
> この課題を解くには、以下の追加ツールが必要になります。
> 
> ```
> $ sudo apt install steghide
> ```
> 
> この研究室でのフラグのフォーマットは次の通りです。inctf{s0me_l33t_Str1ng}

### 攻略のサマリ

- フラグの前半は悪意のあるスクリプトによってファイルが暗号化されてしまっているが、悪意のあるスクリプトも一緒に配置されているため、スクリプトと暗号化されたファイルを復元し、その内容を解読することで復元できる。
- フラグの後半はステガノグラフィーによって隠されている。不審な画像ファイルを復元し、フラグの前半を用いることで、不審な画像ファイルからフラグの後半を復元することできる。

### 攻略(Writeup/Walkthrough)

フラグが2つに別れているため、前半と後半に分けて解説していきます。

#### フラグの前半

まずはダンプメモリの情報を確認します。

```console
$ vol3 -f MemoryDump_Lab3.raw windows.info
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                                                                                              
Variable	Value

Kernel Base	0x82617000
DTB	0x185000
Symbols	file:///usr/local/lib/python3.8/dist-packages/volatility3/framework/symbols/windows/ntkrpamp.pdb/FC47DB45E361459A984AC2204FEB535E-2.json.xz
Is64Bit	False
IsPAE	True
layer_name	0 WindowsIntelPAE
memory_layer	1 FileLayer
KdDebuggerDataBlock	0x82742c68
NTBuildLab	7601.19135.x86fre.win7sp1_gdr.16
CSDVersion	1
KdVersionBlock	0x82742c40
Major/Minor	15.7601
MachineType	332
KeNumberProcessors	1
SystemTime	2018-09-30 09:47:54
NtSystemRoot	C:\Windows
NtProductType	NtProductWinNt
NtMajorVersion	6
NtMinorVersion	1
PE MajorOperatingSystemVersion	6
PE MinorOperatingSystemVersion	1
PE Machine	332
PE TimeDateStamp	Fri Jan 22 05:04:20 2016
```

`NTBuildLab`に出力されていますが、今回は`Windows7SP1`が対象です。

悪意のあるスクリプトが動作中の可能性もあるため、起動プロセスを確認します。

```
$ vol3 -f MemoryDump_Lab3.raw windows.pstree
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                        
PID	PPID	ImageFileName	Offset(V)	Threads	Handles	SessionId	Wow64	CreateTime	ExitTime

4	0	System	0x83d09c60	88	541	N/A	False	2018-09-30 08:09:59.000000 	N/A
* 260	4	smss.exe	0x84551b98	2	29	N/A	False	2018-09-30 08:09:59.000000 	N/A
340	332	csrss.exe	0x84d58030	9	352	0	False	2018-09-30 08:10:04.000000 	N/A
380	372	csrss.exe	0x84d76030	10	189	1	False	2018-09-30 08:10:05.000000 	N/A
* 3176	380	conhost.exe	0x84e37498	2	51	1	False	2018-09-30 09:45:43.000000 	N/A
388	332	wininit.exe	0x84d77d28	3	83	0	False	2018-09-30 08:10:05.000000 	N/A
* 876	388	LogonUI.exe	0x85192030	5	152	0	False	2018-09-30 08:10:40.000000 	N/A
* 500	388	lsm.exe	0x84dd4b28	10	151	0	False	2018-09-30 08:10:08.000000 	N/A
* 484	388	services.exe	0x84dcdbd0	6	195	0	False	2018-09-30 08:10:07.000000 	N/A
** 800	484	svchost.exe	0x84e5ad28	18	438	0	False	2018-09-30 08:10:14.000000 	N/A
*** 5996	800	audiodg.exe	0x84489800	4	120	0	False	2018-09-30 09:45:22.000000 	N/A
** 1184	484	SearchIndexer.	0x84d69d00	15	724	0	False	2018-09-30 08:12:33.000000 	N/A
*** 4036	1184	SearchFilterHo	0x84ef6768	5	97	0	False	2018-09-30 09:47:36.000000 	N/A
*** 5748	1184	SearchProtocol	0x83fbba40	7	281	0	False	2018-09-30 09:45:32.000000 	N/A
** 292	484	sppsvc.exe	0x8515cae0	6	153	0	False	2018-09-30 08:12:31.000000 	N/A
** 440	484	svchost.exe	0x8514bbf0	13	342	0	False	2018-09-30 08:12:32.000000 	N/A
** 648	484	VBoxService.ex	0x84e15d28	12	115	0	False	2018-09-30 08:10:13.000000 	N/A
** 712	484	svchost.exe	0x84e1d030	8	268	0	False	2018-09-30 08:10:14.000000 	N/A
** 904	484	svchost.exe	0x84e6fa18	31	1116	0	False	2018-09-30 08:10:15.000000 	N/A
*** 5644	904	wuauclt.exe	0x84d77868	3	86	1	False	2018-09-30 09:28:49.000000 	N/A
** 588	484	svchost.exe	0x8454e348	10	351	0	False	2018-09-30 08:10:12.000000 	N/A
*** 1008	588	dllhost.exe	0x84700ab8	8	225	1	False	2018-09-30 09:45:48.000000 	N/A
** 1516	484	svchost.exe	0x84893030	12	215	0	False	2018-09-30 08:10:26.000000 	N/A
** 880	484	svchost.exe	0x84e6b030	18	452	0	False	2018-09-30 08:10:15.000000 	N/A
** 1488	484	svchost.exe	0x8488e860	11	267	0	False	2018-09-30 08:10:26.000000 	N/A
** 4816	484	taskhost.exe	0x8441d7e0	8	196	1	False	2018-09-30 09:28:32.000000 	N/A
** 852	484	svchost.exe	0x84e67d28	16	371	0	False	2018-09-30 08:10:15.000000 	N/A
*** 3028	852	dwm.exe	0xa0b21170	3	186	1	False	2018-09-30 09:28:36.000000 	N/A
** 1236	484	svchost.exe	0x8481bcb0	15	478	0	False	2018-09-30 08:10:22.000000 	N/A
** 4724	484	TrustedInstall	0xbc21b9f0	4	139	0	False	2018-09-30 09:40:24.000000 	N/A
** 1368	484	svchost.exe	0x8485b030	18	302	0	False	2018-09-30 08:10:24.000000 	N/A
** 1016	484	msiexec.exe	0x9c627d28	7	345	0	False	2018-09-30 09:39:03.000000 	N/A
*** 5652	1016	msiexec.exe	0xbc2d08a8	0	-	1	False	2018-09-30 09:39:13.000000 	2018-09-30 09:41:17.000000 
** 1340	484	spoolsv.exe	0x8484a800	12	285	0	False	2018-09-30 08:10:24.000000 	N/A
* 492	388	lsass.exe	0x84dd0658	6	561	0	False	2018-09-30 08:10:08.000000 	N/A
424	372	winlogon.exe	0x84da6d28	3	115	1	False	2018-09-30 08:10:05.000000 	N/A
5300	5128	explorer.exe	0x8449d890	30	871	1	False	2018-09-30 09:28:36.000000 	N/A
* 3064	5300	VBoxTray.exe	0x851cdd28	14	154	1	False	2018-09-30 09:28:44.000000 	N/A
* 3432	5300	notepad.exe	0x8443d3c0	1	60	1	False	2018-09-30 09:47:50.000000 	N/A
* 4116	5300	DumpIt.exe	0x84ead628	2	37	1	False	2018-09-30 09:45:43.000000 	N/A
* 3736	5300	notepad.exe	0x9c6b0970	1	60	1	False	2018-09-30 09:47:49.000000 	N/A
```

特に不審なプロセスはなさそうですが、`notepad.exe`を2つユーザが起動しているようです。

`pstree`で見れる情報はファイル名だけなので、TEMPディレクトリ等に配置され同名ファイルで起動されている場合など気づけないため、`cmdline`も実行して確認をします。

```console
$ vol3 -f MemoryDump_Lab3.raw windows.cmdline
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                        
PID	Process	Args

4	System	Required memory at 0x10 is not valid (process exited?)
260	smss.exe	\SystemRoot\System32\smss.exe
340	csrss.exe	%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
380	csrss.exe	%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
388	wininit.exe	wininit.exe
424	winlogon.exe	winlogon.exe
484	services.exe	C:\Windows\system32\services.exe
492	lsass.exe	C:\Windows\system32\lsass.exe
500	lsm.exe	C:\Windows\system32\lsm.exe
588	svchost.exe	C:\Windows\system32\svchost.exe -k DcomLaunch
648	VBoxService.ex	C:\Windows\System32\VBoxService.exe
712	svchost.exe	C:\Windows\system32\svchost.exe -k RPCSS
800	svchost.exe	C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted
852	svchost.exe	C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
880	svchost.exe	C:\Windows\system32\svchost.exe -k LocalService
904	svchost.exe	C:\Windows\system32\svchost.exe -k netsvcs
1236	svchost.exe	C:\Windows\system32\svchost.exe -k NetworkService
1340	spoolsv.exe	C:\Windows\System32\spoolsv.exe
1368	svchost.exe	C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
1488	svchost.exe	C:\Windows\System32\svchost.exe -k utcsvc
1516	svchost.exe	C:\Windows\system32\svchost.exe -k LocalServiceAndNoImpersonation
876	LogonUI.exe	"LogonUI.exe" /flags:0x1
292	sppsvc.exe	C:\Windows\system32\sppsvc.exe
440	svchost.exe	C:\Windows\System32\svchost.exe -k secsvcs
1184	SearchIndexer.	C:\Windows\system32\SearchIndexer.exe /Embedding
4816	taskhost.exe	"taskhost.exe"
3028	dwm.exe	"C:\Windows\system32\Dwm.exe"
5300	explorer.exe	C:\Windows\Explorer.EXE
3064	VBoxTray.exe	"C:\Windows\System32\VBoxTray.exe" 
5644	wuauclt.exe	"C:\Windows\system32\wuauclt.exe"
1016	msiexec.exe	C:\Windows\system32\msiexec.exe /V
5652	msiexec.exe	Required memory at 0x7ffda010 is not valid (process exited?)
4724	TrustedInstall	C:\Windows\servicing\TrustedInstaller.exe
5996	audiodg.exe	C:\Windows\system32\AUDIODG.EXE 0x830
5748	SearchProtocol	"C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe7_ Global\UsGthrCtrlFltPipeMssGthrPipe7 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon" 
4116	DumpIt.exe	"C:\Users\hello\Desktop\DumpIt\DumpIt.exe" 
3176	conhost.exe	\??\C:\Windows\system32\conhost.exe "-578845771-1540166818332419906-659764396-174055078882731463-1164958248-211768531
1008	dllhost.exe	C:\Windows\system32\DllHost.exe /Processid:{76D0CB12-7604-4048-B83C-1005C7DDC503}
4036	SearchFilterHo	"C:\Windows\system32\SearchFilterHost.exe" 0 512 516 524 65536 520 
3736	notepad.exe	"C:\Windows\system32\NOTEPAD.EXE" C:\Users\hello\Desktop\evilscript.py
3432	notepad.exe	"C:\Windows\system32\NOTEPAD.EXE" C:\Users\hello\Desktop\vip.txt
```

さきほど起動していることを確認した`notepad.exe`ですが、`evilscript.py`と`vip.txt`という2つのファイルを開いているようです。ファイル名からして不審なので、抽出して中身を確認していきます。

```console
$ vol3 -f MemoryDump_Lab3.raw windows.filescan | grep evilscript.py
0x3de1b5f0 100.0\Users\hello\Desktop\evilscript.py.py	128
0x3e727490	\Users\hello\AppData\Roaming\Microsoft\Windows\Recent\evilscript.py.lnk	128

$ vol3 -f MemoryDump_Lab3.raw windows.filescan | grep vip.txt
0x3e727e50 100.0\Users\hello\Desktop\vip.txt	128

$ vol3 -f MemoryDump_Lab3.raw -o output windows.dumpfiles --physaddr 0x3de1b5f0
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                        
Cache	FileObject	FileName	Result

DataSectionObject	0x3de1b5f0	evilscript.py.py	file.0x3de1b5f0.0xbc2b6af0.DataSectionObject.evilscript.py.py.dat

$ vol3 -f MemoryDump_Lab3.raw -o output windows.dumpfiles --physaddr 0x3e727e50
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                        
Cache	FileObject	FileName	Result

DataSectionObject	0x3e727e50	vip.txt	file.0x3e727e50.0x83e52420.DataSectionObject.vip.txt.dat
```

抽出したファイルを確認します。

```console
$ ls -l ./output/
total 8
-rw------- 1 remnux remnux 4096 Nov 30 02:58 file.0x3de1b5f0.0xbc2b6af0.DataSectionObject.evilscript.py.py.dat
-rw------- 1 remnux remnux 4096 Nov 30 02:59 file.0x3e727e50.0x83e52420.DataSectionObject.vip.txt.dat

$ cat output/file.0x3de1b5f0.0xbc2b6af0.DataSectionObject.evilscript.py.py.dat 
import sys
import string

def xor(s):

	a = ''.join(chr(ord(i)^3) for i in s)
	return a


def encoder(x):
	
	return x.encode("base64")


if __name__ == "__main__":

	f = open("C:\\Users\\hello\\Desktop\\vip.txt", "w")

	arr = sys.argv[1]

	arr = encoder(xor(arr))

	f.write(arr)

	f.close()

$ cat output/file.0x3e727e50.0x83e52420.DataSectionObject.vip.txt.dat 
am1gd2V4M20wXGs3b2U=
```

入力文字をXOR演算したあとに、Base64エンコードして、`vip.txt`に出力したようです。

つまり、逆の手順で実施すると入力文字が得られそうなので、CyberChefで解読したところフラグの前半が取得できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325671/53d5912b-cecc-227e-bd04-7ef489348b5f.png)

#### フラグの後半

[steghide](http://steghide.sourceforge.net/)が必要だと問題文に記載されているため、ステガノグラフィーによって隠されている可能性が高いことがわかります。

steghideは以下の形式をサポートしているため、どこかに怪しいファイルが格納されてないか、調査をしていきます。

> support for JPEG, BMP, WAV and AU files

まずは`JPEG`から確認をしていきます。

```console
$ vol3 -f MemoryDump_Lab3.raw windows.filescan | grep jpeg
0x4f34148  100.0\Users\hello\Desktop\suspision1.jpeg	128
```

さっそく、怪しいファイルが見つかりました。

このファイルを抽出します。

```console
$ vol3 -f MemoryDump_Lab3.raw -o output windows.dumpfiles --physaddr 0x4f34148
Volatility 3 Framework 2.0.0
Progress:  100.00		PDB scanning finished                        
Cache	FileObject	FileName	Result

DataSectionObject	0x4f34148	suspision1.jpeg	file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat

$ file output/file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat 
output/file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 256x197, components 3
```

抽出されたファイルを確認しましたが、JEPGファイルでしたので、ステガノグラフィーによってフラグが隠されている可能性がグっと高くなりました。

`steghide`を使用するためインストールをします。

```console
$ sudo apt install steghide
$ steghide --version
steghide version 0.5.1
```

情報が埋め込まれているかどうかを確認していきます。

```console
$ steghide info ./output/file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat 
"file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat":
  format: jpeg
  capacity: 581.0 Byte
Try to get information about embedded data ? (y/n) y
Enter passphrase: <-- (パスフレーズはフラグの前半)
  embedded file "secret text":
    size: 16.0 Byte
    encrypted: rijndael-128, cbc
    compressed: yes
```

"secret text"というファイルがあることが確認できました。このまま抽出をしていきます。

```console
$ steghide extract -sf ./output/file.0x4f34148.0x843fcf38.DataSectionObject.suspision1.jpeg.dat 
Enter passphrase: <-- (パスフレーズはフラグの前半)
wrote extracted data to "secret text".
```

抽出ができたので、確認をすると以下の通りフラグの後半が取得できました。

```console
$ cat secret\ text 
_1s_n0t_3n0ugh}
```

### フラグ

```
inctf{0n3_h4lf_1s_n0t_3n0ugh}
```

## さいごに

Volatility3いいですよね。プラグイン名が大きく変わっていたり影響は大きいですが、プロファイルが不要だったり早くなったり(体感ですが)といいことばかりです。

明日は、@sa-da による NTTテクノクロス Advent Calendar 2021 の16日目をお届けしますので引き続きよろしくお願いいたします！