実用例付き Linux strings コマンド

LinuxLinuxBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Linux の strings コマンドを使用して、実行ファイル、ライブラリ、その他のバイナリデータを含むバイナリファイルから印刷可能な文字列を抽出する方法を学びます。strings コマンドの目的と使い方を調べ、圧縮ファイルや暗号化ファイルから文字列を抽出する方法を学び、このコマンドを日常業務でどのように適用するかの実用的な例を見つけます。この実験では、strings コマンドとそのアプリケーションについて包括的な理解を提供し、Linux システム上のバイナリファイルを効果的に分析してトラブルシューティングできるようにします。

Linux コマンドチートシート


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicSystemCommandsGroup(["Basic System Commands"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) linux(("Linux")) -.-> linux/TextProcessingGroup(["Text Processing"]) linux(("Linux")) -.-> linux/SystemInformationandMonitoringGroup(["System Information and Monitoring"]) linux(("Linux")) -.-> linux/CompressionandArchivingGroup(["Compression and Archiving"]) linux(("Linux")) -.-> linux/PackagesandSoftwaresGroup(["Packages and Softwares"]) linux/BasicSystemCommandsGroup -.-> linux/echo("Text Display") linux/BasicFileOperationsGroup -.-> linux/ls("Content Listing") linux/BasicFileOperationsGroup -.-> linux/cat("File Concatenating") linux/FileandDirectoryManagementGroup -.-> linux/cd("Directory Changing") linux/TextProcessingGroup -.-> linux/grep("Pattern Searching") linux/SystemInformationandMonitoringGroup -.-> linux/dd("File Converting/Copying") linux/CompressionandArchivingGroup -.-> linux/gzip("Gzip") linux/PackagesandSoftwaresGroup -.-> linux/openssl("OpenSSL") subgraph Lab Skills linux/echo -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/ls -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/cat -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/cd -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/grep -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/dd -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/gzip -.-> lab-422934{{"実用例付き Linux strings コマンド"}} linux/openssl -.-> lab-422934{{"実用例付き Linux strings コマンド"}} end

strings コマンドの目的と基本的な使い方を理解する

Linux の strings コマンドは、バイナリファイルから人間が読めるテキスト文字列を抽出するユーティリティです。実行プログラムやライブラリなどのバイナリファイルには、マシンコードとテキストデータの両方が含まれています。マシンコードは人間が読めないものの、テキストデータにはエラーメッセージ、設定情報、埋め込まれたドキュメントなどの貴重な情報が含まれることが多いです。

まず、この実験に適したディレクトリにいることを確認しましょう。

cd ~/project/strings_lab

では、一般的なバイナリファイルである ls コマンドの内容を調べることで、strings コマンドの基本的な使い方を探ってみましょう。

strings /bin/ls | head -20

このコマンドは、ls バイナリから最初の 20 個の読み取り可能な文字列を抽出します。以下のような出力が表示されるはずです。

/lib64/ld-linux-x86-64.so.2
libc.so.6
__stack_chk_fail
__cxa_finalize
setlocale
bindtextdomain
textdomain
__gmon_start__
abort
__errno_location
textdomain
dcgettext
dcngettext
strcmp
error
opendir
fdopendir
dirfd
closedir
readdir

デフォルトでは、strings コマンドは改行文字またはヌル文字で終わる 4 文字以上の印刷可能な文字のシーケンスを表示します。これにより、以下の用途に役立ちます。

  1. 実行ファイルに埋め込まれたテキストを見つける
  2. ハードコードされたパスや設定を見つける
  3. 基本的なフォレンジック分析
  4. バイナリファイルのトラブルシューティング

もっと具体的な例を試してみましょう。strings と一緒に grep コマンドを使用して、特定の種類の情報を見つけることができます。たとえば、ls コマンド内の "error" への参照をすべて見つけるには、次のようにします。

strings /bin/ls | grep error

出力には以下のようなものが含まれるかもしれません。

error
strerror
strerror_r
__file_fprintf::write_error
error in %s
error %d

strings コマンドには、その動作をカスタマイズするためのいくつかの便利なオプションも用意されています。たとえば、表示する文字列の最小長を指定することができます。

strings -n 10 /bin/ls | head -10

このコマンドは、少なくとも 10 文字の長さの文字列のみを表示します。出力は次のようになるかもしれません。

/lib64/ld-linux-x86-64.so.2
__stack_chk_fail
__cxa_finalize
bindtextdomain
__gmon_start__
__errno_location
_ITM_registerTMCloneTable
_ITM_deregisterTMCloneTable
__cxa_atexit
__cxa_finalize

もう 1 つの便利なオプションは -t で、これはファイル内の各文字列のオフセットを表示します。

strings -t x /bin/ls | head -10

出力には 16 進数のオフセットが含まれます。

    238 /lib64/ld-linux-x86-64.so.2
    4ca __stack_chk_fail
    4dd __cxa_finalize
    4ec setlocale
    4f7 bindtextdomain
    507 textdomain
    512 __gmon_start__
    522 abort
    528 __errno_location
    539 textdomain

これらのオフセットは、バイナリファイルのより高度な分析に役立つことがあります。

strings を使ったさまざまな種類のバイナリファイルの分析

このステップでは、strings コマンドを使って、システムライブラリやアプリケーションのバイナリなど、さまざまな種類のバイナリファイルを分析する方法を学びます。さまざまなバイナリファイルからテキストを抽出する方法を理解することで、問題のトラブルシューティング、特定の情報の検索、さらには隠された機能の発見に役立ちます。

まず、まだ実験用のディレクトリにいることを確認しましょう。

cd ~/project/strings_lab

システムライブラリの調査

システムライブラリには、複数のプログラムで共有されるコードが含まれています。一般的なシステムライブラリである libc.so.6 を調べてみましょう。これは、Linux 上のほとんどのプログラムで使用される C 標準ライブラリです。

strings /lib/x86_64-linux-gnu/libc.so.6 | head -20

出力は次のようになるかもしれません。

GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3.4) stable release version 2.35.
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 11.4.0.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
/build/glibc-bBNzrH/glibc-2.35/elf/../sysdeps/x86_64/startup.c
7e
m3
.n
zN
?$
?G
G0
5')
5$)

