4ensiX

4ensiX

FPと言ったものはFPを選んだが表示はTPになっていることに気づいた。

Strange PCAP - HackTM CTF 2020 Forensic writeup

前回記事に引き続け!

zarat.hatenablog.com

Strange PCAP

問題文

We managed to get all the data to incriminate our CEO for selling company secrets. Can you please help us and give us the secret data that he has leaked?

Author: Legacy

与えられたファイルを開く

「Strange.pcapng」はパケットキャプチャファイルであるのでWiresharkで見ていく。

f:id:Zarat:20200301213455p:plain
とりあえずWiresharkで開いてみた
これはUSBのパケットキャプチャであることが分かる。

接続されたデバイスを確認

wiresharkを使って例えば「usb.bcdDevice」とフィルタをかけると「GET DESCRIPTOR Response DEVICE」のパケットのみ表示されて、それぞれのパケットの「DEVICE DESCRIPTOR」を見ると接続されたUSBデバイスに関する情報がある。今回は5つのUSBデバイスがあるようだ。

f:id:Zarat:20200301213837p:plain
usb.bcdDeviceでフィルタ
接続要求時のsrcは1.1.0 1.2.0 1.3.0 1.15.0 1.16.0、使用しているときのデータ転送では、アドレスが1.15.1であったり、1.16.2であったりと微妙にアドレスが異っているのはよく分からない。 取りあえず、「1.15.0と1.15.1とかは同じ 」という気持ちでやっていく。

Flash Driveの通信を調査

USBデバイスを確認したときに、usb.device_addressが16の「1.16.0」はusb.idProductが「Flash Drive」となっていた。

f:id:Zarat:20200301214347p:plain
Flash Drive
フラッシュドライブなら何かデータ転送してそうなので、「usb.device_address == 16」とフィルタを設定して調べる。
f:id:Zarat:20200301214649p:plain
usb.device_addresの指定
パッと見づらいのでデータ転送してそうな「Data In LUN」してる「usb.src == "1.16.2"」のフィルタをかける(適当)。
f:id:Zarat:20200301214909p:plain
1.16.2からの通信を見る
とりあえず、Lenが多い順にずらっと見ていくと読める文字があったりするがよく分からない。ここで順に見ていくと、No.1224のパケットが気になった。
f:id:Zarat:20200301215152p:plain
No.1224のパケット
「PK」ってあるし、「Flag.txt」とあるのでzipファイルの転送ぽい気がする。このパケットの「SCSI Payload」をエクスポートしてみる。ここでは、「data.zip」としてエクスポートしてみた。

$ file data.zip
data.zip: Zip archive data, at least v2.0 to extract
$ unzip data.zip
Archive:  data.zip
[data.zip] Flag.txt password:
   skipping: Flag.txt                incorrect password

zipファイルであることは確認できたが、暗号化されているようだ。暗号化されているということはパスワードもどこかにありそうな気がする。ということで探す。

zipのパスワードを捜索

なんとなく、暗号化zipをUSBから取り出したなら次はキーボードからパスワードを入力するのではという推測からNo.1224以降のパケットを中心に見ていく。
USBデバイスからの通信であり、「URB_INTERRUPT in」のメッセージ確認できるパケットに注目すると「usrb.src == "1.15.1"」の通信の多くがパスワード入力ぽい気がする。
ここで、入力データは「Leftover Capture Data」というセクションに保存されており、「usb.capdata」とフィルタすることで取り出すことができる。tsharkで以下のように指定することで欲しい情報を取り出した。

$ tshark -r Strange.pcapng -Y 'usb.src == "1.15.1" && usb.capdata && usb.data_len == 8' -T fields -e usb.capdata > keycapdata.txt

ここからキーボード入力の文字に変換するスクリプト作成のために色々と資料を探した。
資料

CTF Series : Forensics — tech.bitvijays.com
USB Hid Keyboard Scan Codes

GitHub - TeamRocketIst/ctf-usb-keyboard-parser: This is the updated script from https://teamrocketist.github.io/2017/08/29/Forensics-Hackit-2017-USB-ducker/

しかし、他のWriteupを見ているととても良いスクリプトを見つけたのでこれの紹介と共に利用する。
お手本USBパーサー

Strange PCAP – b00t – A cybersecurity blog

ここで利用されているもの使ってパスワードを取り出す。

$ python usbkeyread.py
7vgj4SSL9NHVuK0D6d3F[ENTER]

ここで良いスクリプトと言ったのは、判別できるキーボードが多いからである。Enterの入力まで綺麗に確認できた。これがパスワードだと仮定して入力する。

$ unzip data.zip
Archive:  data.zip
[data.zip] Flag.txt password:
  inflating: Flag.txt             
$ ls
Flag.txt  Strange.pcapng  data.zip  keycapdata.txt  usbkeyread.py
$ cat Flag.txt
HackTM{88f1005c6b308c2713993af1218d8ad2ffaf3eb927a3f73dad3654dc1d00d4ae}

見事flagゲット。
flag: HackTM{88f1005c6b308c2713993af1218d8ad2ffaf3eb927a3f73dad3654dc1d00d4ae}
やろうと思えばデータの転送からパスワードを入力まで筒抜けなわけですね。

その他参考資料

hanya-orz.hatenablog.com

RR - HackTM CTF 2020 Forensic writeup

今頃感でも、土, 01 2月 2020, 17:00 JST — 月, 03 2月 2020, 16:59 JSTに行われたHackTM CTF 2020のForensicのwriteupを記しておく。

