前提与目标
在一次常规的安全测试中,我的目标是一个校园类证书服务站点,其入口是一个微信小程序。测试的目的是在授权范围内,评估其安全性并发现潜在漏洞。
小程序的主界面显示了“智慧空间”和“预约更便捷”等字样,核心功能包括“座位预约”、“扫一扫”等。其用户中心则提供了“预约记录”、“使用须知”、“证明上传”等功能入口。
小程序端测试:弱口令与越权初探
面对此类系统,登录框通常是测试的起点。我的首要思路是尝试弱口令。首先需要抓取登录请求,分析其认证方式。
抓包发现,登录接口的请求与响应如下。请求以明文JSON格式传输用户名和密码,这是一个潜在的风险点。
HTTP请求:
POST /login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: https://www.example.com/login?redirect=https%3A%2F%2Fwww.example.com%2Fdashboard
Content-Type: application/json
...
{"username": "799999", "password": "123456"}
HTTP响应:
HTTP/1.1 200
Date: Thu, 22 Jan 2026 00:39:04 GMT
Server: nginx/1.21.4
Set-Cookie: JSESSIONID=SBF7Z2A2001389Y1EFTG8F176703B282550; Path=/; HttpOnly; Secure; SameSite=Lax
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
...
{"code": 0, "message": "Password error"}
由于密码是明文传输,我直接使用弱口令字典进行爆破,最终成功获得一组账号密码相同的凭证(如 799999/799999),从而进入了小程序后台。
在后台点击“我的”功能时,抓取到一个获取用户信息的请求:
GET /api/v2/110110/sys/user/getByUserId HTTP/1.1
Host: 643566d4f-5f5c-47fc-b1c0-822246adef33
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE1OTE0MDI1fQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
...
响应返回了用户所属组织等信息。注意到请求路径或参数中常包含 userId,这是一个敏感的标识符。我首先尝试将参数置空,但无返回。随后尝试传入 id=1,这通常是管理员账户的常见ID。
GET /servlet/getBy?d=1 HTTP/1.1
Host: 127.0.0.1:8080
Authorization: Bearer d6235dff-f5ca-4776-b1e2-82246e5d6f13
...
HTTP/1.1 200
Server: Apache/2.4.51 (Win64) PHP/8.2.10
...
{"code": "success"}
果不其然,id=1 有数据返回。于是我将之前普通用户请求中的 id 替换为 1 并重放。对比发现,管理员的返回数据包中包含了更丰富的菜单权限字段,例如 permission: 'admin'。
然而,在小程序前端界面中,我并未看到这些新增的管理功能菜单。这引发了一个猜测:这些菜单项可能对应着一个独立的Web管理后台,而小程序端只是屏蔽或未实现这部分UI。
发现Web管理端:目录扫描与鉴权绕过
为了验证猜测,我使用 dirsearch 对目标域名进行目录扫描。成功发现了一个Web端的登录入口:xxxedu.cn/xxx/#/login。
该登录界面是一个紫色背景的管理系统,标题为“管理系统”,包含“工号”和“密码”输入框。我尝试使用从小程序获取的弱口令进行登录,但系统提示“用户名不存在或密码错误”。
抓包对比发现,Web端的登录接口与小程序的完全不同,因此凭证无法通用。对Web登录口进行弱口令爆破也未成功。
这时,我对比了两个系统的登录成功响应包。虽然接口不同,但其响应数据结构极其相似,都采用了{“code”:0, “msg”:“success”, “data”:{...}}的格式,且data中都包含token字段。
小程序登录成功响应示例:
{
"code": 0,
"msg": "success",
"data": {
"expires_in": 359999,
"token_type": "bearer",
"access_token": "f...58-0c37ab21c768",
"scope": ["all"]
}
}
Web登录失败响应示例:
{
"code": 1,
"msg": "用户名不存在或密码错误!",
"data": ""
}
一个大胆的想法浮现:能否将小程序登录成功后获取到的Token,直接用于Web端的会话认证? 即进行一种“Token移植”的测试。
我将浏览器中Web端的请求头Authorization字段,替换为从小程序获取的有效Bearer Token。刷新页面后,成功进入了Web管理后台的界面!这证实了两个系统后端共享了同一套身份验证机制,但在前端登录逻辑上做了隔离。
突破Web端鉴权:未授权访问与水平越权
登录后,页面URL包含#号,判断其为Vue.js开发的前后端分离应用。虽然进入了后台,但侧边导航菜单为空。使用VueCrack等前端路由分析工具,成功探测出大量未在界面上显式渲染的路由路径,例如:
/#/login
/#/movement
/#/seatBoard
/#/home
/#/MettingTable
通过直接访问这些路由,我发现了多个管理功能模块。其中之一是“模型管理”页面,该页面以表格形式展示数据,包含“模型名称”、“所属组织”、“创建时间”等列,并提供“查询”、“新增模型”、“编辑”、“删除”等操作按钮。在教育行业系统的安全/渗透/逆向测试中,能够创建或篡改核心数据模型,通常可构成中危漏洞。
更严重的发现是一个“人员管理”页面。该页面以表格形式列出了全部用户信息,包含姓名、部门、角色、学号/工号等详细字段。
人员表示例:
| 姓名 |
部门 |
角色 |
学号/工号 |
人员类型 |
操作 |
| admin1 |
计算机学院 |
超级管理员 |
admin1 |
教职工 |
编辑 修改 |
| admin2 |
(未显示) |
(未显示) |
admin2 |
学生 |
编辑 修改 |
| ... |
... |
... |
... |
... |
... |
页面底部显示“共219561条数据”,数量巨大。关键在于,访问此页面及后续操作接口并未进行有效的权限校验,即存在未授权访问漏洞。
我尝试点击“编辑”管理员账户,抓取到的请求包如下:
GET /synber/getBy?id=1 HTTP/1.1
Host: xxx
Authorization: Bearer d625daf5fca-476c-bf4d-82246e46d13
...
通过修改id参数,可以查看并编辑任意用户的信息。在返回的编辑数据中,竟然包含了用户密码的密文!虽然密码是加密存储的,但根据常见的网络/系统安全评估标准,在未授权情况下泄露大量用户敏感信息(包括密码密文),已构成高风险漏洞。
利用编辑功能,我直接重置了最高管理员的密码,并使用新密码成功登录管理员账户,从而完成了从普通用户到超级管理员的完整权限提升链条。
总结与思考
本次测试始于一个小程序的弱口令,通过信息泄露发现潜在Web后台,利用共享的Token验证机制绕过登录,最终通过前端的未授权路由和后台的未授权接口,实现了全面的越权访问和信息泄露。
整个测试过程揭示了几个常见但危险的问题:
- 弱口令与明文传输:是突破边界的起点。
- 接口未授权访问/水平越权:
id参数可控且无校验,是贯穿始终的核心问题。
- 前端路由暴露与鉴权缺失:Vue前端未对路由进行有效隐藏和权限控制。
- 多端认证逻辑不一致:小程序与Web端共享Token但登录接口分离,导致了鉴权绕过风险。
- 敏感信息过度返回:在接口响应中返回密码密文是不必要的,增加了信息泄露的隐患。
对于开发者和运维 & 测试人员而言,需要在设计之初就贯彻最小权限原则,对每一个接口、每一次请求都进行严格的身份认证与权限校验,避免“信任”前端传递的任何参数。
参考资料
[1] 记一次某证书站小程序到网站管理的测试, 微信公众号:mp.weixin.qq.com/s/ve0ByZIQKbbNiEBN7OEyzw
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。