備忘録：バイナリ解析２ 表層解析

<h2>バイナリ解析</h2>
<h6><INS>バイナリ解析とは</INS></h6>
バイナリ解析はバイナリファイルのうち、主に実行形式ファイルを対象として解析を
することです。実行形式ファイルはプログラムのことです。なので、バイナリ解析は
プログラムの動作や構造を解析をすることといえます。

<h6><INS>バイナリ解析の手法</INS></h6>
バイナリ解析の手法には、表層解析、動的解析、静的解析の３つの方法があります。
これらの3つの手法を組み合わせて解析をします。
それぞれの解析で得られる情報の多さは、「表層解析＜動的解析＜静的解析」のよう
になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531099/71e2a70f-004e-cb6c-e997-bff4ce7b51a8.png)

<h2>表層解析</h2>
<h6><INS>表層解析とは</INS></h6>
バイナリ解析で最初に実行するのが表層解析です。表層解析ではファイルの表層的な
情報を収集します。そして、収集したデータを元に、インターネットを検索したり、
過去の解析データなどを調査したりします。
表層解析はデジタルフォレンジックの証拠収集にも使われる重要な技術です。
表層解析で得られる情報はそれほど多くありませんが、あまり時間をかけることなく、
動的解析や静的解析で参考になる情報を得ることができます。

<h6><INS>表層解析で取得できる情報</INS></h6>
<font color="Red">表層解析では次のような情報を取得できます。

⚫ ファイルの名前
⚫ ファイルのフォーマット（＝ファイルの種別）
⚫ ファイルのメタ情報
⚫ ファイルに含まれる文字列
⚫ ファイルのハッシュ値
⚫ パッカーの種類</font>

<h2>メタデータ</h2>
<h6><INS>メタデータとは</INS></h6>
メタデータ（metadata）とは、データについてのデータです。データに付随した
そのデータ自身の付加的なデータです。
文書、画像、音声、動画などのファイルフォーマットでは、ファイルのヘッダ情報
でメタデータを保持します。マジックナンバーもメタデータです。ファイルの
途中にメタデータが保持されている場合もあります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531099/5d724c7e-ddd3-5591-8da1-19a71d9d3a41.png)

<h2>表層解析で使用するコマンド</h2>
<h6><INS>表層解析で使用するコマンド</INS></h6>
表層解析では、ファイルの内容やメタデータを収集して解析します。
ファイル内容を表層解析することを、 <font color="Red">ファイルフォレンジック</font>といいます。
表層解析では主に次のようなコマンドを使用します。

⚫ file
⚫ strings
⚫ zip / unzip / gzip / gunzip
⚫ tar
⚫ openssl
⚫ upx
⚫ exiftool
⚫ binwalk
⚫ od / hexdump / xxd

<h2>fileコマンド</h2>
<h6><INS>fileコマンドの概要</INS></h6>
fileコマンドは、ファイルフォーマット（＝ファイル種別）を出力するコマンドです。
fileコマンドは拡張子からファイルのフォーマットを判断するのではなく、ファイル
のマジックナンバーから判定します。
テキストファイルの場合には、文字コード名が出力されます。

<h6><INS>マジックナンバーの定義</INS></h6>
/usr/share/file/magic.mgcは、コンパイルされたマジックファイルです。
マジックファイルには、マジックナンバーの定義が多数格納されています。
fileコマンドはこのファイルを参照して、ファイルフォーマットを判定します。
マジックファイルにエントリがない場合には、テキストファイルとみなされて、
文字コードやプログラミング言語のソースファイルではないかが判定されます。
ファイルフォーマットやテキストファイルの判定ができない場合には、単に ”data”
と出力されます。

```
$ file what-1
what-1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0,
not stripped
$ file what-2
what-2: Zip archive data, at least v1.0 to extract
$ file what-3
what-3: PNG image data, 1526 x 553, 8-bit/color RGBA, non-interlaced
$ file what-4
what-4: data　←ファイル種別が判断できない場合には data と出力される
$ file what-5
what-5: ASCII text
$ file what-6　←テキストファイルの場合にはtextと出力される（この場合、文字コードはASCII）
what-6: gzip compressed data, was "leaf.pdf", last modified: Sun Jan 27
16:39:07 2019, from Unix, original size 40754
$ file what-7　←文字コードがUTF-8のテキストファイル
what-7: UTF-8 Unicode text
$ file what-8
what-8: C source, ASCII text
ファイル種別が判断できない場合には data と出力される
テキストファイルの場合にはtextと出力される（この場合、文字コードはASCII）
文字コードがUTF-8のテキストファイル
C言語のソースファイル
```

