主题
第 8 章 逆向与安全:把黑盒拆开看
预计阅读 20 分钟 · 全文约 5,736 字
本章产出:一份漏洞实战报告、一次 REA 拆解记录,以及一套"能从黑盒里读出逻辑"的方法。
开场:黑盒里到底有什么
你手机里装了一个 App,点了"激活会员",它弹出一行字:"请输入卡密"。
你输入一串乱七八糟的字符,它说"卡密无效"。
你好奇:它怎么知道无效的?它凭什么判断?这个判断逻辑藏在哪?
再比如,你打开一个网页,登录框输错密码,它提示"密码错误"。你想知道:这个判断是在浏览器里做的,还是在服务器上做的?
这两个问题,就是逆向工程和安全研究的起点:当一个东西不给你源码,你怎么知道它内部是怎么运转的。
这一章,人家带你进这个门。先讲清楚"拆"的两种基本手法,再带你走一遍真实流程,最后让你亲手在一个靶场里打出漏洞。
8.1 逆向是什么:从汇编到伪代码
一句话
逆向工程 = 没有源码,从程序的"成品"反推它的"设计图"。
正常开发是:写源码 → 编译 → 得到程序。
逆向是反过来:拿到程序 → 反编译 → 猜出源码逻辑。
为什么需要逆向
- 安全研究:找漏洞、分析恶意软件
- 兼容性:让新系统能跑老程序、读老格式
- 学习:看别人怎么实现的(比如某个算法、某个协议)
- 维护:源码丢了,只能从程序反推
- CTF 比赛:逆向题就是干这个
程序是怎么变成"机器码"的
以 C 语言为例:
c
int add(int a, int b) {
return a + b;
}编译后变成机器码(十六进制):
55 48 89 e5 89 7d fc 89 75 f8 8b 45 fc 03 45 f8 5d c3CPU 只认这些字节。人看不懂。
反汇编:把机器码翻译成汇编语言(人类能读的助记符):
asm
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov eax, DWORD PTR [rbp-4]
add eax, DWORD PTR [rbp-8]
pop rbp
ret反编译:把汇编进一步翻译成类 C 的"伪代码":
c
int add(int a, int b) {
return a + b;
}注意:反编译出来的叫"伪代码",不是原始源码。变量名、注释、结构都会丢失,只能还原"逻辑",还原不了"原文"。
图 8-1:机器码 → 汇编 → 伪代码
三种层次的产物
| 层次 | 产物 | 可读性 | 信息量 |
|---|---|---|---|
| 机器码 | 十六进制字节 | 几乎不可读 | 完整 |
| 汇编 | 助记符指令 | 难读,但精确 | 完整 |
| 伪代码 | 类 C 代码 | 较好读 | 有损(变量名丢失等) |
逆向的日常:先看伪代码理解逻辑,卡住了再看汇编确认细节。
逆向需要的基础
- 汇编基础:知道寄存器、栈、跳转、调用约定
- C 语言:看得懂指针、结构体、内存布局
- 操作系统:进程、内存、文件格式(PE/ELF)
- 耐心:逆向是体力活,一个函数一个函数啃
没有这些基础也能入门,但要往深走,绕不开。
8.2 静态分析 vs 动态调试
两种基本手法
静态分析:不运行程序,直接看它的代码/文件结构。
动态调试:把程序跑起来,边跑边看它的状态(寄存器、内存、调用栈)。
类比:
- 静态分析 = 拆开汽车看图纸和零件
- 动态调试 = 开着车,边开边看仪表盘和引擎
静态分析的工具
| 工具 | 用途 |
|---|---|
| IDA Pro | 业界标准反汇编器(收费,贵) |
| Ghidra | NSA 开源的反汇编器(免费,功能强) |
| Hopper | macOS 上的反汇编器(收费) |
| JADX | Android APK 反编译(免费) |
| dnSpy / ILSpy | .NET 程序反编译 |
| strings | 提取程序里的字符串(最快的第一步) |
| file / binwalk | 识别文件类型、找嵌入内容 |
动态调试的工具
| 工具 | 用途 |
|---|---|
| x64dbg | Windows 用户态调试器(免费) |
| OllyDbg | 老牌 Windows 调试器 |
| GDB | Linux 调试器(命令行) |
| WinDbg | Windows 内核调试 |
| Frida | 动态插桩(Hook 函数、改参数) |
| Wireshark | 抓网络包 |
什么时候用哪个
先静态,后动态。
- 静态分析能快速看清"整体结构":有哪些函数、调用了什么 API、有哪些字符串
- 动态调试用来"验证猜想":你觉得这个函数是验证卡密的,跑起来断点看看它到底收到了什么
实战流程:
1. strings 扫一遍,看有没有线索(URL、错误提示、密钥)
2. 拖进 Ghidra/IDA,看函数列表
3. 找关键函数(验证、解密、网络请求)
4. 看伪代码,理解逻辑
5. 有疑问 → 动态调试,断点验证
6. 得出结论一个真实的小例子
假设你拿到一个程序,输入卡密它说"无效"。
第一步:strings 程序.exe | grep -i "invalid"
找到字符串:"Invalid license key"
第二步:在 Ghidra 里搜这个字符串,找到引用它的函数。
第三步:看伪代码:
c
if (strcmp(user_input, "ABC-123-XYZ") == 0) {
printf("License activated!\n");
} else {
printf("Invalid license key\n");
}结论:卡密是硬编码的,直接输 ABC-123-XYZ 就能过。
这就是最简单的逆向:找到验证逻辑,读出答案。
8.3 REA 实战:用 AI 拆一个 JS/Electron 应用
REA 是什么
REA(Reverse Engineer Anything)= 把逆向工具接给 AI 的 MCP 工具集。
它不替代 Ghidra/IDA,它是"让 AI 能调用这些工具"的中间层。你问 AI"这个功能怎么实现的",AI 通过 REA 去反汇编、读伪代码,然后用人话告诉你。
为什么从 JS/Electron 开始
- 不需要买 IDA:JS 是文本,静态分析免费
- 结构清晰:Electron 应用就是一堆 JS 文件 + 资源
- 容易看到效果:拆完能直接读懂逻辑
环境准备
bash
# 1. 装 Node.js(18+)
node -v
# 2. 装 REA
npm install -g rea-agents
# 3. 验证
rea --help拆一个 Electron 应用
Electron 应用的结构:
app/
├── resources/
│ └── app.asar ← 打包后的 JS 代码
├── app.exe
└── ...第一步:解包 asar
bash
# 装 asar 工具
npm install -g @electron/asar
# 解包
asar extract app.asar app_unpacked/解包后你会看到:
app_unpacked/
├── package.json
├── main.js ← 主进程
├── preload.js ← 预加载脚本
└── renderer/ ← 渲染进程(前端代码)第二步:用 REA 分析
bash
rea analyze-javascript-application /path/to/app_unpacked --json它会输出:模块结构、import 关系、Electron 边界(主进程/渲染进程通信点)。
第三步:让 AI 帮你读
把分析结果或者关键文件贴给 AI,问:
这是一个 Electron 应用的 main.js。
帮我分析:
1. 它启动时做了哪些事
2. 它有没有联网请求,请求到哪个地址
3. 它的授权验证逻辑在哪AI 会逐段解释,告诉你关键逻辑在哪几行。
一个实战思路:找授权验证
Electron 应用的授权验证通常在这几个地方:
- main.js 里的启动检查:启动时验证 license
- preload.js:暴露给渲染进程的 API
- 网络请求:向服务器验证
- 本地文件:读 license 文件
搜关键词:
bash
grep -r "license\|activate\|verify\|trial" app_unpacked/找到相关代码,再看逻辑。
三种验证模式(重要)
模式一:本地硬编码
js
if (key === "ABC-123") { activate(); }特征:密钥直接在代码里。这种最容易被破——搜字符串就能找到。
模式二:本地算法验证
js
function checkKey(key) {
const hash = md5(key + "secret_salt");
return hash === "a1b2c3d4...";
}特征:代码里有算法和盐值。可以逆推出注册机——把算法抄出来,自己生成合法 key。
模式三:服务器验证
js
const res = await fetch("https://api.example.com/verify", {
method: "POST",
body: JSON.stringify({ key })
});
if (res.ok) { activate(); }特征:验证在服务器上。本地改不了——你改客户端,服务器不认。只能:伪造服务器响应(改 hosts/抓包)、或者攻击服务器(另一回事)。
记住这个分类:它决定了"能不能破、怎么破"。
8.4 卡密与授权原理:为什么"破解卡密"大多不成立
卡密的本质
卡密 = 一串字符,证明你付过钱。
它有两种验证方式,对应上一节的模式二和模式三。
本地验证的卡密(可破)
结构:
卡密 = 用户ID + 签名
签名 = 算法(用户ID + 密钥)验证时,程序重新算一遍签名,对比是否一致。
破解方法:
- 逆向出算法和密钥
- 写一个"注册机"(keygen),输入用户ID,输出合法卡密
- 或者直接打补丁,跳过验证函数
这就是网上说的"逆向破解卡密"——针对的是本地验证的软件。
服务器验证的卡密(本地破不了)
结构:
用户输入卡密 → 客户端发给服务器 → 服务器查数据库 → 返回结果特征:
- 客户端里没有验证算法
- 卡密有效性存在服务器数据库
- 每次验证都要联网
本地能做的:
- 抓包看请求格式
- 改客户端让它"显示已激活"(但服务端功能还是不给你)
- 伪造服务器响应(需要改 hosts 或中间人,且只能骗过客户端显示)
做不到的:让服务器认可一个不存在的卡密。
为什么"AI 服务破解卡密白嫖 token"不成立
AI 服务的 token 是服务器端计费的。
- 你的 API key 只是"身份标识"
- 每次请求,服务器扣你的额度
- 额度在服务器数据库里
你本地逆向客户端,改不了服务器的账本。
能白嫖的路径只有:
- 偷别人的 key(违法)
- 找服务端漏洞(那是攻击服务器,另一回事)
- 薅新用户免费额度(批量注册)
"逆向客户端 → 白嫖 token"这条路,技术上就是断的。
授权验证的常见实现
| 方式 | 安全性 | 破解难度 |
|---|---|---|
| 硬编码密钥 | 极低 | 搜字符串就行 |
| 本地算法 + 盐 | 低 | 逆出算法写注册机 |
| 本地算法 + 混淆 | 中 | 要脱壳、反混淆 |
| 服务器验证 | 高 | 要攻击服务器 |
| 服务器验证 + 硬件绑定 | 很高 | 要模拟硬件 |
| 在线验证 + 定期心跳 | 很高 | 要持续伪造 |
这个表告诉你:越是"联网验证 + 加密通信 + 硬件绑定",越难破。反过来,纯本地的、硬编码的,一碰就碎。
8.5 Web 安全基础:HTTP、抓包、请求伪造
先搞懂 HTTP
Web 的一切都是 HTTP 请求和响应。
请求:
http
GET /api/user?id=1 HTTP/1.1
Host: example.com
Cookie: session=abc123
User-Agent: Mozilla/5.0响应:
http
HTTP/1.1 200 OK
Content-Type: application/json
{"id":1,"name":"张三","email":"zhangsan@example.com"}关键点:
- 请求方法:GET(查)、POST(提交)、PUT(改)、DELETE(删)
- 请求头:Cookie(身份)、Authorization(令牌)、Content-Type(格式)
- 请求体:POST/PUT 的数据
- 响应码:200 成功、301 跳转、403 禁止、404 不存在、500 服务器错误
抓包:看浏览器和服务器在聊什么
工具:浏览器 F12(Network 面板)、Burp Suite、mitmproxy、Wireshark。
F12 能看什么:
- 每个请求的 URL、方法、头、体
- 每个响应的状态码、头、体
- 请求耗时、大小
为什么要抓包:因为前端看到的不一定是全部。有些逻辑在请求里,不在页面上。
请求伪造:改一改再发
抓到一个请求,你可以:
- 改参数(
id=1→id=2) - 改 Cookie(换别人的 session)
- 改请求头(伪装成管理员)
- 重放(同样的请求再发一次)
这就是很多漏洞的来源:服务器信任了客户端发来的数据。
一个经典例子:越权
正常请求:GET /api/order?id=1001 (查自己的订单)
篡改请求:GET /api/order?id=1002 (查别人的订单)如果服务器只检查"你登录了吗",不检查"这个订单是不是你的",就能看到别人的订单。
这叫水平越权(同级用户之间越界)。
还有垂直越权:普通用户访问管理员接口。
抓包实战流程
1. 打开 F12 → Network
2. 操作一遍正常流程(登录、下单、查询)
3. 找到关键请求
4. 右键 → Copy as cURL
5. 粘到终端,改参数,重发
6. 看响应有没有变化这个流程能发现大部分逻辑漏洞。
8.6 常见漏洞原理:SQLi / XSS / SSRF / 越权
SQL 注入(SQLi)
原理:用户输入被拼进 SQL 语句,改变了原语句的逻辑。
漏洞代码:
python
query = f"SELECT * FROM users WHERE name = '{username}'"输入 admin' OR '1'='1,语句变成:
sql
SELECT * FROM users WHERE name = 'admin' OR '1'='1'结果:返回所有用户。
危害:拖库、改数据、删表。
防御:参数化查询(预编译),永远不要拼接用户输入。
XSS(跨站脚本)
原理:用户输入被当成 HTML/JS 执行。
漏洞代码:
html
<div>欢迎,<?= $_GET['name'] ?></div>输入 <script>alert(1)</script>,脚本就执行了。
危害:盗 Cookie、钓鱼、篡改页面。
三种类型:
- 反射型:payload 在 URL 里,点链接才触发
- 存储型:payload 存进数据库,所有访问者都中招
- DOM 型:前端 JS 把不可信数据写进页面
防御:输出编码、CSP、HttpOnly Cookie。
SSRF(服务端请求伪造)
原理:服务器替你发请求,你让它去访问内网。
漏洞代码:
python
url = request.args.get('url')
response = requests.get(url) # 用户可控输入 http://169.254.169.254/latest/meta-data/(云服务器元数据接口),就能读到云主机的密钥。
危害:探测内网、读云元数据、攻击内网服务。
防御:白名单、禁止内网地址、DNS 重绑定防护。
越权
原理:只验证"登录了",不验证"有没有权限"。
两种:
- 水平越权:同级别用户互看数据(改 id)
- 垂直越权:低权限用户访问高权限功能(改角色)
防御:每个请求都校验"当前用户是否有权操作这个资源"。
其他常见漏洞
| 漏洞 | 一句话 |
|---|---|
| 文件上传 | 上传 webshell,拿到服务器权限 |
| 命令注入 | 输入拼进系统命令,执行任意命令 |
| 反序列化 | 恶意序列化数据触发代码执行 |
| 逻辑漏洞 | 业务流程设计缺陷(比如 0 元购) |
| 弱口令 | 密码太简单,被爆破 |
漏洞挖掘的基本思路
- 找输入点:所有用户能控制的地方(URL 参数、表单、Header、文件)
- 看它去哪:输入被拼进 SQL?HTML?命令?URL?
- 试 payload:根据去向,试对应的攻击串
- 看响应:报错、回显、延迟——都是信号
8.7 二进制安全入门:栈溢出与 ROP
为什么讲这个
因为它是"底层安全"的经典,理解了它,你才明白"内存安全"到底在防什么。
栈是什么
栈 = 程序运行时用来存"局部变量"和"返回地址"的内存区域。
函数调用时:
1. 把参数压栈
2. 把返回地址压栈(函数执行完要回到哪)
3. 跳转到函数
4. 函数里分配局部变量关键:返回地址就在栈上,紧挨着局部变量。
栈溢出
漏洞代码:
c
void vulnerable() {
char buffer[64];
gets(buffer); // 没有长度检查!
}输入超过 64 字节,就会覆盖栈上后面的内容——包括返回地址。
攻击思路:
输入 = [填充 64 字节] + [覆盖返回地址为 shellcode 地址] + [shellcode]程序返回时,跳到攻击者指定的地址,执行攻击者的代码。
现代防护
| 防护 | 作用 |
|---|---|
| 栈保护(Canary) | 在返回地址前放个随机值,被覆盖就报错 |
| NX(不可执行) | 栈上的数据不能当代码执行 |
| ASLR | 地址随机化,猜不到跳哪 |
| PIE | 程序基址随机化 |
ROP:绕过 NX 的方法
ROP(Return-Oriented Programming)= 用程序里现成的代码片段(gadget)拼出攻击链。
思路:既然栈不能执行代码,那就跳到程序里已有的指令片段,一段段拼起来,实现攻击者的目的。
这属于进阶内容,第 11 章会展开。这一节你只要理解:
- 栈溢出是"内存写越界"
- 现代防护让简单溢出不好使了
- 攻击者用 ROP 等技巧绕过防护
- 防御的核心是"不信任任何输入长度"
为什么普通人也要懂
因为"内存安全"是所有软件的基础。你用的浏览器、操作系统、数据库,都在防这类问题。理解了原理,你才知道为什么"更新补丁"这么重要。
8.8 CTF 靶场实战
什么是 CTF
CTF(Capture The Flag)= 网络安全竞赛,解题拿 flag。
题目分几类:
| 方向 | 考什么 |
|---|---|
| Web | 网站漏洞(SQLi、XSS、文件上传) |
| Pwn | 二进制漏洞利用(栈溢出、ROP) |
| Reverse | 逆向(反汇编、算法还原) |
| Crypto | 密码学(加解密、协议分析) |
| Misc | 杂项(隐写、流量分析、编码) |
新手靶场推荐
- DVWA:经典的 Web 漏洞练习平台,有 SQLi、XSS、文件上传等
- Pikachu:中文 Web 靶场,题目友好
- HackTheBox:在线靶场,难度分级
- TryHackMe:有引导的靶场,适合入门
- CTFHub:中文 CTF 练习平台
DVWA 实战:SQL 注入
环境:本地用 Docker 起一个 DVWA。
bash
docker run -d -p 8080:80 vulnerables/web-dvwa访问 http://localhost:8080,默认账号 admin / password。
步骤:
- 登录,把安全等级调到 Low
- 进 SQL Injection 页面
- 正常输入
1,看返回 - 输入
1' OR '1'='1,看是否返回所有用户 - 输入
1' UNION SELECT user,password FROM users-- -,看能否拖出账号密码 - 记录:payload、返回结果、原理
验收:能解释"为什么这个 payload 能生效"。
一个 CTF Web 题的标准解法
1. 看题目描述,找线索(提示了哪个漏洞类型)
2. 打开目标,看功能(登录框?搜索框?文件上传?)
3. 找输入点
4. 试 payload
5. 看回显/报错
6. 拿到 flag
7. 写 writeup(记录思路和步骤)写 writeup 是关键——不写,你只是"碰巧做出来了";写了,才是"真的会了"。
8.9 完整实战:拆一个 crackme
目标程序
网上有很多 crackme 练习程序(专门给人练逆向的小程序)。这一节带你走完一个典型流程。
假设程序行为:
请输入序列号:____
序列号正确 → "注册成功"
序列号错误 → "序列号无效"第一步:侦察(strings)
bash
strings crackme.exe | grep -i -E "serial|invalid|success|key"输出可能是:
Invalid serial number!
Registration successful!
Enter your serial:得到三个线索:提示语、成功语、输入提示。
第二步:找引用(静态分析)
在 Ghidra 里:
- 搜 "Invalid serial number!"
- 右键 → References → 找到引用它的函数
- 这个函数就是验证函数
第三步:读伪代码
反编译出来大概是这样:
c
int check_serial(char *input) {
int len = strlen(input);
if (len != 16) return 0;
int sum = 0;
for (int i = 0; i < 16; i++) {
sum += (unsigned char)input[i];
sum *= 3;
sum %= 100000;
}
if (sum == 87321) return 1;
return 0;
}读懂逻辑:
- 序列号必须 16 位
- 每位字符累加,然后乘 3、取模 100000
- 最终结果必须等于 87321
第四步:写注册机
python
def gen_serial(seed="A"*16):
s = list(seed)
for _ in range(1000000):
total = 0
for ch in s:
total = (total + ord(ch)) * 3 % 100000
if total == 87321:
return "".join(s)
# 简单调整:改最后一位
s[-1] = chr((ord(s[-1]) - 65 + 1) % 26 + 65)
return None
print(gen_serial())更聪明的做法:反过来算。最后一步是 sum == 87321,所以从末位倒推每一位的字符。这需要一点数学,但比暴力快得多。
第五步:验证
把生成的序列号输进程序,看是否提示"注册成功"。
如果成功:算法还原正确。 如果失败:回到第三步,检查是不是漏了某个变换(比如某位有特殊校验)。
第六步:写报告
一份逆向报告包含:
- 目标信息:文件名、大小、哈希
- 环境:系统、工具版本
- 静态分析:关键函数、算法逻辑
- 动态验证:断点位置、寄存器值、内存状态
- 结论:算法还原结果
- 附件:注册机代码
为什么要写报告:三个月后你自己都忘了怎么做的;而且这是你能力的证明。
8.10 Web 漏洞实战:DVWA 五个关卡的具体打法
关卡一:SQL 注入(Low)
目标:拖出 users 表。
步骤:
- 正常输入
1,返回 ID=1 的用户 - 输入
1',报 SQL 语法错误 → 确认存在注入 - 输入
1' OR '1'='1,返回所有用户 - 判断列数:
1' ORDER BY 2-- -(正常),1' ORDER BY 3-- -(报错)→ 2 列 - 联合查询:
1' UNION SELECT user, password FROM users-- -
原理:输入被拼进 SQL,-- - 注释掉后面的内容。
关卡二:SQL 注入(Blind)
目标:盲注猜数据。
步骤:
- 输入
1' AND '1'='1(正常),1' AND '1'='2(异常)→ 布尔盲注存在 - 猜数据库名长度:
1' AND LENGTH(database())=4-- - - 逐字符猜:
1' AND SUBSTRING(database(),1,1)='d'-- -
原理:没有回显,靠"页面正常/异常"判断真假。
关卡三:反射型 XSS
目标:弹窗。
步骤:
- 输入
<script>alert(document.cookie)</script> - 页面直接执行 → XSS 成立
- 构造链接发给受害者:
http://target/vuln.php?name=<script>...</script>
原理:输入被直接输出到 HTML,浏览器当脚本执行。
关卡四:存储型 XSS
目标:让所有访问者中招。
步骤:
- 在留言板输入
<script>alert(1)</script> - 提交后,每次打开页面都弹窗
原理:payload 存进数据库,每次渲染都执行。
关卡五:命令注入
目标:执行 whoami。
步骤:
- 正常输入
127.0.0.1,页面返回 ping 结果 - 输入
127.0.0.1; whoami,返回当前用户 - 输入
127.0.0.1; cat /etc/passwd,读文件
原理:输入被拼进系统命令,; 分隔执行。
每个关卡的"防御对照"
| 漏洞 | 防御 |
|---|---|
| SQL 注入 | 参数化查询(预编译) |
| XSS | 输出编码 + CSP |
| 命令注入 | 不用 shell 拼接;白名单校验 |
写 writeup 时,把"攻击"和"防御"成对写——这才是完整的安全认知。
行业观察:软件公司的三种授权方案,成本差多少
一家做桌面工具的公司,评估过三种授权方式:
| 方案 | 开发成本 | 被破解难度 | 运维成本 | 适合 |
|---|---|---|---|---|
| 本地卡密(算法验证) | 2 人周 | 低(几天可破) | 0 | 低价工具 |
| 联网激活(服务器验证) | 6 人周 | 中 | 服务器 + 客服 | 中高价软件 |
| 硬件绑定 + 在线心跳 | 12 人周 | 高 | 较高 | 专业软件 |
他们最终选了第二种,理由是:第一种上线三个月就出现注册机;第三种会让换电脑的用户大量投诉。
行业真相:没有绝对防破解的方案,只有"破解成本 > 购买成本"的方案。 定价 99 元的工具,做 12 周的防破解是亏本生意。
踩坑实录
坑一:以为反编译能拿回源码
场景:有人反编译一个程序,发现变量名全是 var1、var2,结构也乱了,抱怨"这反编译没用"。
为什么:编译过程会丢掉变量名、注释、宏定义。反编译只能还原"逻辑",还原不了"原文"。
怎么爬出来:接受这个现实。逆向是"读懂逻辑",不是"恢复源码"。变量名自己重命名,逻辑自己梳理。
坑二:以为"破解"能搞定一切
场景:有人花一周逆向一个软件,改掉本地验证,结果发现核心功能还是要联网验证,白忙。
为什么:没先搞清楚"验证在哪一层"。本地验证能破,服务器验证破不了。
怎么爬出来:先判断验证模式(8.4 节那三种),再决定值不值得投入。
坑三:在没授权的目标上练手
场景:有人拿真实网站练 SQL 注入,被报警。
为什么:技术不分好坏,但目标有归属。碰别人的系统,就是另一回事了。
怎么爬出来:练手用靶场(DVWA、HTB、CTF 平台),或者自己搭环境。真实目标必须有书面授权。
坑四:只收藏工具不练
场景:有人装了 IDA、Ghidra、Burp、Frida,一个都没打开过。
为什么:工具是"解决问题"的,没有问题的时候装工具,只是收集癖。
怎么爬出来:拿一道 CTF 题,逼自己用工具做出来。做不出来再学工具。
Lab 8-1|在 DVWA 靶场打出五个漏洞
难度:⭐⭐⭐☆☆ 预计耗时:120 分钟
目标:亲手复现五类常见 Web 漏洞,理解原理
步骤:
- 用 Docker 起 DVWA:
docker run -d -p 8080:80 vulnerables/web-dvwa- 登录(admin/password),安全等级调 Low
- 依次完成:
- SQL 注入:用 UNION 查出 users 表
- XSS(反射型):弹出一个 alert
- XSS(存储型):让每次访问都弹窗
- 文件包含:读取服务器上的
/etc/passwd- 命令注入:执行
whoami- 每个漏洞记录:payload、返回结果、原理、防御方法
- 整理成一份 writeup
验收标准:
- [ ] 五个漏洞都复现成功
- [ ] 每个都有 payload 和原理说明
- [ ] 能说出每个漏洞的防御方法
- [ ] 有一份完整的 writeup
卡住了怎么办:
- Docker 起不来 → 检查端口占用,换端口
- payload 不生效 → 确认安全等级是 Low
- 看不懂返回 → 用 F12 看请求和响应
本章自检清单
- [ ] 逆向、反汇编、反编译,三者什么关系?
- [ ] 静态分析和动态调试各适合什么场景?
- [ ] 卡密的三种验证模式是什么?哪种能破、哪种不能?
- [ ] 为什么"AI 服务破解卡密白嫖 token"不成立?
- [ ] 抓包能发现哪类漏洞?
- [ ] SQLi、XSS、SSRF、越权,各一句话说清原理和防御
- [ ] 栈溢出的原理是什么?现代防护有哪几种?
- [ ] CTF 的五个方向是什么?
学习进度:0 / 13 章
📝 本章小测验(3 题)
1. 哪种卡密验证方式在本地破不了?
2. 「破解卡密白嫖 token」为什么不成立?
3. 栈溢出攻击覆盖的是什么?
一句话记住
本地验证能破,服务器验证破不了——先搞清楚锁在哪,再决定撬不撬。
延伸阅读
- DVWA 官方文档——靶场使用说明
- 《加密与解密》——逆向入门经典
- OWASP Top 10——Web 漏洞权威清单
最后更新:2026-10