ctftime.org

RR

One of my drives failed and I need help recovering all my files. As far as I know the persons who have set up my PC used something like Reusing All of Internal Disks.

Author: Legacy

直リンが良いか分からないがファイルが残っているようなのでリンクを貼っておく。

https://mega.nz/#!1MEQRCpD!YfSQZQSmKn520Jh8DCBb2Xh0ndqF_kPjgZsQIYtvH8A
https://drive.google.com/open?id=1hPBksCtm3a4wGs9cd8DYkM4mcV0aNCEJ

リンク先には「Images.zip」というファイルがあり、これを解凍すると3つの.imgファイルが現れる。これらのファイルを見てみる。

$ ls -al
-rw-r--r-- 1 root root 536870912  1月 31 22:56 1.img
-rw-r--r-- 1 root root         0  1月 31 23:30 2.img
-rw-r--r-- 1 root root 536870912  1月 31 22:56 3.img

$ file *.img
1.img:    DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system", disk signature 0xd7f49e5c; partition 1 : ID=0x83, start-CHS (0x0,32,33), end-CHS (0x41,69,4), startsector 2048, 1046528 sectors
2.img:    empty
3.img:    DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system", disk signature 0xd7f49e5a; partition 1 : ID=0x83, start-CHS (0x0,32,33), end-CHS (0x41,69,4), startsector 2048, 1046528 sectors

3つのイメージがあり、このうち「2.img」のみ空となっている。ここでなんとなく、これはRAIDに関するものではないかと推測した。
次に、パーティション情報を確認して実体を取り出し、これをfileコマンドで見る。

# mmls 1.img
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0001048575   0001046528   Linux (0x83)

# dd if=1.img of=Linux.img skip=2048
1046528+0 レコード入力
1046528+0 レコード出力
535822336 bytes (536 MB, 511 MiB) copied, 7.62211 s, 70.3 MB/s

# file Linux.img
Linux.img: Linux Software RAID version 1.2 (1) UUID=d9190a86:8c515f00:2c041f9d:7bc188b8 name=ubuntu:0 level=5 disks=3

これで、今回はRAID5のイメージが与えられていることが分かった。このRAID5では、3つのイメージを揃えて、元のディスクをrebuildして、そのディスクを解析すると思われる。次に、やるべきことは2.imgの復元である。では、どうやって復元するのかというところで次のスライドを参考にした。

www.slideshare.net

このスライドを参考に、「2.img」を「1.img」と「3.img」のXORによって復元しようとした。pythonでやろうとしたが上手くいかず、スライドで出てきたWindowsで使えるXorFilesに頼ったところ簡単にできたと思われる。そして、OSForensicsを使えばRAIDをrebuildできるというのを見たので試したところ全く上手くいかない。
色々悩んだ結果、ReclaiMeというソフトを見つけた。これでディスクマウントができるようなので、XorFilesで復元したイメージと「1.img」,「3.img」を開いてみたところ次のようになった。

f:id:Zarat:20200228204924p:plain
ReclaiMeを使って、色々開いてみた
「1.img」と「3.img」は同じRAIDとして展開されているが、復元したファイルのみが一つのイメージとして認識されてしまい上手くいかない。と思ったが、一つ足りないという状態で展開してみるとjpeg画像見れてしまった。
f:id:Zarat:20200228205520p:plain
見れてしまったflag
flag: HackTM{1bf965b6e23e5d2cb4bdfa67b6d8b0940b5a23e98b8593bb96a4261fb8a1f66a}

回想

今思えば、OSForensicsでrebuildできなかったのは復元したイメージにRAID5を示すラベルのようなものが無かったからのような気がする。

The Sleuth Kitの使い方に触れながら Determine Window Version!

一個前の記事で、
Windowsのバージョン情報どこじゃい - 4ensiX
こんな話をした。 ていうことは、レジストリの任意のkeyを参照できればoffline imagefileのWindows Versionを判定できると思ったのでチャレンジする。 コンシュマー系のWindowsのみやってみる。

今回の流れ

  1. イメージファイルを用意する。これは、構成された完全なrawイメージを使う。
  2. The Sleuth Kitで目的のレジストリハイヴファイルを取り出す。
  3. keyをhivexであったり、何らかの方法で持ってくる。

これでWindows Versionの判定を行う。

レジストリを取り出すWindowsイメージの用意

始めに、バージョン判定するためのwindowsイメージを用意する。ここで使うイメージは、isoではなく、インストールされて構成されたイメージである必要がある。
方針としては、検証したいWindows Versionのisoイメージを拾ってきて、ここから仮想マシンを立てる。この仮想マシンのイメージをrawイメージにして解析する。そんなメンドクサイことなんでやるのって、それは構成されたrawイメージが欲しいからなのだけど、良い方法があればご教授願いたい。
今回はこちらのサイトからイメージをお借りする
GetMyOS

f:id:Zarat:20200130223452p:plain
GetMyOSのホーム
ここにはMac以外なら沢山あるので、色んな環境で検証したいときはおススメ。ただ、WindowsはEnterpriseじゃないとプロダクトキーが必要で使えないので注意。
ダウンロードして見たところ、WinXPくらいまでは、何事もなくVMが動かせた。