<h2>ASCIIZ文字列</h2>
<h6><INS>ASCIIZ文字列</INS></h6>
ASCIIコードで表示可能な範囲の文字（0x20～0x7e）が連続していて、
終端がNUL文字（0x0）であるデータをASCIIZ文字列といいます。NUL文字は¥0と
表現されることもあります。通常はASCIIZ文字列のことを、単に文字列といいます。
文字列はダブルクォーテーションやシングルクォーテーションで囲んで表すことが
あります。C言語ではダブルクォーテーションで囲みます。
NUL文字を除く文字数（=バイト数）を、文字列の長さといいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531099/23bfb8e9-dfe3-90f4-5e1a-e5cd6dabf722.png)

<h2>stringsコマンド</h2>
<h6><INS>stringsコマンド</INS></h6>
stringsコマンドは、バイナリファイル内に含まれる文字列を抜き出して、それを
表示するコマンドです。実行形式ファイルや各種データファイルなどの、非テキスト
ファイルから文字列を抜き出すことができます。

stringsコマンドは、デフォルトでは文字列の長さが4以上の文字列を出力します。
-nオプション、または、-数値 オプションで、文字列の最小の長さを指定できます。
stringsコマンドは、NUL文字以外の文字であっても、表示可能ではない文字を
終端文字とみなします。そのため、たまたま表示可能な文字が連続している場合には、
意味がない文字列でありながら文字列とみなされて表示されることがあります。

<h2>grepコマンド</h2>
<h6><INS>grepコマンド</INS></h6>
grepコマンドは、ファイルの中からパターン文字列を含む行を抽出して出力します。
-vオプション（reverse）を使用すると、指定した文字列を含まない行を抽出します。
アルファベットの大文字・小文字を区別しない場合には、-iオプション（ignore
case）オプションを使用します。

パターン文字列は正規表現（regular expression）を使用できます。
grepコマンドは、ファイルを指定する以外に、他のコマンドの実行結果を
パイプ機能で連結して、パターン文字列を含む行を抽出することもできます。
egrepコマンド
egrepコマンドは、パターン文字列に拡張正規表現を使用することができます。
grepコマンドに –E オプションを指定すると、egrepコマンドとして動作します。
<h6>[stringsとgrepの実行例]</INS></h6>

```
$ file fruits
fruits: data ←ファイル種別は不明なのでdataと表示される
$ strings fruits
apple
banana
cherry
durian
$ strings –n 6 fruits　←抽出する文字列の最低文字数を6文字とする（オプションは -6 でも良い）
banana
cherry
durian
$ strings fruits | grep 'an'　←文字列"an"を含む行のみを抽出して出力する
banana
durian
$ strings fruits | egrep 'an|ry'　
banana　　　　　↑
cherry　　　　　文字列"an"または”ry"を含む行のみを抽出して出力する
durian　　　　　| は拡張正規表現で利用できるメタ文字である　ファイル種別は不明なのでdataと表示される
```

<h2>ハッシュ値</h2>
<h6>ハッシュ値とは</INS></h6>
ハッシュ値（hash value）は、データが持つ固有で固定サイズの値です。
<font color="Red">ハッシュ値は、要約値、ダイジェスト値、または単にハッシュ</font>ともいいます。
ハッシュ値はハッシュ関数によって計算されます。ハッシュ関数は一方向関数なので、
圧縮とは異なりハッシュ値を元のデータに戻すことはできません（不可逆）。
同一データのハッシュ値は同じ値になり、<font color="Red">1ビットでも異なるデータ</font>ではハッシュ値
が異なります。
ハッシュ関数は、ハッシュアルゴリズムによってハッシュ値を計算します。ハッシュ
アルゴリズム毎に、ハッシュ値のサイズは決まっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531099/154c6ab5-f5cf-92dc-5cda-a2bda64126b0.png)

<h2>OpenSSL</h2>
<h6>OpenSSL</INS></h6>
OpenSSLは、インターネットで標準的に利用されている暗号通信プロトコルである
SSL（Secure Sockets Layer）やTLS（Transport Layer Security）の機能を実装
した、オープンソースのライブラリです。
opensslコマンド
opensslコマンドは、OpenSSLライブラリを使用して、暗号化に関する様々な
処理を実行するコマンドです。

opensslコマンドでは次のような暗号化機能を実行できます。
⚫ ファイルの暗号化と復号
⚫ ハッシュ値の計算
⚫ 秘密鍵と公開鍵の鍵ペアの作成と管理
⚫ デジタル証明書の作成やフォーマット変換
⚫ デジタル証明書の署名と検証
⚫ 素数の生成やテスト

