hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

binwalkコマンドの使い方

1 binwalkコマンドとは?

ファイルの種別を調べたり、ファイルの中にファイルが含まれているファイルからファイルを抽出できるコマンドです。

公式ページは以下になります。
https://github.com/ReFirmLabs/binwalk

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 インストール方法

公式ページの手順にしたがって、インストールしてみます。

公式ページからファイルをダウンロードします。

[root@server ~]# wget https://github.com/ReFirmLabs/binwalk/archive/master.zip

ダウンロードしたファイルを確認します。

[root@server ~]# ls -l master.zip
-rw-r--r--. 1 root root 39775250  5月  9 19:49 master.zip

ダウンロードしたファイルを解凍します。

[root@server ~]# unzip master.zip

binwalkコマンドをインストールします。

[root@server binwalk-master]# cd binwalk-master && sudo python setup.py uninstall && sudo python setup.py install

binwalkコマンドの版数を確認します。

[root@server binwalk-master]# cd
[root@server ~]# binwalk -h

Binwalk v2.3.3
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
-snip-

4 オプション一覧

オプションは以下のとおりです。

[root@server ~]# binwalk -h

Binwalk v2.3.3
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk

Usage: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...

Signature Scan Options:
    -B, --signature              Scan target file(s) for common file signatures
    -R, --raw=<str>              Scan target file(s) for the specified sequence of bytes
    -A, --opcodes                Scan target file(s) for common executable opcode signatures
    -m, --magic=<file>           Specify a custom magic file to use
    -b, --dumb                   Disable smart signature keywords
    -I, --invalid                Show results marked as invalid
    -x, --exclude=<str>          Exclude results that match <str>
    -y, --include=<str>          Only show results that match <str>

Extraction Options:
    -e, --extract                Automatically extract known file types
    -D, --dd=<type[:ext[:cmd]]>  Extract <type> signatures (regular expression), give the files an extension of <ext>, and execute <cmd>
    -M, --matryoshka             Recursively scan extracted files
    -d, --depth=<int>            Limit matryoshka recursion depth (default: 8 levels deep)
    -C, --directory=<str>        Extract files/folders to a custom directory (default: current working directory)
    -j, --size=<int>             Limit the size of each extracted file
    -n, --count=<int>            Limit the number of extracted files
    -0, --run-as=<str>           Execute external extraction utilities with the specified user's privileges
    -1, --preserve-symlinks      Do not sanitize extracted symlinks that point outside the extraction directory (dangerous)
    -r, --rm                     Delete carved files after extraction
    -z, --carve                  Carve data from files, but don't execute extraction utilities
    -V, --subdirs                Extract into sub-directories named by the offset

Entropy Options:
    -E, --entropy                Calculate file entropy
    -F, --fast                   Use faster, but less detailed, entropy analysis
    -J, --save                   Save plot as a PNG
    -Q, --nlegend                Omit the legend from the entropy plot graph
    -N, --nplot                  Do not generate an entropy plot graph
    -H, --high=<float>           Set the rising edge entropy trigger threshold (default: 0.95)
    -L, --low=<float>            Set the falling edge entropy trigger threshold (default: 0.85)

Binary Diffing Options:
    -W, --hexdump                Perform a hexdump / diff of a file or files
    -G, --green                  Only show lines containing bytes that are the same among all files
    -i, --red                    Only show lines containing bytes that are different among all files
    -U, --blue                   Only show lines containing bytes that are different among some files
    -u, --similar                Only display lines that are the same between all files
    -w, --terse                  Diff all files, but only display a hex dump of the first file

Raw Compression Options:
    -X, --deflate                Scan for raw deflate compression streams
    -Z, --lzma                   Scan for raw LZMA compression streams
    -P, --partial                Perform a superficial, but faster, scan
    -S, --stop                   Stop after the first result

General Options:
    -l, --length=<int>           Number of bytes to scan
    -o, --offset=<int>           Start scan at this file offset
    -O, --base=<int>             Add a base address to all printed offsets
    -K, --block=<int>            Set file block size
    -g, --swap=<int>             Reverse every n bytes before scanning
    -f, --log=<file>             Log results to file
    -c, --csv                    Log results to file in CSV format
    -t, --term                   Format output to fit the terminal window
    -q, --quiet                  Suppress output to stdout
    -v, --verbose                Enable verbose output
    -h, --help                   Show help output
    -a, --finclude=<str>         Only scan files whose names match this regex
    -p, --fexclude=<str>         Do not scan files whose names match this regex
    -s, --status=<int>           Enable the status server on the specified port

5 実行ファイルのシグネチャを調べる方法

テスト用のソースファイルを作成します。

[root@server ~]# vi tp.c
[root@server ~]# cat tp.c
#include <stdio.h>

int main()
{
    printf("Hello\n");
    return 0;
}

ソースファイルをコンパイルします。

[root@server ~]# gcc -Wall -o tp tp.c

シグネチャを確認します。ELFファイルであることがわかります。

[root@server ~]# binwalk -B tp

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)

なお、シグネチャを確認するだけなら、fileコマンドでもできます。

[root@server ~]# file tp
tp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=661aae172177fbc4b72f2ccf0a2afe080659c722, not stripped

6 圧縮ファイルのシグネチャを調べる方法

テスト用のファイルを作成します。

[root@server ~]# fallocate -l 1M test.dat

テスト用のファイルを圧縮します。

[root@server ~]# gzip test.dat

圧縮したファイルを確認します。