f:id:Zarat:20200130224825p:plain
Virtualboxでやってみた
しかし、Windows2000は、Enterpriseが見つからないし、WinMe以前は上手く動かない。しかしisoイメージがなくとも、そもそも仮想イメージを欲しているので仮想イメージがあればいいじゃない。 Windowsのバージョン情報どこじゃい - 4ensiX
Win95,Meは前回の終わりの方で示したVDIを利用する。


Windows Me

Windows Me VDI File for VirtualBox : Microsoft : Free Download, Borrow, and Streaming : Internet Archive

Windows98

X-MAS-CTF/A Trip To Grandmas House.md at master · RealAwesomeness/X-MAS-CTF · GitHub

Windows95

Windows 95 VDI File for VirtualBox : Microsoft : Free Download, Borrow, and Streaming : Internet Archive


ここらで、先ほど揃えたVMの仮想イメージと拾ってきたvdiをrawに変えてから中身みる。イメージの変換はこちらを参照ドぞ。
仮想イメージからファイルを取り出す エラーを吐いたVMからファイルを救え - 4ensiX

自分はこれぐらいの容量で用意した

f:id:Zarat:20200131224502p:plain
windows仮想マシンをできるだけ最小構成にしたあとrawイメージに変換した(ハズ)

The Sleuth Kitのお話

The Sleuth Kitはディスクイメージ解析といえば、AutopsyとFTK Imagerを聞くと思うのですが、そのうちのAutopsyのCLI版という感じで、Cライブラリで動くイメージファイルを扱うツールセット。コマンドは、

blkcalc - Converts between unallocated disk unit numbers and regular disk unit numbers.
blkcat - Display the contents of file system data unit in a disk image.
blkls - List or output file system data units.
blkstat - Display details of a file system data unit (i.e. block or sector).
fcat - Output the contents of a file based on its name.
ffind - Finds the name of the file or directory using a given inode.
fiwalk - print the filesystem statistics and exit.
fls - List file and directory names in a disk image.
fsstat - Display general details of a file system.
hfind - Lookup a hash value in a hash database.
icat - Output the contents of a file based on its inode number.
ifind - Find the meta-data structure that has allocated a given disk unit or file name.
ils - List inode information.
img_cat - Output contents of an image file.
img_stat - Display details of an image file.
istat - Display details of a meta-data structure (i.e. inode).
jcat - Show the contents of a block in the file system journal.
jls - List the contents of a file system journal.
jpeg_extract - jpeg extractor.
mactime - Create an ASCII time line of file activity.
mmcat - Output the contents of a partition to stdout.
mmls - Display the partition layout of a volume system (partition tables).
(以下略)

とまあこんな感じで、ココに色々あるのだが、今回はimg_stat,mmls,fsstat,fls,icatの5つでお送りいたす。

レジストリハイヴを取り出す前準備

基本方針
  1. ファイル形式を判定
    img_stat -t [image file]
  2. パーティションレイアウトを確認
    mmls [image file]
  3. ファイルシステムを確認
    fsstat -i [file type] -o [partition start] -t [image file]
  4. 上記の情報で展開できるか確認
    fsstat -i [file type] -f [file system] -o [partition start] [image file]
  5. レジストリハイヴのinode番号を捜索
    fls -i [file type] -f [file system] -o [partition start] [image file] [inode number]#繰り返す
  6. レジストリハイヴを取り出す
    icat -i [file type] -f [file system] -o [partition start] [image file] [inode number] > [registry]

という手順で進める。しかし、そう簡単にはいかない。1995から2019年のwindowsの変遷を一気に辿ろうものなら、それなりに各々に違いはあるのである。

バージョンごとイメージの違いを確認

用意したイメージはWindows 95からWindows 10から1バージョンずつである。これらはいくつかの点でバージョンによって違いがある。

バージョンごとのファイルシステム

まず、これらはファイルシステムを大まかに3種類に分けられる。

バージョンごとのパーティション情報の違い

次に、バージョンごとのパーティション情報の違いがある。 細かい説明がメンドクサイので、以下を見てもらう。

# mmls win95.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0004193279   0004193217   DOS FAT16 (0x06)
003:  -------   0004193280   0004194303   0000001024   Unallocated
# mmls win98.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0010474379   0010474317   Win95 FAT32 (0x0b)
003:  -------   0010474380   0010485759   0000011380   Unallocated
# mmls winMe.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0008385929   0008385867   Win95 FAT32 (0x0b)
003:  -------   0008385930   0008388607   0000002678   Unallocated

Windows 95, 98, Meまでは、FAT16FAT32の違いはあるが、どれもパーティションが63から始まっている。

# mmls winXPsimple.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0005233535   0005233473   NTFS / exFAT (0x07)
003:  -------   0005233536   0005242879   0000009344   Unallocated
# mmls winVista.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0031455231   0031453184   NTFS / exFAT (0x07)
003:  -------   0031455232   0031457279   0000002048   Unallocated

Windows XPWindows Vistaを比べると、どちらもNTFSであるがパーティションの始まりが63と2048と異なる。

# mmls win7simple.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000206847   0000204800   NTFS / exFAT (0x07)
003:  000:001   0000206848   0025163775   0024956928   NTFS / exFAT (0x07)
004:  -------   0025163776   0025165823   0000002048   Unallocated
# mmls win8simple.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000718847   0000716800   NTFS / exFAT (0x07)
003:  000:001   0000718848   0025163775   0024444928   NTFS / exFAT (0x07)
004:  -------   0025163776   0025165823   0000002048   Unallocated
# mmls win10simple.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0001187839   0001185792   NTFS / exFAT (0x07)
003:  000:001   0001187840   0025163775   0023975936   NTFS / exFAT (0x07)
004:  -------   0025163776   0025165823   0000002048   Unallocated

