简介
在这个实验中,你将学习如何使用 Linux 的 strings
命令从二进制文件(包括可执行文件、库文件和其他二进制数据)中提取可打印的字符串。你将探究 strings
命令的用途和用法,学习如何从压缩和加密文件中提取字符串,并了解在日常工作中应用该命令的实际示例。本实验将让你全面了解 strings
命令及其应用,使你能够在 Linux 系统上有效地分析和排查二进制文件的问题。
在这个实验中,你将学习如何使用 Linux 的 strings
命令从二进制文件(包括可执行文件、库文件和其他二进制数据)中提取可打印的字符串。你将探究 strings
命令的用途和用法,学习如何从压缩和加密文件中提取字符串,并了解在日常工作中应用该命令的实际示例。本实验将让你全面了解 strings
命令及其应用,使你能够在 Linux 系统上有效地分析和排查二进制文件的问题。
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 个或更多可打印字符组成、并以换行符或空字符结尾的字符串序列。这使得该命令在以下方面非常有用:
让我们尝试一个更具体的示例。你可以将 grep
命令与 strings
命令结合使用,以查找特定类型的信息。例如,要在 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
另一个有用的选项是 -t
,它会显示每个字符串在文件中的偏移量:
strings -t x /bin/ls | head -10
输出会包含十六进制的偏移量:
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
shell 可能引用的所有环境变量。
你还可以使用 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
当你需要在不运行程序的情况下快速检查其版本时,这尤其有用。
让我们创建一个既包含二进制数据又包含文本字符串的简单二进制文件:
## Create a file with some text and binary data
echo "This is a visible string in our test file." > testfile.bin
echo "Another string that should be extractable." >> testfile.bin
## Add some binary data
dd if=/dev/urandom bs=100 count=1 >> testfile.bin 2> /dev/null
## Add one more text string
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
如何处理压缩内容:
首先,让我们创建一个包含多行内容的简单文本文件:
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
能提取出什么内容:
## Create a file with a secret message
echo "This is a top secret message that should be encrypted." > secret.txt
## Encrypt the file using OpenSSL
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc -k "password123" -pbkdf2
现在,让我们使用 strings
检查加密文件:
strings secret.enc
你可能会看到类似如下的输出:
Salted__
正如预期的那样,你看不到原始消息,因为它已被正确加密。唯一可读的文本是 OpenSSL 添加到加密文件开头的 "Salted__" 头部,用于表明在加密过程中使用了盐值。
系统管理员通常会压缩日志文件以节省空间。让我们模拟一个日志文件,并在压缩后对其进行检查:
## Create a simulated log file
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
## Compress the log file
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
命令在二进制文件中查找硬编码的凭证:
## Create a sample program with "credentials"
cat > credentials_example.c << EOF
#include <stdio.h>
int main() {
char* username = "admin";
char* password = "supersecret123";
printf("Connecting with credentials...\n");
return 0;
}
EOF
## Compile the program
gcc credentials_example.c -o credentials_example
现在,让我们搜索潜在的密码:
strings credentials_example | grep -i 'password\|secret\|admin\|user\|login'
这可能会输出:
admin
supersecret123
password
这展示了安全审计人员如何识别应用程序中潜在的硬编码凭证。
当文件扩展名缺失或具有误导性时,strings
命令可以帮助识别文件类型:
## Create a PNG file without the correct extension
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
选项允许你查看文件中每个字符串的偏移量,这对于更详细的分析非常有价值:
## Create a sample binary file
cat > offset_example.bin << EOF
This is at the beginning of the file.
EOF
## Add some binary data
dd if=/dev/urandom bs=100 count=1 >> offset_example.bin 2> /dev/null
## Add another string
echo "This is in the middle of the file." >> offset_example.bin
## Add more binary data
dd if=/dev/urandom bs=100 count=1 >> offset_example.bin 2> /dev/null
## Add a final string
echo "This is at the end of the file." >> offset_example.bin
现在,让我们使用带有 -t
选项的 strings
命令来查看偏移量:
strings -t d offset_example.bin
-t d
选项显示十进制偏移量。你的输出可能如下所示:
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.
这些信息对于定位二进制文件中字符串的精确位置非常有用,这对于二进制补丁或详细的文件分析等任务至关重要。
网络数据包通常包含二进制数据和可读文本。让我们模拟一个捕获的网络数据包并对其进行分析:
## Create a simulated network packet with HTTP data
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
## Add some binary header and footer to simulate packet framing
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
## Combine them into a complete "packet"
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
命令在高级应用中的多功能性:
strings
与 grep
结合使用以搜索特定模式strings
识别文件类型这些技术对于需要在不使用专业工具的情况下分析二进制数据的系统管理员、安全专业人员和软件开发人员来说非常有价值。
在本次实验中,你探索了 Linux 的 strings
命令,并学习了如何使用它从二进制文件中提取可读文本。本次实验涵盖的要点包括:
strings
命令的目的是从二进制文件中提取人类可读的字符序列,这对于检查可执行文件、库和其他非文本文件非常有用。strings
命令的基本用法,包括使用 -n
选项指定字符串的最小长度,以及使用 -t
选项显示文件偏移量。strings
命令在分析不同类型二进制文件中的应用,包括系统库和应用程序可执行文件。strings
如何从压缩文件中提取信息,而加密文件通常只能显示极少的信息。strings
与 grep
等其他命令结合使用以进行有针对性的分析、识别文件类型以及检查网络流量。你在本次实验中学到的技能对于系统管理、软件开发、安全审计和数字取证都非常有价值。strings
命令提供了一种简单而强大的方法,无需专业工具就能查看二进制文件的内容,使其成为 Linux 管理员工具包中的必备实用工具。