```
$ openssl version
OpenSSL 1.0.2g 1 Mar 2016　←バージョンによっては脆弱性があるので注意が必要
```
```
$ openssl dgst -md5 fileA
MD5(fileA)= e468c3ece792485afc96218c97cddacd　←opensslでMD5を指定してハッシュ値を取得する（省略時はSHA-256
```
```
$ md5sum fileB
e468c3ece792485afc96218c97cddacd fileB　←MD5のハッシュ値はmd5sumでも計算できる
```
```
$ openssl dgst -md5 fileC
MD5(fileC)= 130d7297cb79fdbdacfbac5f46e4f66c　←内容が異なるとハッシュ値も異なる
```
```
※catでfileAの内容を表示する
$ cat fileA
Supercalifragilisticexpialidocious　

※fileBの内容はfileAと同じなので、ハッシュ値も同じ
$ cat fileB
Supercalifragilisticexpialidocious　←バージョンによっては脆弱性があるので注意が必要

※fileAとfileCは内容が異なるので、ハッシュ値も異なる
$ cat fileC
Supercaliflagilisticexpialidocious　←バージョンによっては脆弱性があるので注意が必要
```
```
$ openssl dgst -sha1 fileA
SHA1(fileA)= 8dd1d16bf3aadadb2d625f4a54c6b861fd27920　1←ハッシュアルゴリズムにSHA-1を指定する


$ sha1sum fileB
8dd1d16bf3aadadb2d625f4a54c6b861fd279201 fil　←SHA-1はsha15sumでも計算できる
```

<h2>圧縮/解凍コマンド</h2>
<h6>圧縮/解凍コマンド</INS></h6>
ファイルの内容をファイルサイズが小さくなるように変換することを圧縮
（compress）といいます。その逆に、圧縮したファイルを圧縮前のファイルに復元
することを解凍（decompress）といいます。

ファイルの圧縮にはzipコマンドやgzipコマンドを使用します。また、ファイルの
解凍にはunzipコマンドやgunzipコマンドを使用します。

<h6>アーカイブ</INS></h6>
複数のファイルを１つにまとめたファイルをアーカイブ（archive）といいます。
アーカイブを操作するコマンドをアーカイバ（archiver）といいます。
Linuxのアーカイバはtar（tape archiver）コマンドです。tarコマンドで、
アーカイブを作成したり、アーカイブからファイルを抽出したりすることができます。

<h6>[zipの実行例]</INS></h6>

```
$ ls boss.txt sally.txt mike.txt
-rw-r--r-- 1 guest guest 92 1月 4 08:02 boss.txt
-rw-r—r– 1 guest guest 114 1月 4 08:03 mike.txt
-rw-r--r-- 1 guest guest 49 1月 4 08:03 sally.txt
$ zip monsters.zip boss.txt sally.txt mike.txt　　←※zipで圧縮する
adding: boss.txt (deflated 1%)
adding: sally.txt (deflated 25%)
adding: mike.txt (deflated 14%)
$ ls –l monsters.zip
-rw-r—r– 1 guest guest 666 1月 31 13:23 monsters.zip
$ file mosnsters.zip
monsters.zip: Zip archive data, at least v2.0 to extract
```

<h6>[unzipの実行例]</INS></h6>

```
$ unzip -l monsters.zip　←-lオプションでunzipで一覧表示する
Archive: monsters.zip
Length Date Time Name
--------- ---------- ----- ----
92 2019-01-31 09:58 boss.txt
49 2019-01-31 09:59 sally.txt
114 2019-01-31 10:02 mike.txt
--------- -------
255 3 files

$ rm boss.txt sally.txt mike.txt
$ unzip monsters.zip　←unzipで解凍する
Archive: monsters.zip
inflating: boss.txt
inflating: sally.txt
inflating: mike.txt
$ ls boss.txt sally.txt mike.txt
boss.txt mike.txt sally.txt
```

<h6>[gzip / gunzipの実行例]</INS></h6>

<h6>[tarの実行例]</INS></h6>

```
※tarでアーカイブを作成する※
$ tar cvf nemo.tar bruce.txt dory.txt marlin.txt
bruce.txt
dory.txt
marlin.txt  ※3つのファイルがアーカイブファイルnemo.tarにアーカイブされる※
※cは圧縮（compress）、vは実行状況表示（verbose）、fはファイル名指定（filename）※
```
```
$ file nemo.tar
nemo.tar: POSIX tar archive (GNU)
$ tar tvf nemo.tar　　　　　　　　　　　　　　　　　　　　※tarでアーカイブの一覧表示する※
-rw-r--r-- menta/menta 14 2019-01-31 16:24 bruce.txt
-rw-r--r-- menta/menta 52 2019-01-31 16:21 dory.txt
-rw-r--r-- menta/menta 36 2019-01-31 16:25 marlin.txt
$ tar xf nemo.tar　　　　　　　　　　　　　　　　　　　　　※tarでアーカイブの展開する（extract）※
$ tar cfz nemo.tar.gz bruce.txt dory.txt marlin.txt　　 ※アーカイブをgzip圧縮して作成する※
$ file nemo.tar.gz
nemo.tar.gz: gzip compressed data, last modified: Thu Jan 31 18:49:52 2019,
from Unix, original size 10240
$ tar xfz nemo.tar.gz
```