Windows 7以降では、全てNTFSであるがパーティション領域が2つある。これは、Windows 10 Drive Partitionsによると、1つ目はリカバリパーティションらしい。OSの問題をトラブルシューティングするための回復環境を置いておく領域のようだ。セーフモードとか選ぶ青い画面はここに別パーティションで保持されているということではないだろうか。我々が解析するパーティションは2つ目のパーティションである。

目的レジストリハイブパスの違い

ファイルシステムの変遷に伴い、レジストリハイヴにも変更があったようで、バージョンを参照できる目的レジストリハイブパスは3種類ある。

レジストリハイヴをdump! バージョン判定までいっちゃうゼ

ここでは、Windows 98Windows 10の2つのバージョンからレジストリハイヴを取り出し、バージョン判定までを紹介する。レジストリハイブからkeyの読み込みはhivexを使うがWindowsMe以前のレジストリハイブには対応していない?ようなのでstrings | grepする。

Windows 98からレジストリハイブを取り出してバージョン判定

基本方針に沿っていく。

1.ファイル形式を判定

# img_stat -t win98.raw
raw

2.パーティションレイアウトを確認

# mmls win98.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000000062   0000000063   Unallocated
002:  000:000   0000000063   0010474379   0010474317   Win95 FAT32 (0x0b)
003:  -------   0010474380   0010485759   0000011380   Unallocated

3.ファイルシステムを確認

# fsstat -i raw -o 63 -t win98.raw
fat32

4.上記の情報で展開できるか確認

# fsstat -i raw -f fat32 -o 63 win98.raw
FILE SYSTEM INFORMATION
--------------------------------------------
File System Type: FAT32

OEM Name: MSWIN4.1
Volume ID: 0x187b08f7
Volume Label (Boot Sector): NO NAME 
Volume Label (Root Directory):
File System Type Label: FAT32 
Next Free Sector (FS Info): 20470
Free Sector Count (FS Info): 9003760

Sectors before file system: 63

File System Layout (in sectors)
Total Range: 0 - 10474316
* Reserved: 0 - 31
** Boot Sector: 0
** FS Info Sector: 1
** Backup Boot Sector: 6
* FAT 0: 32 - 10250
* FAT 1: 10251 - 20469
* Data Area: 20470 - 10474316
** Cluster Area: 20470 - 10474309
*** Root Directory: 20470 - 20477
** Non-clustered: 10474310 - 10474316

METADATA INFORMATION
--------------------------------------------
Range: 2 - 167261558
Root Directory: 2

CONTENT INFORMATION
--------------------------------------------
Sector Size: 512
Cluster Size: 4096
Total Cluster Range: 2 - 1306731

FAT CONTENTS (in sectors)
--------------------------------------------
20470-20477 (8) -> EOF
20478-20485 (8) -> EOF
20486-20493 (8) -> EOF
20494-20541 (48) -> EOF
20542-20581 (40) -> EOF
20582-20629 (48) -> 37646
20630-21261 (632) -> 21638
(以下略)

5.レジストリハイヴのinode番号を捜索

# fls -i raw -f fat32 -o 63 win98.raw
r/r 3:    BOOTLOG.TXT
r/r 4:    COMMAND.COM
r/r 5:    SUHDLOG.DAT
r/r 6:    FRUNLOG.TXT
r/r 7:    MSDOS.---
r/r 8:    SETUPLOG.TXT
d/d 9:    WINDOWS
r/r 10:    NETLOG.TXT
r/r 11:    MSDOS.SYS
r/r 12:    VIDEOROM.BIN
r/r 13:    DETLOG.TXT
r/r 14:    CONFIG.SYS
r/r 15:    BOOTLOG.PRV
r/r 16:    AUTOEXEC.BAT
r/r 17:    SYSTEM.1ST
r/r 18:    IO.SYS
d/d 20:    My Documents
d/d 22:    Program Files
r/r 24:    io32.sys
d/d 25:    RECYCLED
r/r 26:    SCANDISK.LOG
r/r * 27:    _UTMP0.19
r/r 29:    autoexec.sdd
v/v 167261555:    $MBR
v/v 167261556:    $FAT1
v/v 167261557:    $FAT2
V/V 167261558:    $OrphanFiles
# fls -i raw -f fat32 -o 63 win98.raw | grep WINDOWS 
d/d 9:    WINDOWS
# fls -i raw -f fat32 -o 63 win98.raw 9 | grep SYSTEM.DAT
r/r 494448:    SYSTEM.DAT

6.レジストリハイヴを取り出す

# icat -i raw -f fat32 -o 63 win98.raw 494448 > SYSTEM.DAT

7.レジストリハイブからkeyを持ってくる。

strings SYSTEM.DAT | egrep 'ProductName' | uniq | sed -e 's/ProductName//g' | grep "Microsoft Windows"
Microsoft Windows 98

Windows Version Determine!

Windows 10からレジストリハイブを取り出してバージョン判定(簡略化)

必要な部分だけ説明を加える。

# img_stat -t win10simple.raw
raw
# mmls win10simple.raw
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0001187839   0001185792   NTFS / exFAT (0x07)
003:  000:001   0001187840   0025163775   0023975936   NTFS / exFAT (0x07)
004:  -------   0025163776   0025165823   0000002048   Unallocated