ご覧のように、ライブラリの冒頭にはバージョン情報、著作権表示、その他の人間が読めるテキストが含まれています。この情報は、互換性の問題をトラブルシューティングしたり、ライブラリのバージョンを確認したりする際に役立ちます。

バイナリファイル内の特定の情報を見つける

プログラムで使用される可能性のあるすべての環境変数を見つけたいとしましょう。バイナリファイル内で "$" で始まる文字列を検索することができます。

strings /bin/bash | grep '^\$' | head -10

このコマンドの出力は次のようになるかもしれません。

$HOME
$PATH
$SHELL
$TERM
$USER
$HOSTNAME
$PWD
$MAIL
$LANG
$LC_ALL

これは、bash シェルが参照する可能性のあるすべての環境変数を示しています。

バージョン情報の分析

strings コマンドを使って、バイナリファイル内のバージョン情報を見つけることもできます。

strings /bin/bash | grep -i version

出力には次のようなものが含まれるかもしれません。

GNU bash, version %s (%s)
version
VERSION
version_string
dist_version
show_shell_version
BASH_VERSION
GNU bash, version %s-(%s)
@(#)version.c
version.c

これは、プログラムを実行せずにすぐにバージョンを確認する必要がある場合に特に便利です。

分析用の簡単なバイナリファイルの作成

バイナリデータとテキスト文字列の両方を含む簡単なバイナリファイルを作成してみましょう。

## テキストとバイナリデータを含むファイルを作成する
echo "This is a visible string in our test file." > testfile.bin
echo "Another string that should be extractable." >> testfile.bin
## いくつかのバイナリデータを追加する
dd if=/dev/urandom bs=100 count=1 >> testfile.bin 2> /dev/null
## もう 1 つのテキスト文字列を追加する
echo "Final string after some binary data." >> testfile.bin

では、strings コマンドを使ってこのバイナリファイルからテキストを抽出しましょう。

strings testfile.bin

出力にはすべてのテキスト文字列が含まれるはずです。

This is a visible string in our test file.
Another string that should be extractable.
Final string after some binary data.

これは、strings がバイナリデータと混在している場合でも、バイナリデータを効果的にフィルタリングして人間が読めるテキストのみを表示できることを示しています。

圧縮ファイルと暗号化ファイルの操作

このステップでは、圧縮ファイルと暗号化ファイルに対して strings コマンドを使用する方法を学びます。これらのファイルには多くの場合バイナリデータが含まれているため、strings コマンドはファイルを完全に解凍または復号せずに読み取り可能なテキストを抽出するのに役立ちます。

実験用のディレクトリにいることを確認しましょう。

cd ~/project/strings_lab

圧縮ファイルの分析

テキストファイルを作成し、異なる方法で圧縮して、strings が圧縮された内容をどのように扱うかを見てみましょう。

gzip 圧縮の使用

まず、複数行の簡単なテキストファイルを作成しましょう。

cat > sample_text.txt << EOF
This is a sample text file.
It contains multiple lines of text.
We will compress it in different ways.
Then we'll use the strings command to see what we can extract.
The strings command is useful for examining binary files.
EOF

では、このファイルを gzip を使って圧縮しましょう。

gzip -c sample_text.txt > sample_text.gz

-c オプションは、gzip に元のファイルを置き換える代わりに標準出力に書き込むよう指示します。では、strings を使って何が抽出できるか見てみましょう。

strings sample_text.gz

次のような出力が表示されるかもしれません。

sample_text.txt
This is a sample text file.
It contains multiple lines of text.
We will compress it in different ways.
Then we'll use the strings command to see what we can extract.
The strings command is useful for examining binary files.

ファイルが圧縮されているにもかかわらず、strings が元のテキスト内容を抽出できることに注意してください。これは、gzip がデータを暗号化するのではなく、圧縮するだけであり、多くの読み取り可能なテキストセグメントがそのまま残っているためです。

異なる圧縮形式の使用

別の圧縮方法である bzip2 を試してみましょう。

bzip2 -c sample_text.txt > sample_text.bz2

では、このファイルを strings で調べてみましょう。

strings sample_text.bz2

出力は gzip の場合よりも読みにくくなるかもしれません。

BZh91AY&SY
s1r
U*T)