<h2>パッカー</INS></h2>
<h6>パッカー</INS></h6>
パッカー（packer）は、実行形式ファイルの圧縮ソフトウェアです。パッカーで圧
縮することをパック（pack）、解凍することをアンパック（unpack）といいます。
パックしたファイルは実行時に自動的にメモリ内で解凍されるので、アンパックせず
にそのまま実行することができます。

upxコマンド
upx（ultimate packer for executables）コマンドはパッカーの一種です。
upxコマンドで実行形式ファイルを圧縮すると、実行可能なプログラムのままで
ファイルサイズを約50％～70％削減することが可能です。
upxコマンドは、マルウェアの作成者が、検出や解析から逃れるためにパックする
場合に使われることもあります。

<h6>[upxの実行例（パック）]</INS></h6>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531099/7dd01eae-f6bb-f36d-c66f-c9f3f3bb47e6.png)

<h6>[upxの実行例（アンパック）]</INS></h6>

```
$ ls –l hello
-rwxr-xr-x 1 guest guest 315328 1月 11 16:14 hello
$ upx -d hello 　　　　　　　　　　　　　←※upxに-d オプションを指定してアンパックする
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2013
UPX 3.91 Markus Oberhumer, Laszlo Molnar & John Reiser Sep 30th
2013
File size Ratio Format Name
-------------------- ------ ----------- -----------
735787 <- 315328 42.86% netbsd/elf386 hello
Unpacked 1 file.
$ ls -l hello
-rwxr-xr-x 1 guest guest 732428 1月 11 16:14 hello
```

<h2>exiftoolコマンド</INS></h2>
<h6>Exif</INS></h6>
Exif（Exchangeable image file format）は、ファイル内に写真用のメタデータを
含む画像ファイルフォーマットです。
Exifでは撮影した画像データと併せて、撮影した日時やデジタルカメラの機種、
絞り値、画素数、ISO感度、色空間などの情報がメタデータとして記録されます。

<h6>exiftoolコマンド</INS></h6>
exiftoolコマンドは、ファイルのExif情報を表示したり編集したりするコマンドです。
exiftoolは、Microsoft Officeで作成したファイルや、PDFファイルなどのメタデータ
も操作することができます。Exif情報の改ざんや削除も可能です。

<h6>[exiftoolコマンドの実行例]</INS></h6>

```
$ exiftool tokyotower.jpg　　←※exiftoolでEXIF情報を表示する
ExifTool Version Number : 10.10
File Name : tokyotower.jpg
Directory : .
File Size : 11 MB
File Modification Date/Time : 2023:01:11 14:17:15+09:00
File Access Date/Time : 2023:01:11 14:17:19+09:00
File Inode Change Date/Time : 2023:01:11 14:17:15+09:00
File Permissions : rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
～（略）～
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 3936x5248
Megapixels : 20.7
```

<h2>binwalkコマンド</INS></h2>
<h6>binwalkコマンド</INS></h6>
binwalkコマンドは、圧縮、アーカイブ、パックによって、ファイル内に埋め込まれ
ているファイルを確認したり取り出したりすることができるコマンドです。
-e オプションで圧縮ファイルやアーカイブファイルを展開することができます。

[binwalkの実行例]

```
$ file tokyotower.jpg　　　※fileで確認するとJEPG画像ファイルであると認識される※
tokyotower.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density
1x1, segment length 16, baseline, precision 8, 3936x5248, frames 3
$ binwalk -B tokyotower.jpg　　　※binwalkで確認すると gzipで圧縮されたファイルが埋め込まれて※
DECIMAL HEXADECIMAL DESCRIPTION　※（追加されて）いることがわかる※
---------------------------------------------------------------------------
-----
0 0x0 JPEG image data, JFIF standard 1.01
11962987 0xB68A6B gzip compressed data, has original file name:
"messages.txt", from Unix, last modified: 2023-01-11 02:51:49
$ binwalk –e tokyotower.jpg　　　※binwalkで展開する※
DECIMAL HEXADECIMAL DESCRIPTION
---------------------------------------------------------------------------
-----
0 0x0 JPEG image data, JFIF standard 1.01
11962987 0xB68A6B gzip compressed data, has original file name:
"messages.txt", from Unix, last modified: 2023-01-11 02:51:49

$ cd _tokyotower.jpg.extracted※展開されたファイルのあるディレクトリに移動する※
$ ls
messages.txt
$ cat messages.txt※内容を表示してみるとBase64でエンコードされているように見える※
Y3Rme0ZsYWdJc0ZyaWVkUG90YXRvfQo=
$ cat messages.txt | base64 -d　　※base64でデコードする※
ctf{Flag}
```