Linux 基础与命令行:CTF 选手的第一把刀
说实话,很多刚接触 CTF 的朋友,一上来就急着学漏洞利用、学 shellcode。但我得泼盆冷水——Linux 命令行都玩不溜,后面寸步难行。Pwn 和逆向工程,说白了就是在 Linux 环境下跟二进制文件打交道。你连文件长啥样都看不明白,怎么去分析它、攻击它?
这一章,我带你把最核心的 Linux 基础过一遍。别嫌简单,这些都是我每天在用的东西。
为什么 CTF 选手必须懂 Linux?
CTF 的 Pwn 题目,99% 跑在 Linux 上。逆向工程分析的 ELF 文件,也是 Linux 的可执行格式。你想想看,比赛时拿到一个 binary,连 file 命令都忘了怎么用,那多尴尬。
我个人习惯,把 Linux 基础分成三个板块:
- 文件操作:找文件、看文件、分析文件
- 文件分析:识别文件类型、提取字符串、查看结构
- 权限与进程:理解谁在运行、谁能访问
下面我们一个一个来啃。
常用命令行操作:你的瑞士军刀
ls — 看看目录里有什么
ls 是我用得最多的命令,没有之一。但很多人只会 ls -l,这不够。
ls -la # 显示所有文件(包括隐藏文件)的详细信息
ls -lh # 文件大小以人类可读方式显示(K、M、G)
ls -lt # 按修改时间排序,最新的在最上面
ls -la 看一眼。有时候 flag 文件就藏在隐藏文件里,或者有个叫 .flag 的文件,你不加 -a 根本看不见。
cd — 在目录间跳来跳去
这个太基础了,但有个坑我得提醒你。
cd /home/user/challenge # 绝对路径
cd challenge # 相对路径(当前目录下)
cd .. # 返回上级目录
cd - # 回到上一个目录
cd 到一个不存在的目录,然后 ./run 执行了错误的程序,浪费了 20 分钟。嗯,每次 cd 之后,养成习惯 pwd 确认一下当前位置。
cat — 看文件内容
看小文件用 cat,看大文件用 less 或 head。
cat flag.txt # 直接输出文件内容
cat -n flag.txt # 显示行号
head -20 flag.txt # 只看前 20 行
tail -10 flag.txt # 只看最后 10 行
逆向分析时,我经常用 cat 配合管道看汇编代码的片段,但别用它看大文件——终端会卡死。
文件分析三板斧:file、strings、objdump
拿到一个未知文件,我有一套固定的分析流程。这套流程帮我解决过无数 CTF 题目。
file — 识别文件类型
别靠后缀名猜文件类型。Linux 下文件后缀就是个摆设。
$ file challenge
challenge: ELF 64-bit LSB executable, x86-64, version 1 (SYSV)
看到 ELF 就知道这是 Linux 可执行文件。64-bit 说明是 64 位程序。LSB 是小端序(Little Endian),x86 架构基本都是这个。
关键点:file 命令能告诉你文件是 ELF、PE、shell script、还是纯文本。CTF 里经常有人把 flag 藏在各种奇怪格式的文件里,file 一眼就能看穿。
strings — 提取可打印字符串
这个命令在逆向和 Pwn 里太常用了。它能从二进制文件中提取出所有可打印的字符序列。
$ strings challenge | head -20
/lib64/ld-linux-x86-64.so.2
libc.so.6
puts
printf
system
/bin/sh
flag{this_is_a_test_flag}
看到了吗?有时候 flag 就直接硬编码在二进制文件里。strings 一下就出来了。
strings -n 10 challenge 只显示长度 >= 10 的字符串,可以过滤掉大量无意义的短字符串。我在分析恶意软件时经常这么干。
objdump — 反汇编与查看结构
objdump 是逆向工程的核心工具之一。它能反汇编、查看节区、查看符号表。
objdump -d challenge # 反汇编代码段
objdump -t challenge # 查看符号表
objdump -x challenge # 查看所有头部信息
举个例子,反汇编一个简单的函数:
$ objdump -d challenge | grep -A 20 "<main>:"
0000000000401136 <main>:
401136: 55 push %rbp
401137: 48 89 e5 mov %rsp,%rbp
40113a: bf 01 00 00 00 mov $0x1,%edi
40113f: e8 ec fe ff ff callq 401030 <sleep@plt>
401144: b8 00 00 00 00 mov $0x0,%eax
401149: 5d pop %rbp
40114a: c3 retq
这段代码调用了 sleep(1),然后返回 0。你看,反汇编并不神秘。
readelf — 深入 ELF 文件结构
readelf 比 objdump 更专注于 ELF 结构本身。我一般在需要查看节区表、程序头表时用它。
readelf -h challenge # ELF 文件头
readelf -S challenge # 节区表
readelf -l challenge # 程序头表(段)
来看一个典型的 ELF 文件头:
$ readelf -h challenge
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Entry point address: 0x401060
Start of section headers: 12000 (bytes into file)
入口点地址 0x401060 就是程序开始执行的地方。Pwn 题里经常需要你修改这个地址,或者跳转到特定地址。
文件权限与进程管理
文件权限:rwx 到底什么意思?
Linux 里每个文件都有三组权限:所有者(owner)、所属组(group)、其他人(others)。每组权限用 rwx 表示。
| 符号 | 含义 | 数字表示 |
|---|---|---|
r |
读取权限 | 4 |
w |
写入权限 | 2 |
x |
执行权限 | 1 |
- |
无权限 | 0 |
举个例子:-rwxr-xr-- 表示所有者可读写执行,所属组可读执行,其他人只能读。
./challenge 报错 Permission denied。别慌,chmod +x challenge 加上执行权限就行。我曾经见过有人卡在这步半小时,以为是题目有问题。
chmod — 修改权限
chmod 755 challenge # rwxr-xr-x
chmod +x challenge # 给所有人加执行权限
chmod u+x challenge # 只给所有者加执行权限
数字法更常用:chmod 755 等于 rwxr-xr-x。7=4+2+1,5=4+1。
进程管理:看看谁在跑
Pwn 题经常需要你 attach 到进程上调试,或者查看进程的内存映射。
ps aux # 查看所有进程
ps -ef # 另一种格式
top # 实时进程监控
htop # 更友好的 top(需要安装)
调试时最常用的是 ps aux | grep challenge 找到进程 PID,然后用 GDB attach 上去。
$ ./challenge &
[1] 12345
$ ps aux | grep challenge
user 12345 0.0 0.1 12345 6789 pts/0 S 10:00 0:00 ./challenge
PID 是 12345,然后 gdb -p 12345 就能调试了。
知识体系总览
我把这一章的核心知识点画成了一张图,方便你对照着学:
实战演练:分析一个 CTF 题目
光说不练假把式。我们模拟一个真实场景:你拿到一个叫 challenge 的文件,不知道它是什么。
- 第一步:识别文件类型
嗯,是个 64 位 ELF 可执行文件。$ file challenge challenge: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2 - 第二步:提取字符串
有时候就这么简单,flag 直接暴露了。$ strings challenge | grep -i flag flag{you_found_me} - 第三步:查看入口点
入口点在$ readelf -h challenge | grep Entry Entry point address: 0x4005c00x4005c0,后面调试时用得着。 - 第四步:反汇编 main 函数
看看程序逻辑,找漏洞点。$ objdump -d challenge | grep -A 30 "<main>:"
记住这个流程:file → strings → readelf → objdump。这是我处理每个 CTF 二进制题目的标准开场。熟练了之后,五分钟就能摸清一个题目的底细。
避坑指南
我带过不少学生,发现几个常见的坑,这里列出来:
- 权限问题:下载的题目经常没有执行权限,记得
chmod +x。 - 路径问题:用相对路径时,确认当前目录对不对。
pwd是你的好朋友。 - strings 输出太多:加
-n 10过滤短字符串,或者用grep搜索关键词。 - objdump 输出太长:用
grep -A 20 "<function_name>:"只看特定函数。
-a 参数,漏掉了隐藏目录里的 flag 文件。找了半小时才发现。从那以后,ls -la 成了我的肌肉记忆。
好了,这一章的内容就到这里。Linux 命令行是 CTF 的基础,也是你未来所有二进制分析工作的起点。把这些命令练熟,后面的路会顺畅很多。