[root@server ~]# ls -l test.dat.gz
-rw-r--r--. 1 root root 3809  5月  9 21:20 test.dat.gz

シグネチャを確認します。gzipで圧縮したファイルであることがわかります。

[root@server ~]# binwalk -B test.dat.gz

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             gzip compressed data, has original file name: "test.dat", from Unix, last modified: 2022-05-09 12:20:03

7 アーカイブファイルのシグネチャを調べる方法

テスト用のファイルを作成します。

[root@server ~]# touch a
[root@server ~]# touch b

作成したファイルのアーカイブファイルを作成します。

[root@server ~]# tar cvf test.tar a b
a
b

アーカイブファイルを確認します。

[root@server ~]# ls -l test.tar
-rw-r--r--. 1 root root 10240  5月  9 21:22 test.tar

シグネチャを確認します。tarでアーカイブしたファイルであることがわかります。

[root@server ~]# binwalk -B test.tar

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             POSIX tar archive (GNU)

8 ファイルの中にファイルが存在する場合のシグネチャを調べる方法

ddコマンドの使い方で作成したファイル(test.dat)のシグネチャを調べてみます。確認するファイルの構造は、以下のようになっています。zero.datは0で埋まったバイナリファイル、tpはgccコンパイルした実行ファイル、ls.dat.gzはgzipで圧縮したファイルです。なお、ddコマンドは、ddコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

     test.dat
+----------------+ -*-            -*-         -*-
|                |  |              |           |
|    zero.dat    | 1024(byte)      |           |
|                |  |              |           |
+----------------+ -*-           9416(byte)    |
|                |  |              |           |
|       tp       | 8392(byte)      |           |
|                |  |              |           |
+----------------+ -*-            -*-        9579(byte)
|                |  |                          |
|   ls.dat.gz    | 163(byte)                   |
|                |  |                          |
+----------------+ -*-                        --*-

binwalkコマンドを実行すると、1024バイト目に実行ファイル、9416バイト目に圧縮ファイルが存在することがわかります。

[root@server test]# binwalk -B test.dat

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1024          0x400           ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)
9416          0x24C8          gzip compressed data, has original file name: "ls.dat", from Unix, last modified: 2022-05-09 11:49:38

9 ファイルを抽出する方法

ここでは、8章で作成したtest.datに含まれているファイルを抽出してみます。rootユーザで実行すると、下記警告文が表示されます。rootで実行するのは安全ではいようです。試されるかたは、一般ユーザを作成して、試した方が良いと思います。私はrootで試してみました。

[root@server test]# binwalk -D='.*' test.dat

Extractor Exception: Binwalk extraction uses many third party utilities, which may not be secure. If you wish to have extraction utilities executed as the current user, use '--run-as=root' (binwalk itself must be run as root).
-snip-

私は、警告文中の指示通り"--run-as=root"オプションを付けてrootユーザでファイルを抽出してみました。

[root@server test]# binwalk --run-as=root -D='.*' test.dat

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1024          0x400           ELF, 64-bit LSB executable, AMD x86-64, version 1 (SYSV)
9416          0x24C8          gzip compressed data, has original file name: "ls.dat", from Unix, last modified: 2022-05-09 11:49:38

ファイル抽出後のディレクトリを確認します。_test.dat.extractedディレクトリに抽出したファイルが格納されています。

[root@server test]# ls -lF
合計 12
drwxr-xr-x. 2 root root   48  5月  9 21:51 _test.dat.extracted/
-rw-r--r--. 1 root root 9579  5月  9 21:07 test.dat

_test.dat.extractedディレクトリ配下のファイルを確認してみます。

[root@server _test.dat.extracted]# ls -l
合計 20
-rw-r--r--. 1 root root 8555  5月  9 21:51 400
-rw-r--r--. 1 root root  329  5月  9 21:51 ls.dat
-rw-r--r--. 1 root root  163  5月  9 21:51 ls.dat.gz

400という名前のファイルをfileコマンドで確認してみます。ELFファイルであることがわかります。

[root@server _test.dat.extracted]# file 400
400: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=661aae172177fbc4b72f2ccf0a2afe080659c722, not stripped

ファイル400に実行権を付けます。

[root@server _test.dat.extracted]# chmod 744 400
[root@server _test.dat.extracted]# ls -l 400
-rwxr--r--. 1 root root 8555  5月  9 21:51 400

ファイルを実行してみます。”Hello"と表示されたことから、実行ファイル(tp)であることがわかります。

[root@server _test.dat.extracted]# ./400
Hello

次にfileコマンドを使ってls.dat.gzのファイルタイプを確認します。gzipファイルであることがわかります。

[root@server _test.dat.extracted]# file ls.dat.gz
ls.dat.gz: gzip compressed data, was "ls.dat", from Unix, last modified: Mon May  9 20:49:38 2022

ls.dat.gzの中身を確認してみます。

[root@server _test.dat.extracted]# zcat ls.dat.gz
System.map-3.10.0-1160.el7.x86_64
config-3.10.0-1160.el7.x86_64
efi
grub
grub2
initramfs-0-rescue-cc95d5e11b57492fa2f013c560b342a5.img
initramfs-3.10.0-1160.el7.x86_64.img
initramfs-3.10.0-1160.el7.x86_64kdump.img
symvers-3.10.0-1160.el7.x86_64.gz
vmlinuz-0-rescue-cc95d5e11b57492fa2f013c560b342a5
vmlinuz-3.10.0-1160.el7.x86_64

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