131 lines
5.1 KiB
Markdown
131 lines
5.1 KiB
Markdown
---
|
||
name: pentest-personalblog-fun-mass-assignment
|
||
description: {target_domain} Spring Boot 博客系统渗透测试——通过 Swagger 泄露 + Mass Assignment 提权至管理员,JS静态分析补充攻击面
|
||
metadata:
|
||
type: project
|
||
---
|
||
|
||
# {target_domain} 渗透测试记录
|
||
|
||
**日期**: 2026-05-16
|
||
**目标**: https://www.{target_domain}/
|
||
**关键词**: Spring Boot, MyBatis-Plus, SaToken, Mass Assignment, Swagger泄露, 权限提升, Vue 3, JS静态分析, 前端路由绕过, DTO缺失
|
||
|
||
## 背景
|
||
|
||
黑盒渗透测试一个基于 Spring Boot 的个人博客系统,目标是进入后台管理页面。
|
||
|
||
## 攻击路径
|
||
|
||
1. **信息收集**: 识别 Vue SPA → 提取 JS 中的 API 端点 → 发现 `/api/v3/api-docs`(Swagger 未授权访问)
|
||
2. **API 文档分析**: 获得完整端点定义、数据模型、管理员接口
|
||
3. **用户枚举**: 文章列表接口暴露 admin 用户信息(id=1,email={admin_email})
|
||
4. **公告提示漏洞存在**: 公告 #14 标注"网站普通用户可被提权管理员"
|
||
5. **注册**: 通过 mail.tm 临时邮箱接收验证码注册普通用户
|
||
6. **Mass Assignment 提权**: `PUT /api/user/profile` 传入 `"role":"admin"` 将 role 从 reader 提升为 admin
|
||
|
||
## JS 静态分析补充发现
|
||
|
||
IP 被限速后通过前端 JS bundle 做静态分析,提取了完整的 API 端点列表:
|
||
|
||
| 来源 | 发现 |
|
||
|------|------|
|
||
| `user-n8GFLR5I.js` | 全部 16 个用户/认证端点的完整参数定义 |
|
||
| `article-manage-BUHBK4I3.js` | 全部 8 个文章端点的操作(CRUD + 发布/草稿/列表) |
|
||
| `upload-C3Isuhzt.js` | 文件上传逻辑(avatar + cover),使用 FormData/multipart |
|
||
| `Login-BfQvQsk0.js` | 登录/注册完整流程,含邮箱验证码登录 |
|
||
| `index-F3rwNCiG.js` | axios 实例配置(baseURL: /api, satoken header) |
|
||
|
||
### 前端路由保护发现
|
||
|
||
Vue Router 定义中管理端路由带 `requiresAdmin: true` 标志,但**仅在前端判断**:
|
||
|
||
```javascript
|
||
{ path: "/user-manage", name: "UserManage", ..., meta: { requiresAdmin: true } },
|
||
{ path: "/category-manage", name: "CategoryManage", ..., meta: { requiresAdmin: true } },
|
||
```
|
||
|
||
后端 API 虽然有 SaToken 鉴权,但管理端 GET 接口(如 article/all)缺少认证检查。
|
||
|
||
### 完整 API 端点清单
|
||
|
||
**用户/Auth**(user-n8GFLR5I.js):
|
||
- `POST /user/login` — 用户名密码登录
|
||
- `POST /user/register` — 注册
|
||
- `GET /user/info` — 当前用户信息
|
||
- `PUT /user/profile` — 更新资料(Mass Assignment!)
|
||
- `PUT /user/password` — 修改密码
|
||
- `POST /user/logout` — 登出
|
||
- `POST /auth/send-code` — 发验证码
|
||
- `POST /auth/verify-email-code` — 校验验证码
|
||
- `POST /user/login-by-email` — 邮箱验证码登录
|
||
- `GET /user/check-username` / `check-email` / `check-exists` — 检查接口
|
||
- `PUT /user/{id}/status` — 管理员禁用用户
|
||
- `GET /user/{id}` — 管理员查用户详情
|
||
- `GET /user/list` — 管理员用户列表
|
||
|
||
**文章**(article-manage-BUHBK4I3.js):
|
||
- `POST /article` — 创建文章
|
||
- `PUT /article/{id}` — 更新文章
|
||
- `DELETE /article/{id}` — 删除文章
|
||
- `GET /article/{id}` — 查文章详情
|
||
- `GET /article/drafts` — 我的草稿
|
||
- `GET /article/my` — 我的文章
|
||
- `GET /article/all` — 所有文章(管理端)
|
||
- `POST /article/{id}/publish` — 发布文章
|
||
|
||
### 已验证安全的攻击面
|
||
|
||
| 测试项 | 结论 |
|
||
|-------|------|
|
||
| 密码修改需旧密码 | PUT /user/password 需要旧密码认证 |
|
||
| 邮箱验证码一次性 | 验证码消费后不可重用 |
|
||
| 前端无 API Key/Secret 硬编码 | bundle 中无敏感凭证 |
|
||
| SaToken UUIDv4 不可伪造 | UUID 随机性足够 |
|
||
| nginx 正确拦截 Method Override | HTTP 动词篡改被 405 拒绝 |
|
||
|
||
## 关键发现
|
||
|
||
| 发现 | 说明 |
|
||
|------|------|
|
||
| Swagger 生产环境未关闭 | `/api/v3/api-docs` + Knife4j + Swagger UI 全暴露 |
|
||
| MyBatis-Plus 直接接受 Entity | Controller 直接接收 User 对象传给 updateById,未做字段过滤 |
|
||
| CORS 全通 | `access-control-allow-origin: *` |
|
||
| 邮箱验证码可用 temp mail | mail.tm 临时邮箱可接收验证码 |
|
||
| **前端路由保护仅前端控制** | requiresAdmin 标志在后端无对应强制校验 |
|
||
| **系统级 Mass Assignment** | Article/Category/Tag/Announcement 全部 CRUD Entity 直收 |
|
||
| **article/all 无认证** | 管理端文章列表接口未做任何权限校验 |
|
||
|
||
## 复现命令
|
||
|
||
```bash
|
||
# 注册
|
||
POST /api/user/register {"username":"x","password":"{test_password}","email":"{test_email}","emailCode":"123456"}
|
||
# 提权
|
||
PUT /api/user/profile {"role":"admin"}
|
||
# 验证
|
||
GET /api/user/info → {"role":"admin",...}
|
||
GET /api/user/list → [全部用户]
|
||
```
|
||
|
||
## 工具
|
||
|
||
- curl (Windows)
|
||
- mail.tm API (临时邮箱)
|
||
- Python 3
|
||
- JS 源码静态分析(regex/py 提取端点)
|
||
|
||
## 修复要点
|
||
|
||
1. DTO 隔离:Controller 不要直接接收 Entity 对象(全局审计)
|
||
2. `@JsonIgnore` 或 Service 层 role 字段强制写保护
|
||
3. 生产禁用 Swagger/Knife4j
|
||
4. CORS 限制为具体域名
|
||
5. 用户信息接口脱敏
|
||
6. Article/all 添加 SaCheckRole 注解
|
||
7. 后端对所有管理端接口做独立权限校验(不依赖前端路由控制)
|
||
|
||
## 关联
|
||
|
||
- [[swagger-exposure-pentest]]
|