网络环境搭好之后,终于到了最期待的环节——用 Kali Linux 对自己的项目做一次安全测试。我想知道自己写的这个 PetSocial 项目,到底能不能经得起考验。
前置准备
测试环境
| 角色 | 系统 | IP |
|---|---|---|
| 攻击机 | Kali Linux(VMware 虚拟机) | 10.5.7.93 |
| 目标 | Windows 宿主机上的 Docker 服务 | 10.5.7.1 |
目标端口
| 服务 | 端口 | 说明 |
|---|---|---|
| 用户前端 | 5173 | Vue 3 + Nginx |
| 管理后台 | 5174 | Vue 3 + Nginx |
| 后端 API | 8000 | Django + Gunicorn |
上一篇文章已经通过 netsh portproxy 把这些端口转发到了虚拟网,Kali 可以直接访问。
声明
所有测试都在本地 Docker 环境中进行,只针对自己的项目,不涉及任何外部网站或非法行为。 安全测试是为了学习和加强防御。
第一步:目录扫描
先用 gobuster 扫一下网站有没有暴露敏感文件或隐藏目录。
扫描前端
gobuster dir -u http://10.5.7.1:5173 \
-w /usr/share/wordlists/dirb/common.txt \
-x html,php,js,txt,env,bak \
-t 10 \
--exclude-length 首页大小
这里有个坑:PetSocial 是 Vue 单页应用,所有不存在的路径都会返回 200(因为 Nginx 配置了 try_files $uri /index.html)。所以需要用 --exclude-length 过滤掉和首页大小相同的响应,否则结果全是误报。
扫描后端
gobuster dir -u http://10.5.7.1:8000 \
-w /usr/share/wordlists/dirb/common.txt \
-x json,yaml,txt,env \
-t 10
扫描结果

| 检查项 | 结果 |
|---|---|
.env 文件泄露 | ❌ 未发现 |
.git 目录泄露 | ❌ 未发现 |
| 管理后台路径 | ❌ 未暴露 |
| API 端点 | 发现 /api/ 路径(正常) |
| 后端根路径 | 全部返回 400/404 |
结论:没有敏感文件泄露,后端没有暴露多余的端点,防御不错。
第二步:弱口令爆破
登录接口是最常被攻击的地方。我用 ffuf 对登录 API 进行弱口令爆破测试。
爆破命令
ffuf -u http://10.5.7.1:8000/api/users/login/ \
-X POST \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"FUZZ"}' \
-w /usr/share/wordlists/rockyou.txt \
-mc 200 \
-fs 错误响应大小 \
-t 10
FUZZ 是 ffuf 的占位符,会被字典中的每一行替换。rockyou.txt 是一个包含上万条常见密码的字典。
爆破结果
试了 1 万多条常见密码,全部返回 400 失败。admin 账号的密码不在常见弱密码列表中。
结论:密码强度足够,弱口令攻击无效。
第三步:SQL 注入测试
SQL 注入是最经典的 Web 漏洞之一。用 sqlmap 检查登录接口是否存在注入点。
测试命令
sqlmap -u "http://10.5.7.1:8000/api/users/login/" \
--method=POST \
--data='{"username":"admin","password":"test"}' \
--headers="Content-Type: application/json" \
--level=1 --risk=1 \
--batch \
--technique=B \
--dbms=mysql
参数说明:
--level=1 --risk=1:基础扫描级别--batch:自动回答所有提示--technique=B:布尔盲注测试--dbms=mysql:指定数据库类型
测试结果

sqlmap 的结论:not injectable(不可注入)。
我又手动试了几个经典 payload:
{"username": "' OR '1'='1", "password": "test"}
{"username": "admin'--", "password": "test"}
全部失败。Django 的 ORM 默认使用参数化查询,从根本上防止了 SQL 注入。
结论:SQL 注入攻击无效,ORM 的防护起了作用。
测试总结

| 测试项目 | 工具 | 结果 |
|---|---|---|
| 敏感文件泄露 | gobuster | ✅ 未发现 |
| 隐藏目录暴露 | gobuster | ✅ 未发现 |
| 弱口令 | ffuf | ✅ 未爆破成功 |
| SQL 注入 | sqlmap | ✅ 不可注入 |
整体来看,项目的基础安全防护做得还行,没有「低挂果实」(low-hanging fruit)——也就是那些最容易被利用的漏洞。
为什么能防住?
回头分析一下,主要是这几点起了作用:
| 防护措施 | 对应攻击 |
|---|---|
Nginx 只代理 /api/ 和 /media/ | 防止后端路径暴露 |
| Django ORM 参数化查询 | 防止 SQL 注入 |
| 使用强密码 | 防止弱口令爆破 |
| 前端构建后只有静态文件 | 没有 .env、.git 等敏感文件 |
学到了什么
作为一个安全测试新手,这次实践让我学到了不少:
- 目录扫描是渗透测试的第一步:很多网站会不小心暴露
.env、.git、备份文件等,一扫就能发现 - 单页应用的扫描需要特殊处理:Vue/React 应用所有路径都返回 200,需要用
--exclude-length过滤 - 弱口令依然是最常见的攻击方式:用强密码真的很重要
- ORM 是防 SQL 注入的利器:只要不写原生 SQL,基本不用担心注入问题
- 安全是代码写法 + 配置 + 测试的综合结果
下一步计划
基础测试通过了,但还有更深层的安全问题值得探索:
- 业务逻辑漏洞:比如越权访问(A 用户能不能看到 B 用户的数据)
- JWT Token 安全:Token 有没有过期机制?能不能被篡改?
- 用 Burp Suite 抓包分析:更细致地检查请求和响应
安全测试是一个持续的过程,不是跑一次工具就完事了。但至少现在我知道,自己的项目不是那种一碰就碎的「低级项目」,这让我挺有成就感的。