先ほど示した通り、参照するパーティションは2つ目の方。

# fsstat -i raw -o 1187840 -t win10simple.raw
ntfs
# fsstat -i raw -f ntfs -o 1187840 win10simple.raw
FILE SYSTEM INFORMATION
--------------------------------------------
File System Type: NTFS
Volume Serial Number: DAE616D3E616B02D
OEM Name: NTFS 
Version: Windows XP

METADATA INFORMATION
--------------------------------------------
First Cluster of MFT: 786432
First Cluster of MFT Mirror: 2
Size of MFT Entries: 1024 bytes
Size of Index Records: 4096 bytes
Range: 0 - 93440
Root Directory: 5

CONTENT INFORMATION
--------------------------------------------
Sector Size: 512
Cluster Size: 4096
Total Cluster Range: 0 - 2996990
Total Sector Range: 0 - 23975934

$AttrDef Attribute Values:
$STANDARD_INFORMATION (16)   Size: 48-72   Flags: Resident
$ATTRIBUTE_LIST (32)   Size: No Limit   Flags: Non-resident
$FILE_NAME (48)   Size: 68-578   Flags: Resident,Index
$OBJECT_ID (64)   Size: 0-256   Flags: Resident
$SECURITY_DESCRIPTOR (80)   Size: No Limit   Flags: Non-resident
$VOLUME_NAME (96)   Size: 2-256   Flags: Resident
$VOLUME_INFORMATION (112)   Size: 12-12   Flags: Resident
$DATA (128)   Size: No Limit   Flags:
$INDEX_ROOT (144)   Size: No Limit   Flags: Resident
$INDEX_ALLOCATION (160)   Size: No Limit   Flags: Non-resident
$BITMAP (176)   Size: No Limit   Flags: Non-resident
$REPARSE_POINT (192)   Size: 0-16384   Flags: Non-resident
$EA_INFORMATION (208)   Size: 8-8   Flags: Resident
$EA (224)   Size: 0-65536   Flags:
$LOGGED_UTILITY_STREAM (256)   Size: 0-65536   Flags: Non-resident

何故かWindows XP判定。

# fls -i raw -f ntfs -o 1187840 win10simple.raw | grep Windows
d/d 1731-144-5:    Windows
# fls -i raw -f ntfs -o 1187840 win10simple.raw 1731 | grep System32
d/d 3757-144-7:    System32
# fls -i raw -f ntfs -o 1187840 win10simple.raw 3757 | grep config
d/d 3786-144-7:    config
r/r 40736-128-5:    configmanager2.dll
r/r 41741-128-4:    ipconfig.exe
r/r 42325-128-4:    mmc.exe.config
r/r 42403-128-4:    msconfig.exe
r/r 43649-128-5:    tetheringconfigsp.dll
r/r 43750-128-1:    UevAppMonitor.exe.config
r/r 44447-128-5:    wpr.config.xml
r/r 44488-128-5:    wsmanconfig_schema.xml
# fls -i raw -f ntfs -o 1187840 win10simple.raw 3786 | grep SOFTWARE
r/r 44905-128-5:    SOFTWARE.LOG1
r/r 44863-128-5:    SOFTWARE.LOG2
r/r 49608-128-4:    SOFTWARE
# icat -i raw -f ntfs -o 1187840 win10simple.raw 49608 > SOFTWARE

hivexの登場。

# hivexget SOFTWARE 'Microsoft\Windows NT\CurrentVersion' | egrep 'ProductName|ReleaseId|"ProductId'
"ProductName"="Windows 10 Enterprise Evaluation"
"ReleaseId"="1909"
"ProductId"="*****-*****-*****-*****"
#一応伏せとく

Windows Version Determine!

終わりに

また少しWindowsと仲良くなれました。
ついでに今回の一連の流れをシェルスクリプトにしてみました。初めて書いたシェルスクリプトであり、プログラミングも得意な方ではないので汚いかもしれませんがご査証ください。

# !/bin/sh
# oschecker.sh

