# 渗透测试报告 —— ShopLite 小型在线商城 | 项目 | 内容 | | --- | --- | | 测试目标 | 192.168.107.3(ShopLite 小型在线商城) | | Target ID | ca21f209 | | 授权范围 | 以 80 端口 Web 服务为起点,扩大到该主机的授权服务(`/api` 后端) | | 规则约定(RoE) | 标准 RoE:允许主动扫描、漏洞验证与授权范围内的利用;**禁止 DoS、破坏性操作与高风险稳定性影响行为** | | 测试方法 | 参考 PTES(渗透测试执行标准)7 阶段方法学 | | 测试时间 | 2026-08-28(UTC) | | 输出语言 | 中文 | | 报告版本 | v1.0(正式交付版) | > 本报告依据全流程各阶段已归档交付物编写,每项发现均标注可复验证据路径。报告中未披露任何用户密码明文、口令哈希及敏感 PII 的完整内容,仅用于说明影响范围,符合标准 RoE。 --- ## 1. 执行摘要(Executive Summary) ### 1.1 总体结论 对 ShopLite 小型在线商城(192.168.107.3)实施的一次授权渗透测试中,确认存在 **4 项可利用漏洞**,其中 **1 项为严重(Critical)级别**:攻击者可在**不持有任何密钥**的前提下,通过伪造 `alg=none` 的 JWT 令牌直接获得**全站管理员读写权限**,进而读取全部用户个人信息(含邮箱、手机号、家庭住址)与订单数据,并可篡改任意用户角色、商品信息等。该漏洞一旦被真实攻击者利用,可导致平台**全站沦陷**。 整体风险评级:**高(High)**。 ### 1.2 风险总览表 | 编号 | 漏洞名称 | 严重度 | CVSS 3.1 | CWE | 利用前置条件 | 证据 | | --- | --- | --- | --- | --- | --- | --- | | F-001 | JWT `alg=none` 签名校验绕过 → 全站管理员提权 | **严重** | 9.8 | CWE-347 / CWE-287 | 无(仅需网络可达) | 阶段 04/05 evidence | | F-002 | `/api/products` 参数 SQL 注入(PostgreSQL) | **高** | 8.1 | CWE-89 | 无(公开接口) | 阶段 04/05 evidence | | F-003 | 头像上传任意文件 + 同源存储型 XSS 载体 | 中-高 | 6.1 | CWE-434 / CWE-79 | 任一登录账户 | 阶段 04/05 evidence | | F-004 | 用户枚举 + 弱口令 `alice/alice123`,无速率限制 | 中 | 5.3 | CWE-200 / CWE-521 / CWE-307 | 无 | 阶段 04 evidence | ### 1.3 业务影响 - **数据泄露**:全量用户 PII(邮箱、手机号、家庭住址)、12 笔订单(含收货地址/明细)、14 条评论、2 条用户备注均可被未授权读取。 - **账户接管**:可借提权/资料篡改接管任意账户,或批量制造管理员身份。 - **业务篡改**:可篡改商品价格、库存,造成财务损失与业务中断风险。 - **信任声誉**:泄露事件与存储型 XSS 钓鱼链将严重损害平台用户信任。 ### 1.4 最快攻击路径 ``` 获取任意有效 Bearer 令牌(开放注册即可) └──► 离线改写为 alg=none JWT(payload 设 role=admin, sub=1,空签名) └──► GET /api/admin/users|orders|products|comments 读取全量数据 └──► PATCH /api/admin/users/{id} {role:"admin"} 建立/抹平管理员 → 全站接管 ``` 无需密钥、无需用户交互、可完全自动化,全程可在数秒内完成。 --- ## 2. 范围与授权(Scope & Authorization) ### 2.1 目标清单 | 目标 | 描述 | 范围 | | --- | --- | --- | | 192.168.107.3:80 | ShopLite 商城 Web 前端(nginx)+ `/api` Express 后端 | 在授权范围内 | | 192.168.107.3 其余端口 | TCP 全端口/UDP top-30 | 仅作识别,确认仅 80 开放 | ### 2.2 RoE 检查清单 | 项目 | 是否符合 | | --- | --- | | 允许主动扫描 | 是(SYN/Connect scan、目录、指纹) | | 允许漏洞验证 | 是(在授权范围内确认可利用性) | | 允许授权范围内利用 | 是(仅针对自建测试账户做写操作) | | 禁止 DoS / 破坏性操作 | 遵守(未做高并发/重负载、未删改既有数据) | | 稳定性与数据影响最小化 | 遵守(写操作仅作用于自建测试账户) | | 语言 | zh-CN | ### 2.3 授权依据 授权范围见 `target/inputs/pre-engagement.md` 与 `target/scope.md`:以 80 端口 Web 服务为起点,随后按渗透流程扩大到该主机的授权服务。`target/roe.md` 明确定义标准 RoE。 --- ## 3. 测试范围与方法(Methodology) 测试遵循 PTES 7 阶段方法学,各阶段执行情况与交付物路径如下: ### 3.1 情报收集(PTES 01 Pre-engagement / 02 Intelligence Gathering) - 全端口 TCP 扫描确认 **仅 80/tcp 开放(nginx 1.27.5)**,UDP top-30 无确认开放服务。 - Web 指纹识别技术栈:**nginx 1.27.5 + Vite 构建的 React 18 SPA + Node.js Express 后端**;认证为 Bearer token(存 localStorage),无 Cookie。 - 枚举暴露面:公开 `/api/products(?q=&category=)`;认证 `/api/auth/{login,register,me}`、`/api/orders`、`/api/notes`、`/api/upload/avatar`;管理面 `/api/admin/{stats,users,products,orders,comments}`。 - 识别安全弱点:`Access-Control-Allow-Origin: *` 且允许 `Authorization` 头;无 CSP / X-Frame-Options / HSTS;`Server` / `X-Powered-By` 版本泄露。 - 交付物:D-001(资产/端口/指纹)、D-002(技术栈/暴露面)。 ### 3.2 威胁建模(PTES 03 Threat Modeling) - 建立资产/信任边界/用户角色模型,按 STRIDE + CIA 分类。 - 输出 12 条候选攻击路径,按价值×可行性排序为 P1–P8 验证优先级,并记录信息缺口 G1–G9。 - 核心判断:认证与授权链路(JWT、admin 越权、角色注入)为最高价值攻击面。 - 交付物:D-003。 ### 3.3 漏洞分析(PTES 04 Vulnerability Analysis) - 按 P1–P8 顺序对每条候选路径做实证验证: - P1 admin BFLA:普通用户直连 admin 端点 → 403(未确认越权)。 - P2 JWT:弱密钥爆破(约 15.5 万密钥,未命中);**发现并确认 `alg=none` 签名绕过**。 - P3/P4 注册与资料角色注入:服务端过滤,未确认。 - P5 注入:`/api/products?q=` **确认 PostgreSQL SQL 注入**(布尔+时间盲注);`/api/products/{id}` 参数化不可注入。 - P6 上传:**确认任意文件上传**,可存储 HTML/SVG(stored XSS 载体)。 - P7 IDOR:未确认(orders/notes 严格按 token 用户归属)。 - P8 **确认用户枚举(register 重名报错 + login 时序侧信道)+ 弱口令 alice/alice123 + 无速率限制**。 - 交付物:D-004、D-005。 ### 3.4 漏洞利用(PTES 05 Exploitation) - 对 F1–F4 做破坏性最小的正式利用验证,全程只读为主,写操作仅针对自建测试账户: - F1:伪造 `alg=none` token 走通完整 admin 接管链(读取全部 admin 数据 + PATCH 自建账户提权并回验闭环)。 - F2:布尔/时间盲注复验,sqlmap 双类型确认,克制提取非敏感元数据(DB 版本/库/用户/表结构/字段名)。 - F3:上传 `xss_proof.html` 并回读确认 `text/html` 可执行脚本。 - F4:alice/alice123 登录确认,核查访问面(仅自身数据)。 - 交付物:D-006(evidence/f1_*、f2_*、f3_*、f4_*)。 ### 3.5 后利用与影响评估(PTES 06 Post Exploitation) - 量化数据面影响(15 用户/12 订单/18 商品/14 评论/2 备注),评估篡改能力与持久化特征(纯逻辑型漏洞,可持续伪造 admin)。 - 输出 8 个业务影响维度 + 3 条攻击链场景。 - 执行清理:自建测试账户降权为 user;识别 `xss_proof.html` 无删除接口的遗留项。 - 交付物:D-007(result.md、evidence/cleanup_evidence.txt)。 ### 3.6 报告(PTES 07 Reporting) - 整合各阶段交付物,产出正式中文报告 `report/report.md`。交付物:D-008。 --- ## 4. 发现的安全问题(Technical Findings) > 严重度依据漏洞可利用性、前置条件与影响综合评定,并给出 CVSS 3.1 评分与 CWE 分类。 ### 4.1 F-001【严重】JWT `alg=none` 签名校验绕过 → 全站管理员提权 | 属性 | 值 | | --- | --- | | 严重度 | **严重(Critical)** | | CVSS 3.1 | **9.8**,向量 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H | | CWE | CWE-347(签名算法未正确校验)/ CWE-287(认证绕过) | | 发现/利用阶段 | 漏洞分析(PTES 04)→ 利用验证(PTES 05) | **CVSS 向量分解** | 分量 | 评估 | 说明 | | --- | --- | --- | | 攻击向量 AV | N 网络 | 通过 HTTP `/api` 远程可达 | | 利用复杂度 AC | L 低 | 无需任何绕过,直接伪造令牌 | | 所需权限 PR | N 无 | 开放注册即得有效令牌(可选),甚至无需有效令牌 | | 用户交互 UI | N 无 | 无需受害者交互 | | 影响范围 S | U 不变 | 漏洞仅影响应用自身 | | 机密/完整/可用 | H/H/H | 全量数据可读、可篡改,平台可被完全接管 | **描述** 服务端 JWT 校验**未设置算法(alg)白名单**:它会对 HS256 令牌严格执行签名校验(篡改 payload、保留原签名的 HS256 令牌会返回 401),但**接受 `alg=none`(空签名)**,且**信任令牌内 `role` 声明**而非从数据库判定角色。攻击者只需将令牌 header 改为 {"alg":"none","typ":"JWT"}、payload 置为 role:admin、sub:1、签名留空,即可伪造出被服务端接受的管理员令牌,**全程无需任何密钥**。 **复现步骤** 1. 注册/登录取得一个 Bearer token(或直接观察任意合法 token 的解码结构)。 2. 构造新 JWT:header={"alg":"none","typ":"JWT"},payload={"sub":1,"role":"admin","iat":...,"exp":...},签名留空。 3. 以 `Authorization: Bearer <伪造token>` 请求(无需真实密钥): - `GET /api/auth/me` → HTTP 200,返回 admin(id=1, role=admin) 身份。 - `GET /api/admin/stats` → HTTP 200(全量统计)。 - `GET /api/admin/users|products|orders|comments` → HTTP 200(全量数据泄露)。 - `PATCH /api/admin/users/{自建测试id} {"role":"admin"}` → HTTP 200(提权有效,重新登录后令牌 role=admin)。 **证据路径** - `04-vulnerability-analysis/delegations/D-004/artifacts/forged_tokens.txt`(伪造 alg=none / 篡改 HS256 对照令牌) - `04-vulnerability-analysis/delegations/D-004/artifacts/alg_none_admin_data.txt`、`alg_none_me.txt`、`alg_none_patch_self.txt`、`post_patch_login.txt` - `05-exploitation/delegations/D-006/evidence/f1_me.txt`、`f1_admin_data.txt`、`f1_admin_leaks.json`、`f1_patch.txt`、`f1_after_login.txt`、`f1_chain.txt` **影响** - 无需密钥即获**全站管理员读写**能力,可读取全部用户 PII、订单(含收货地址)、商品与评论数据。 - 可篡改任意用户角色(批量制造 admin / 降权现有管理员)、篡改用户资料、商品价格/库存等。 - 属**纯逻辑型持久化**:无需在服务器落下任何文件,攻击者可随时再次伪造 admin 身份,直至修复。 **修复建议** 1. 【P0·24h】在 JWT 验证处**强制算法白名单**,仅允许 HS256(或 RS256),显式拒绝 alg=none / none / None 及任何可变算法参数(使用主流 JWT 库的 algorithms 白名单参数)。 2. 【P0·24h】**立即轮换 JWT 签名密钥**,作废可能已泄露的既有令牌。 3. 【P0·24h】**角色改由服务端数据库判定**,每个请求从 DB 读取用户角色,不信任令牌内 role 声明。 4. 【P1·1 周】升级 JWT 库至无已知 CVE 的稳定版并做版本审计。 5. 【P1·1 周】引入统一 RBAC 中间件层做权限判定,而非在各路由独立校验。 6. 【P2·1 月】对全部 admin 操作记录审计日志(操作者/时间/IP/变更内容);在 CI 中加入 JWT 安全检测门禁。 --- ### 4.2 F-002【高】`/api/products` 参数 SQL 注入(PostgreSQL) | 属性 | 值 | | --- | --- | | 严重度 | **高(High)** | | CVSS 3.1 | **8.1**,向量 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L | | CWE | CWE-89(SQL 注入) | | 发现/利用阶段 | 漏洞分析(PTES 04)→ 利用验证(PTES 05) | **CVSS 向量分解** | 分量 | 评估 | 说明 | | --- | --- | --- | | 攻击向量 AV | N 网络 | 公开接口远程可达 | | 利用复杂度 AC | L 低 | 直接注入 | | 所需权限 PR | N 无 | `/api/products` 匿名可访问 | | 用户交互 UI | N 无 | 无需交互 | | 影响范围 S | U 不变 | 影响应用/数据库 | | 机密性 C / 完整性 I | H / H | 可读取与改写数据 | | 可用性 A | L 低 | 借时间盲注可拖慢查询,无直接 DoS | **描述** `GET /api/products?q=`(及 `category=`)参数经 `Prisma $queryRawUnsafe` 直接拼入 SQL 的 `ILIKE '%q%' ORDER BY id ASC` 子句,导致 SQL 注入。注入点为 PostgreSQL 关系型库,**兼具布尔盲注与时间盲注**,可逐字节有序提取数据库全部业务数据。已确认可通过盲注读取:DB 版本、库名、用户名、表结构、字段名。 **复现步骤** 1. 布尔盲注:`q=none' OR 1=1-- -` → 返回 18 条;`q=none' OR 1=2-- -` → 返回 0 条(baseline zzz 为 0 条)。 2. 时间盲注:`q=x' OR (SELECT CASE WHEN pg_sleep(3) IS NULL THEN 1 ELSE 1 END)=1-- -` → 约 3.09s(baseline 0.05s)。 3. sqlmap 自动确认 boolean-based + time-based,DBMS=PostgreSQL。 4. 克制元数据提取:version()=PostgreSQL 16.15(musl/Alpine)、current_database()=shoplite、current_user=shoplite;public 6 张表:OrderItem, Order, Note, Comment, Product, User;User 表字段含 password(哈希,未导出)。 **证据路径** - `04-vulnerability-analysis/delegations/D-005/evidence/p5_sqli_products.log`、`p5_sqli_time.log` - `05-exploitation/delegations/D-006/evidence/f2_meta.txt`、`f2_tables.txt`、`f2_columns.txt`、`f2_timeconfirm.txt`、`f2_sqlmap_meta.log`、`f2_sqlmap_tables.log` **影响** - 攻击者可读取数据库全部业务数据,**含 `User.password` 口令哈希字段**(本次未导出哈希值)。 - 若配合离线破解/进一步提取,可扩大为口令泄露与横向入侵。机密性与完整性风险均高。 **修复建议** 1. 【P0·24h】将 `$queryRawUnsafe` 全部替换为**参数化查询**(Prisma 参数化 API),杜绝把用户输入拼入 SQL 字符串。 2. 【P0·24h】在 nginx/WAF 层临时增加注入特征拦截规则(如 UNION、OR 1=1、pg_sleep 等)。 3. 【P1·1 周】全库审计所有 `$queryRawUnsafe` / `$executeRawUnsafe` 调用并替换;数据库连接按最小权限原则授权(读写分离)。 4. 【P1·1 周】对用户输入进行必要的白名单/转义(不能替代参数化)。 --- ### 4.3 F-003【中-高】头像上传任意文件 → 同源存储型 XSS 载体 | 属性 | 值 | | --- | --- | | 严重度 | **中-高(Medium-High)** | | CVSS 3.1 | **6.1**,向量 AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N | | CWE | CWE-434(不受限制的文件上传)/ CWE-79(存储型 XSS) | | 发现/利用阶段 | 漏洞分析(PTES 04)→ 利用验证(PTES 05) | **CVSS 向量分解** | 分量 | 评估 | 说明 | | --- | --- | --- | | 攻击向量 AV | N 网络 | 远程上传/访问 | | 利用复杂度 AC | L 低 | 直接上传即可 | | 所需权限 PR | L 低 | 需任一登录账户 | | 用户交互 UI | R 需交互 | 需诱导受害者访问恶意文件 URL | | 影响范围 S | C 已改变 | 可借助 xss 影响会话/权限 | | 机密性 C | H | 可窃取令牌 | | 完整性 I | L | 页面内容篡改 | **描述** `POST /api/upload/avatar`(字段 avatar)**无扩展名/内容类型白名单**:.png/.html/.svg/.php 及无扩展名文件均可上传,返回 `/uploads/avatars/<时间戳>-<原名>`;存储文件**按原名+原 MIME 回读**,.html 以 text/html 输出、正文 `