SECCON 2018 オンライン予選 「History」解説

# はじめに
現在CTF勉強の一環として SECCON の過去問題を解いています。今回は SECCON 2018 のオンライン予選に出題された「History」という問題について解説します。

# History
History は Forensics に分類されています。問題ファイルは以下のページから取得。

https://github.com/SECCON/SECCON2018_online_CTF/tree/master/Forensics/History

# 解き方
## まずは問題の把握から
question.txt を見ると、以下の記述がみられます。
```
History
Check changed filename.
file:J.zip_4c7050d70c9077b8c94ce0d76effcb8676bed3ba
```
直訳すると「ファイル名変更をチェックせよ」でしょうか。
ファイル名が書かれているのでそのファイルを調査していきます。

## ファイルの調査
J.zip_4c7050d70c9077b8c94ce0d76effcb8676bed3ba について、fileコマンドを使ってファイルの種別を確認します。
```
$ file J.zip_4c7050d70c9077b8c94ce0d76effcb8676bed3ba
J.zip_4c7050d70c9077b8c94ce0d76effcb8676bed3ba: Zip archive data, at least v2.0 to extract, compression method=deflate
```
出力より、このファイルは拡張子が示す通りのzipファイルであることがわかりました。そこで、ファイル名をJ.zipに変更してunzipコマンドを用いて展開し、得られたファイルJに対してfileコマンドを使います。
```
$ unzip J.zip
$ file J
J: data
```
結果として「data」が出力されました。fileコマンドの出力は3通りで、text, executable, dataに分かれ、それぞれテキストファイル、実行可能ファイル、その他（バイナリファイルなど）をあらわします。stringsコマンドを用いても大した情報は得られませんでした。
このままでは特に情報が得られないと判断し、hexdumpコマンドを使ってさらに詳しくデータを観察します。
```
$ hexdump -C J | head -n 50
00000000  60 00 00 00 02 00 00 00  55 ed 00 00 00 00 23 00  |`.......U.....#.|
00000010  61 08 00 00 00 00 01 00  d0 73 3f 01 00 00 00 00  |a........s?.....|
00000020  a4 df f6 d3 62 49 d1 01  00 01 00 00 00 00 00 00  |....bI..........|
00000030  00 00 00 00 20 00 00 00  22 00 3c 00 6e 00 67 00  |.... ...".<.n.g.|
00000040  65 00 6e 00 5f 00 73 00  65 00 72 00 76 00 69 00  |e.n._.s.e.r.v.i.|
00000050  63 00 65 00 2e 00 6c 00  6f 00 63 00 6b 00 00 00  |c.e...l.o.c.k...|
00000060  60 00 00 00 02 00 00 00  a7 56 00 00 00 00 01 00  |`........V......|
00000070  61 08 00 00 00 00 01 00  30 74 3f 01 00 00 00 00  |a.......0t?.....|
00000080  a4 df f6 d3 62 49 d1 01  02 00 00 00 00 00 00 00  |....bI..........|
00000090  00 00 00 00 20 00 00 00  20 00 3c 00 6e 00 67 00  |.... ... .<.n.g.|
000000a0  65 00 6e 00 5f 00 73 00  65 00 72 00 76 00 69 00  |e.n._.s.e.r.v.i.|
000000b0  63 00 65 00 2e 00 6c 00  6f 00 67 00 00 00 00 00  |c.e...l.o.g.....|
000000c0  60 00 00 00 02 00 00 00  a7 56 00 00 00 00 01 00  |`........V......|
000000d0  61 08 00 00 00 00 01 00  90 74 3f 01 00 00 00 00  |a........t?.....|
000000e0  a4 df f6 d3 62 49 d1 01  02 00 00 80 00 00 00 00  |....bI..........|
000000f0  00 00 00 00 20 00 00 00  20 00 3c 00 6e 00 67 00  |.... ... .<.n.g.|
00000100  65 00 6e 00 5f 00 73 00  65 00 72 00 76 00 69 00  |e.n._.s.e.r.v.i.|
00000110  63 00 65 00 2e 00 6c 00  6f 00 67 00 00 00 00 00  |c.e...l.o.g.....|
00000120  60 00 00 00 02 00 00 00  55 ed 00 00 00 00 23 00  |`.......U.....#.|
00000130  61 08 00 00 00 00 01 00  f0 74 3f 01 00 00 00 00  |a........t?.....|
（中略）
```
2バイト文字であることがわかったのでstringsコマンドをオプションを付けて実行します。
```
$ strings -e l J
```
実行結果は割愛しますが、WindowsUpdate.logなどの文字が含まれていました。このことから、JがWindowsOSに関係のあるファイルであることがわかりました。