# argument check
if [ $# -ne 1 ]; then
    echo "Invalid argument"
    exit 1
fi

if [ "$1" = "-h" ]; then
    echo "Usage: oschecker.sh [-h] [imagefile]"
    echo ""
    echo "-h     print description"
    echo ""
    echo "This script can determine Windows Version (above windows 95) from offline disk image!"
    echo "However, only the raw format is supported."
    echo "In addition, tools must be pre-instaled."
    echo ""
    echo 'Tools:'
    echo "  The Sleuth Kit"
    echo "       (https://www.sleuthkit.org/sleuthkit/)"
    echo ""
    echo "  hivex "
    echo "       ex) sudo apt install libhivex-bin"
    echo ""
    echo ""
    echo "Have a nice DFIR!"
    exit 0 
fi

if [ -f "$1" -a -r "$1" ]; then
    echo "$1"
else
    echo "File Error"
    exit 1
fi

# image open setting
ver="ntfs"

img_type=`img_stat -t "$1"`

partition_s=`mmls "$1" | grep -i FAT`

tmp=`echo "$partition_s" | grep NTFS`
if [ -z "$tmp" ]; then
    ver="fat"
fi

if [ `echo "$partition_s" | grep -c ''` = 2 ]; then
    partition_s=`echo "$partition_s" | grep "003:"`
fi

# image open
str="$partition_s"
ary=(`echo $str`)   # store array

partition_addr=`echo ${ary[2]}`
analyze_s=`fsstat -i "$img_type" -f "$ver" -o "$partition_addr" "$1"`

if [ -z "$analyze_s" ]; then
    echo "file open Error\n please restart"
    exit 1
fi

# search inode number of registry hive
if [ "$ver" = "fat"  ]; then
    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" | grep -i WINDOWS`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" | grep -i SYSTEM.DAT`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    icat -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" > SYSTEM.DAT
    tmp=`strings SYSTEM.DAT | egrep 'ProductName' | uniq | sed -e 's/ProductName//g' | grep "Microsoft Windows"`
    echo '"ProductName"="'"${tmp}"'"'
    rm SYSTEM.DAT

elif [ "$ver" = "ntfs"  ]; then
    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" | grep -i WINDOWS`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" | grep -i system32`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" | grep d/d | grep config`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    tmp=`fls -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" | grep -i software | grep -v LOG`
    str="$tmp"
    ary=(`echo $str`)
    target_inode=`echo ${ary[1]} | sed -e 's/://g' | sed -e 's/-.*//'`

    icat -i "$img_type" -f "$ver" -o "$partition_addr" "$1" "$target_inode" > software
    hivexget software 'Microsoft\Windows NT\CurrentVersion' | egrep 'ProductName|CSDVersion|ReleaseId|"ProductId'
    rm software

else
    echo "now making"
fi

こんな感じで使えます。

# ./oschecker.sh win95.raw
win95.raw
"ProductName"="Microsoft Windows 95"
# ./oschecker.sh win98.raw
win98.raw
"ProductName"="Microsoft Windows 98"
# ./oschecker.sh winMe.raw
winMe.raw
"ProductName"="Microsoft Windows ME"
# ./oschecker.sh winXPsimple.raw
winXPsimple.raw
"ProductName"="Microsoft Windows XP"
"CSDVersion"="Service Pack 3"
"ProductId"="*****-***-*******-*****"
# ./oschecker.sh winVista.raw
winVista.raw
"ProductName"="Windows Vista (TM) Enterprise"
"ProductId"="*****-***-*******-*****"
"CSDVersion"="Service Pack 2"
# ./oschecker.sh win7simple.raw
win7simple.raw
"ProductName"="Windows 7 Enterprise"
"ProductId"="*****-***-*******-*****"
"CSDVersion"="Service Pack 1"
# ./oschecker.sh win8simple.raw
win8simple.raw
"ProductName"="Windows 8 Enterprise N"
"ProductId"="*****-*****-*****-*****"
# ./oschecker.sh win10simple.raw
win10simple.raw
"ProductName"="Windows 10 Enterprise Evaluation"
"ReleaseId"="1909"
"ProductId"="*****-*****-*****-*****"

変数名とかにツッコミどころ満載だし、なんで関数にしないのとかあると思いますがモチベが来たら直します。

Windowsのバージョン情報どこじゃい

ある日、

A:「フォレンジッカー的には、実際はwindowsのシェアが多いから解析対象もwindowsが多いわけです。」

B:「じゃあ、windowsを理解せねばいかんのか」

A:「そうです。windowsと仲良くならなきゃいかんのです。」

B:「windowsのosってディスクイメージからだと、何見て判定するんだろ。てか、そもそもWindowsのバージョン情報てどこに書いてあるんだ

A:「volatilityかな......」

ということでwindowsのバージョン情報の場所を探した記録。

windowsのバージョン確認方法

windowsのバージョン確認方法って、そういえば知らないなと思って調べたら。二つの方法があることを知った。

  • winver.exeを動かす。
  • msinfo32.exeを動かす。

GUIだとこの2種類で見れる。じゃあこの二つがどこを見ているのか。何を参照しているのか。

調べても出てこなかった。。。。。。

何か、Ghidraさんとかで見てみると、レジストリにアクセスしているのが見える。

やっぱwindowsの重要情報といっちゃレジストリか!

でも、レジストリのどこにwindowsのバージョン情報があるのか。

「HKEY_LOCAL_MACHINE\System」とか怪しいなぁと眺めてみたけど分からん。

Windowsのバージョン情報はココだ!

Determine Windows version from offline image » SkullSecurity

つまりwindowsのバージョン情報は、

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion」のkeyにあるらしい。確認してみる。レジストリを見るために、「regedit.exe」を起動する。

f:id:Zarat:20200124163900p:plain

VMの情報なので特にモザイクかけなくても良いかな

あったあったよ。ついに、私、見つけましたわ。つまり、osプロファイルを判定できるvolatilityはここを見ているのかと思ったと共に、でもvolatilityってプロファイル何個も表示するから見ているのはここではないとも思う。

そういえばvolatilityって

volatilityの基本登録プロファイルを見ると、

 Profiles
--------
VistaSP0x64 - A Profile for Windows Vista SP0 x64
VistaSP0x86 - A Profile for Windows Vista SP0 x86
VistaSP1x64 - A Profile for Windows Vista SP1 x64
VistaSP1x86 - A Profile for Windows Vista SP1 x86
VistaSP2x64 - A Profile for Windows Vista SP2 x64
VistaSP2x86 - A Profile for Windows Vista SP2 x86
Win10x64 - A Profile for Windows 10 x64
Win10x64_10586 - A Profile for Windows 10 x64 (10.0.10586.306 / 2016-04-23)
Win10x64_14393 - A Profile for Windows 10 x64 (10.0.14393.0 / 2016-07-16)
Win10x86 - A Profile for Windows 10 x86
Win10x86_10586 - A Profile for Windows 10 x86 (10.0.10586.420 / 2016-05-28)
Win10x86_14393 - A Profile for Windows 10 x86 (10.0.14393.0 / 2016-07-16)
Win2003SP0x86 - A Profile for Windows 2003 SP0 x86
Win2003SP1x64 - A Profile for Windows 2003 SP1 x64
Win2003SP1x86 - A Profile for Windows 2003 SP1 x86
Win2003SP2x64 - A Profile for Windows 2003 SP2 x64
Win2003SP2x86 - A Profile for Windows 2003 SP2 x86
Win2008R2SP0x64 - A Profile for Windows 2008 R2 SP0 x64
Win2008R2SP1x64 - A Profile for Windows 2008 R2 SP1 x64
Win2008R2SP1x64_23418 - A Profile for Windows 2008 R2 SP1 x64 (6.1.7601.23418 / 2016-04-09)
Win2008SP1x64 - A Profile for Windows 2008 SP1 x64
Win2008SP1x86 - A Profile for Windows 2008 SP1 x86
Win2008SP2x64 - A Profile for Windows 2008 SP2 x64
Win2008SP2x86 - A Profile for Windows 2008 SP2 x86
Win2012R2x64 - A Profile for Windows Server 2012 R2 x64
Win2012R2x64_18340 - A Profile for Windows Server 2012 R2 x64 (6.3.9600.18340 / 2016-05-13)
Win2012x64 - A Profile for Windows Server 2012 x64
Win2016x64_14393 - A Profile for Windows Server 2016 x64 (10.0.14393.0 / 2016-07-16)
Win7SP0x64 - A Profile for Windows 7 SP0 x64
Win7SP0x86 - A Profile for Windows 7 SP0 x86
Win7SP1x64 - A Profile for Windows 7 SP1 x64
Win7SP1x64_23418 - A Profile for Windows 7 SP1 x64 (6.1.7601.23418 / 2016-04-09)
Win7SP1x86 - A Profile for Windows 7 SP1 x86
Win7SP1x86_23418 - A Profile for Windows 7 SP1 x86 (6.1.7601.23418 / 2016-04-09)
Win81U1x64 - A Profile for Windows 8.1 Update 1 x64
Win81U1x86 - A Profile for Windows 8.1 Update 1 x86
Win8SP0x64 - A Profile for Windows 8 x64
Win8SP0x86 - A Profile for Windows 8 x86
Win8SP1x64 - A Profile for Windows 8.1 x64
Win8SP1x64_18340 - A Profile for Windows 8.1 x64 (6.3.9600.18340 / 2016-05-13)
Win8SP1x86 - A Profile for Windows 8.1 x86
WinXPSP1x64 - A Profile for Windows XP SP1 x64
WinXPSP2x64 - A Profile for Windows XP SP2 x64
WinXPSP2x86 - A Profile for Windows XP SP2 x86
WinXPSP3x86 - A Profile for Windows XP SP3 x86

 

とまあこんな感じで、XPからある。

せっかくなので他のバージョンの感じも見てみたい。

WindowsXPのバージョンの情報

何となく、8とか7くらいならあまり変わらないのではという先入観から、windowsXPを確認する。

windowsXPx86SP3*1見てみる。

f:id:Zarat:20200124170639p:plain

XPのHKLM\SOFTWARE\Microdoft\Windows NT\Currentversion

WindowsMe

windowsME*2も見てみよ。

f:id:Zarat:20200124170938p:plain

MeのHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion

うん?あれおかしいな。

Windows98

windowsMeと2000は似たようなイメージがあるので、windows98*3はどうだろ。

f:id:Zarat:20200124171123p:plain

98のHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion

後ろが荒れているのは気にしないとして、WindowsMe以前はwindowsのバージョン情報の場所が違う?みたい。

WindowsMe以前はwindowsのバージョン情報ドコ?

困った!?と思ったが、何か押し間違いで「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion」にMeも98も見つけた。

f:id:Zarat:20200124174414p:plain

MeのHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

f:id:Zarat:20200124174252p:plain

98のHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

最後に

Windows95くらいまでは試したかったけど、他にやることがあるので止めました。

これで、少しだけWindowsと仲良くなれました○。

自分で試したい人用資料

基本的に、OSイメージはGetMyOSから持ってくる。しかし、古いものだと各々のOSを起動するために必要なドライバであったり、準備であったりは多岐に渡るのでイメージがあれば仮想マシンとしてすぐ動く!とはならない。一回適当に起動してみれば分かるハズ。vdiはアカウントがすでに作成されているけど、基本的にログインバイパス(例 ログイン画面でesc等)の脆弱性があると思うので大丈夫(大丈夫ではない)。

 

Windows Me

Windows Me VDI File for VirtualBox : Microsoft : Free Download, Borrow, and Streaming : Internet Archive

VDIでVM作ってログインバイパス。

Windows98

Windows 98. SE + Plus 98 Vmware 7z : Microsoft : Free Download, Borrow, and Streaming : Internet Archive

聖なる日にWindows98を動かすお話 - らぴーとの書き溜め

ここら辺でいけそう

Windows95

Windows 95 VDI File for VirtualBox : Microsoft : Free Download, Borrow, and Streaming : Internet Archive

今のパソコン上のVirtualBoxにWindows95を入れる - Qiita

上のやつは試したけど、editが上手く使えなかったので詰んだ。これさえ乗り越えれば簡単そう。

 

 

Windows7が終わるころに、Windows98と95とかと戦っている人がいて安心した。

contrailCTF2019 Forensic Writeup

三週間近く出遅れたけれど、やっと今年のCTFに辿り着いた。

ちょっと前まで話題になっていた気がするcontrailCTFのWriteupをお届け致します。

 Persistence

Can you find persistence.

貰ったファイル「forensics_persistence.arn」を見てみる。

# file forensics_persistence.arn
forensics_persistence.arn: DIY-Thermocam raw data (Lepton 2.x), scale 0-0, spot sensor temperature 0.000000, unit celsius, color scheme 0, calibration: offset 2361183241434822606848.000000, slope 32.249870

よく分からんので、.arnを調べる。

おそらく.arnは、Windows起動時のプログラム実行設定が書いてあるのだという理解でいく。

「Autoruns」の膨大な情報から本当に怪しいヤツをあぶりだすテク:ITプロ必携の超便利システム管理ツール集(2) - @IT

Sysinternalsのautorunsツールで自動起動するプログラムを調査する:Tech TIPS - @IT

これらに従って、Autoruns.exeを使ってみると、Task SchedulerのEvilっていう怪しいkeyにflagがある。

ctrctf{P3rs1st3nc3_5ch3dul3d_Ta3ks}

 

alice's_password

Alice losts her password...

I lockyou alice's password.

 

zip password is md5(alice's password)

 Forensicといえばメモリダンプとディスクイメージというのが本来だが、最近めっきり見なくなったメモリダンプ解析問題。とりあえず、volatility使うのが定石。そんで、SECCONの過去問でこんなの見たことある。レジストリの仮想アドレス見て、SYSTEMとSAMレジストリあればパスワードのハッシュダンプできる。

https://gomiba.co.in/blog/archives/342

# volatility -f memdump.mem --profile=Win7SP1x64 hivelist
Volatility Foundation Volatility Framework 2.6
Virtual Physical Name
------------------ ------------------ ----
~略~
0xfffff8a000024010 0x000000002d4c2010 \REGISTRY\MACHINE\SYSTEM
~略~
0xfffff8a0063fa010 0x0000000077843010 \SystemRoot\System32\Config\SAM

 

 # volatility -f memdump.mem --profile=Win7SP1x64 -y 0xfffff8a000024010 -s 0xfffff8a0063fa010 hashdump
Volatility Foundation Volatility Framework 2.6
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Aqua:1000:aad3b435b51404eeaad3b435b51404ee:813ea107eccdab91a1b9c15b67693cb4:::
Alice:1001:aad3b435b51404eeaad3b435b51404ee:19bf8c07d19ea196464115e443854654:::

 

とりあえずAliceのntlmハッシュをCrackStationに投げるとハッシュ解読できて、それをmd5が別で貰ったzipファイルのパスワードということでflag

ctrctf{Y0u_c4n_dump_4nd_cr4ck_hash!}

できるならばjohnでハッシュ解決したかったけど、今後の課題。

 

cutecats

I'm browsing cute catz...

Do you know my password ?

 同じメモリダンプで問題に取り組む。まず、問題文の「cute catz」が引っかかった。catz?  もう一つcutecatsを見て、「mimikatzはフランス語だかでcute catsを意味する」というのを思い出した。つまりmimikatzを使うということですな。

Tag : forensics volatility mimikatz « g4ngli0s's blog

Windows Credentials and Memory Dumps – Part 4: Volatility & Mimikatz | govolution

plugins使う場合は、windowsだと色々モジュールが必要でメンドクサソウ。

# volatility --plugins=/usr/share/volatility/plugins -f memdump.mem --profile=Win7SP1x64 mimikatz
Volatility Foundation Volatility Framework 2.6
Module User Domain Password
-------- ---------------- ---------------- ----------------------------------------
wdigest Aqua WIN-O1AE35RFM94 ctrctf{Y0u_c4n_us3_m1m1katz}
wdigest WIN-O1AE35RFM94$ WORKGROUP

 

ctrctf{Y0u_c4n_us3_m1m1katz}

 

once_again

 Can you find registry ?

新たに与えられたメモリダンプ「onceagain.mem」を見ていく。レジストリの何を見るんだろ。手がかりはおそらく「once again」。そこで「windows registry once again」で調べてみると、

Run and RunOnce Registry Keys - Win32 apps | Microsoft Docs

「RunOnce」これかなということで見てみる。

# volatility -f onceagain.mem --profile=Win7SP1x64 printkey -K "Microsoft\Windows\CurrentVersion\RunOnce"
Volatility Foundation Volatility Framework 2.6
Legend: (S) = Stable (V) = Volatile

----------------------------
Registry: \SystemRoot\System32\Config\SOFTWARE
Key name: RunOnce (S)
Last updated: 2019-12-10 14:09:45 UTC+0000

Subkeys:

Values:
REG_SZ flag : (S) pgspgs{i0yng1y1gl_1f_hf3shy_zrz0elnanylf1f}

 

これだね。

# echo pgspgs{i0yng1y1gl_1f_hf3shy_zrz0elnanylf1f} | nkf -r
ctfctf{v0lat1l1ty_1s_us3ful_mem0ryanalys1s}

 

 

ちゃんとCTF開催中に参加したいこの頃