これは、異なる圧縮アルゴリズムが異なるバイナリパターンを生成し、一部のアルゴリズムは他のアルゴリズムよりも読み取り可能なテキストセグメントを残す量が少ないためです。

暗号化ファイルの操作

暗号化は、適切な鍵がなければ内容を読めなくするために設計されています。暗号化ファイルを作成し、strings が何を抽出できるか見てみましょう。

## 秘密のメッセージを含むファイルを作成する
echo "This is a top secret message that should be encrypted." > secret.txt

## OpenSSL を使ってファイルを暗号化する
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc -k "password123" -pbkdf2

では、strings を使って暗号化ファイルを調べてみましょう。

strings secret.enc

次のような出力が表示されるかもしれません。

Salted__

予想通り、元のメッセージは適切に暗号化されているため見ることはできません。唯一読み取り可能なテキストは、OpenSSL が暗号化ファイルの先頭に追加する "Salted__" ヘッダーで、これは暗号化プロセスでソルトが使用されたことを示しています。

実用例: 圧縮されたログファイルの調査

システム管理者は、スペースを節約するためにログファイルを圧縮することがよくあります。ログファイルをシミュレートし、圧縮後に調べてみましょう。

## シミュレートされたログファイルを作成する
cat > system.log << EOF
[2023-10-25 08:00:01] INFO: System startup completed
[2023-10-25 08:05:22] WARNING: High memory usage detected
[2023-10-25 08:10:15] ERROR: Failed to connect to database
[2023-10-25 08:15:30] INFO: Database connection restored
[2023-10-25 08:20:45] WARNING: CPU temperature above threshold
EOF