## Jの正体
結論を述べると、Jの正体はUSNジャーナルファイルです。
Jの正体にたどり着く道筋は各々の経験などによって異なると思います。以下はその一例です。
- 問題文からファイル変更に関する情報が記載されたファイルであると推測できる
- ファイル名「J」からUSNジャーナルが想起できる
- 前述の手順からJがWindowsOS関連のファイルであると推測できる

本記事以外にも本問の解説記事はネットに転がっているので見比べてみるのもよいでしょう。

## usnジャーナルファイルの解析
usnジャーナルファイルの解析にはusnparserを使います。
まずはusnparserをインストールします。
```
pip install usnparser
```
次に以下のリンクからusn.pyをダウンロード、手元のフォルダに置く必要があります。

https://github.com/PoorBillionaire/USN-Journal-Parser/blob/master/usnparser/usn.py

ここまで出来たら後はコマンドを実行するだけ。
実行例も確認しておきましょう。
```
dev@computer:$ python usn.py -f usnjournal -o /tmp/usn.txt
dev@computer:$ cat /tmp/usn.txt
```
usnjournalはUSNジャーナルファイル、/tmp/usn.txtは出力ファイルをあらわします。
今回の場合、以下のように書けばよいです。
```
python3 usn.py -f J -o usn.txt
```

実行すると以下のデータがusn.txtに保存されます。
```
$ python3 usn.py -f J -o usn.txt
（中略）
2018-09-29 07:51:24.557945 | SEC.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:51:24.557945 | CON{.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:51:24.557945 | CON{.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:52:22.779984 | CON{.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:52:22.779984 | F0r.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:52:22.779984 | F0r.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:52:26.330582 | WmiApRpl_new.h | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:52:26.330582 | WmiApRpl.h | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:52:26.330582 | WmiApRpl.h | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:52:26.330582 | WmiApRpl_new.ini | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:52:26.330582 | WmiApRpl.ini | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:52:26.330582 | WmiApRpl.ini | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:52:53.691992 | F0r.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:52:53.691992 | ensic.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:52:53.691992 | ensic.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:53:08.622816 | ensic.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:53:08.622816 | s.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:53:08.622816 | s.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:54:24.492611 | s.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:54:24.492611 | _usnjrnl.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:54:24.492611 | _usnjrnl.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
2018-09-29 07:54:38.376635 | _usnjrnl.txt | ARCHIVE | RENAME_OLD_NAME
2018-09-29 07:54:38.376635 | 2018}.txt | ARCHIVE | RENAME_NEW_NAME
2018-09-29 07:54:38.376635 | 2018}.txt | ARCHIVE | RENAME_NEW_NAME CLOSE
（中略）
```

## ログデータの解析
usn.py が出力するログの形式は以下の通りです
```
ログの作成時刻 | ファイル名 | ファイル属性 | USN REAZON
```
左から、ログの作成時刻、ファイル名、ファイル属性、USN REAZON をあらわします。今回の問題はファイル名変更のチェックであるということを考え、USN REAZON が RENAME*** となっているものを探します。

ファイル名部分をよく見ると、SEC.txt、CON{.txt、などいかにもな文字列を名前に含むファイルが発見できました。そこで、RENAME_OLD_NAME、RENAME_NEW_NAME がこの順に並ぶログを集めると、同一ファイルが 

SEC.txt　⇒　CON{.txt　⇒　F0r.txt　⇒　ensic.txt　⇒　s.txt　⇒　_usnjrnl.txt　⇒　2018}.txt

の順に名称変更されていることがわかります。これらのファイル名から拡張子を取り除いてつなぎ合わせると「SECCON{F0rensics_usnjrnl2018}」という文字列が得られました。これが求めるフラグです。


# 参考
・USNジャーナル解析の追及

https://www.jpcert.or.jp/present/2018/JSAC2018_03_yamazaki.pdf

・入門セキュリティコンテスト

https://gihyo.jp/book/2022/978-4-297-13180-7