## ログファイルを圧縮する
gzip -c system.log > system.log.gz

では、strings にいくつかの追加オプションを指定して、圧縮されたログファイルを調べてみましょう。

strings -n 20 system.log.gz

-n 20 オプションは、strings に 20 文字以上の印刷可能な文字のシーケンスのみを表示するよう指示します。出力には次のようなものが含まれるかもしれません。

[2023-10-25 08:00:01] INFO: System startup completed
[2023-10-25 08:05:22] WARNING: High memory usage detected
[2023-10-25 08:10:15] ERROR: Failed to connect to database
[2023-10-25 08:15:30] INFO: Database connection restored
[2023-10-25 08:20:45] WARNING: CPU temperature above threshold

これは、システム管理者が圧縮されたログファイルを最初に解凍することなく内容をすぐに確認できることを示しています。これは、大きなログアーカイブを扱う際に特に便利です。

strings コマンドの高度な使い方と実用例

この最後のステップでは、strings コマンドのいくつかの高度な使い方と実用例を探索します。これらのテクニックは、システム管理、ソフトウェア開発、デジタルフォレンジックスにおいて特に有用です。

まだ実験用のディレクトリにいることを確認しましょう。

cd ~/project/strings_lab

strings と他のコマンドの組み合わせ

strings コマンドを他の Linux コマンドと組み合わせると、その真の力が明らかになります。いくつかの便利な組み合わせを見てみましょう。

潜在的なハードコードされた資格情報の検索

セキュリティ監査員は、バイナリファイル内のハードコードされた資格情報を探すために strings をよく使用します。

## "資格情報" を含むサンプルプログラムを作成する
cat > credentials_example.c << EOF
#include <stdio.h>

int main() {
    char* username = "admin";
    char* password = "supersecret123";
    
    printf("Connecting with credentials...\n");
    return 0;
}
EOF

## プログラムをコンパイルする
gcc credentials_example.c -o credentials_example

では、潜在的なパスワードを検索しましょう。

strings credentials_example | grep -i 'password\|secret\|admin\|user\|login'

これにより、次のような出力が得られるかもしれません。

admin
supersecret123
password

これは、セキュリティ監査員がアプリケーション内の潜在的なハードコードされた資格情報を特定する方法を示しています。

ファイルタイプの分析

拡張子が欠落しているか誤解を招く場合、strings コマンドはファイルのタイプを特定するのに役立ちます。

## 正しい拡張子のない PNG ファイルを作成する
cp /usr/share/icons/Adwaita/16x16/places/folder.png mystery_file

では、strings を使ってファイルタイプに関する手がかりを探しましょう。

strings mystery_file | grep -i 'png\|jpeg\|gif\|image'

次のような出力が表示されるかもしれません。

PNG
IHDR
pHYs
iDOT

PNG 関連の文字列が含まれていることは、このファイルが適切な拡張子を持たないにもかかわらず、PNG 画像である可能性があることを示唆しています。

ファイルオフセットでの strings の使用

-t オプションを使用すると、ファイル内の各文字列のオフセットを確認でき、より詳細な分析に役立ちます。

## サンプルのバイナリファイルを作成する
cat > offset_example.bin << EOF
This is at the beginning of the file.
EOF

## いくつかのバイナリデータを追加する
dd if=/dev/urandom bs=100 count=1 >> offset_example.bin 2> /dev/null

## 別の文字列を追加する
echo "This is in the middle of the file." >> offset_example.bin

## さらにバイナリデータを追加する
dd if=/dev/urandom bs=100 count=1 >> offset_example.bin 2> /dev/null

## 最後の文字列を追加する
echo "This is at the end of the file." >> offset_example.bin

では、-t オプションを指定して strings を使用し、オフセットを確認しましょう。

strings -t d offset_example.bin

-t d オプションは、10 進数のオフセットを表示します。出力は次のようになるかもしれません。

         0 This is at the beginning of the file.
       137 This is in the middle of the file.
       273 This is at the end of the file.

この情報は、バイナリファイル内の文字列の正確な位置を特定するのに役立ち、バイナリパッチングや詳細なファイル分析などのタスクに不可欠です。

ケーススタディ: ネットワークトラフィックの分析

ネットワークパケットには、バイナリデータと読み取り可能なテキストの両方が含まれることがよくあります。キャプチャされたネットワークパケットをシミュレートし、分析してみましょう。

## HTTP データを含むシミュレートされたネットワークパケットを作成する
cat > http_packet.bin << EOF
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml
EOF

## パケットフレーミングをシミュレートするために、いくつかのバイナリヘッダーとフッターを追加する
dd if=/dev/urandom bs=20 count=1 > packet_header.bin 2> /dev/null
dd if=/dev/urandom bs=20 count=1 > packet_footer.bin 2> /dev/null

## これらを結合して完全な "パケット" にする
cat packet_header.bin http_packet.bin packet_footer.bin > captured_packet.bin

では、この "キャプチャされたパケット" を strings で分析しましょう。

strings captured_packet.bin

出力には HTTP リクエストが含まれるはずです。

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml

これは、ネットワークアナリストが、バイナリプロトコルデータと混在している場合でも、キャプチャされたネットワークトラフィックから有用な情報をすぐに抽出できることを示しています。

高度な使い方のまとめ

このステップで学んだテクニックは、高度なアプリケーションにおける strings コマンドの汎用性を示しています。

  1. stringsgrep を組み合わせて特定のパターンを検索する
  2. strings を使ってファイルタイプを特定する
  3. 正確なバイナリ分析のためにファイルオフセットを使用する
  4. ネットワークパケットのような混合バイナリコンテンツから読み取り可能なデータを抽出する

これらのテクニックは、特殊なツールを使用せずにバイナリデータを分析する必要があるシステム管理者、セキュリティ専門家、ソフトウェア開発者にとって価値があります。

まとめ

この実験では、Linux の strings コマンドを探索し、バイナリファイルから読み取り可能なテキストを抽出する方法を学びました。この実験でカバーされた重要なポイントは以下の通りです。

  1. strings コマンドの目的は、バイナリファイルから人間が読める文字シーケンスを抽出することです。これは、実行ファイル、ライブラリ、その他の非テキストファイルを調査するのに役立ちます。

  2. strings コマンドの基本的な使い方。これには、最小文字列長を指定する -n や、ファイルオフセットを表示する -t などのオプションが含まれます。

  3. strings コマンドを使用して、システムライブラリやアプリケーション実行ファイルなど、さまざまなタイプのバイナリファイルを分析する方法。

  4. 圧縮ファイルと暗号化ファイルを扱うテクニック。strings が圧縮ファイルから情報を抽出できる一方で、暗号化ファイルからは通常最小限の情報しか明らかにされないことを示しています。

  5. 高度な使い方。grep などの他のコマンドと strings を組み合わせてターゲット分析を行う方法、ファイルタイプを特定する方法、ネットワークトラフィックを調査する方法などが含まれます。

この実験で学んだスキルは、システム管理、ソフトウェア開発、セキュリティ監査、デジタルフォレンジックスにおいて価値があります。strings コマンドは、特殊なツールを使用せずにバイナリファイルの中身を簡単に調べる強力な方法を提供するため、Linux 管理者のツールキットに欠かせないユーティリティです。

Linux コマンドチートシート