PortSwigger靶场之Exploiting server-side parameter pollution in a REST URL通关秘籍

本靶场的核心是服务器端参数污染 (Server-Side Parameter Pollution, SSPP) ,并通过路径遍历 (Path Traversal) 来实现。

一、核心理论知识

这个实验利用的漏洞链比单一的漏洞要复杂,主要涉及以下几个关键概念:

1. URL 路径注入 (URL Path Injection)

这是整个漏洞链的起点。当服务器接收到一个用户输入(如此处的 username),并且没有经过充分的净化和编码,就直接将其拼接到一个 URL 路径中去构造一个新的、服务器端的请求时,就产生了路径注入。

  • 正常情况 :服务器期望 username 是 administrator,于是它在后端请求的 URL 可能是 https://api.internal/v1/users/administrator。

  • 漏洞情况 :如果我们输入 ../admin,且服务器没有对 . 和 / 进行编码,那么后端的 URL 就会变成 https://api.internal/v1/users/../admin,这可能会让我们访问到 https://api.internal/v1/admin 这个意料之外的端点。

2. 服务器端参数污染 (SSPP)

这是本实验的核心。当攻击者能够通过一个输入点影响到服务器向另一个后端服务发起的请求中的多个参数时,就发生了参数污染。

在本实验中,前端只提供了一个 username 输入框,但我们发现的后端内部 API 端点是 /api/internal/v1/users/{username}/field/{field},它有两个参数:{username} 和 {field}。

我们的目标就是用前端这一个 输入框,去控制后端那两个 参数。我们将构造一个恶意的 username 值,例如 administrator/field/passwordResetToken,服务器在拼接 URL 时,就会把 administrator 赋值给 {username},把 passwordResetToken 赋值给 {field},从而实现了参数污染。

3. 通过错误信息进行盲探 (Blind Probing via Error Analysis)

由于我们看不到后端的代码,我们需要像侦探一样通过服务器的响应来推断其内部行为。

  • 使用特殊字符:

    • # (URL 片段):URL 中 # 后面的内容通常不会发送到服务器。如果添加 # (%23) 导致响应变化(例如从成功变为"路由无效"),这强烈暗示我们的输入被放在 URL 路径的末尾,# 截断了后面必要的部分。

    • ? (查询参数):? 用于分隔 URL 路径和查询参数。如果添加 ? (%3F) 同样导致路径错误,这也证明了我们的输入点在 URL 路径部分。

  • 路径遍历探测:

    • 使用 ../ 向上导航。通过观察错误信息的变化(例如从 "Invalid route" 变为 "Not found"),我们可以判断是否已经跳出了应用本身定义的 API 路由,到达了 Web 服务器的根目录级别。

4. API 文档发现

一旦我们能通过路径遍历在服务器上"自由移动",一个常见的攻击目标就是寻找隐藏的 API 文档文件,例如 openapi.json 或 swagger.json。这些文件就像是 API 的蓝图,会暴露大量未公开的、可能存在漏洞的内部 API 端点。


二、靶场具体解题步骤

阶段一:探测注入点并确认漏洞

  1. 触发功能 :首先,在忘记密码页面输入 administrator 并提交,以捕获一个合法的 POST /forgot-password 请求。

  2. 发送到 Repeater :在 Burp 的 Proxy > HTTP history 中找到该请求,右键发送到 Repeater 以便进行修改和重放。

  3. 进行盲探 🕵️:

    • 将 username 参数的值改为 administrator%23 (administrator#)。发送后,收到 Invalid route 错误。推断: 我们的输入在 URL 路径中。

    • 将值改为 administrator%3F (administrator?)。同样收到 Invalid route 错误。再次确认: 输入点在 URL 路径中。

    • 将值改为 ./administrator。响应恢复正常。确认: 服务器正在解析路径语法。

    • 将值改为 ../administrator。收到 Invalid route 错误。这说明路径遍历正在起作用,但可能目标路径不存在。

阶段二:路径遍历与 API 发现

我们的目标是向上遍历目录,直到跳出当前 API 的路径范围,然后寻找文档。

  1. 寻找 API 根目录 :持续在 username 参数前增加 ../,并用 # (%23) 结尾来截断 URL。

    • ../%23 -> Invalid route

    • ../../%23 -> Invalid route

    • ../../../%23 -> Invalid route

    • ../../../../%23 -> Not found

      关键突破! 错误消息从应用的"路由无效"变成了服务器的"未找到"。这说明我们已经成功跳到了 API 路由之外的某个根级别。

  2. 发现 API 文档 🗺️:在这个根级别上,我们尝试访问常见的 API 文档文件名。

    • 构造 Payload: username=../../../../openapi.json%23

    • 发送请求后,服务器返回了一条包含新 API 端点的错误信息。你成功发现了一个隐藏的内部 API:

      bash 复制代码
      /api/internal/v1/users/{username}/field/{field}

阶段三:利用参数污染泄露重置令牌

现在我们有了新的武器:一个内部 API 端点。我们要用它来泄露 administrator 的密码重置令牌。

  1. 探测新端点 :根据发现的结构,我们来污染 username 和 field 两个参数。

    • Payload 1 : username=administrator/field/foo%23

      • 这会污染后端请求为 /api/internal/v1/users/administrator/field/foo。

      • 服务器返回错误,提示只支持 email 字段。这是非常有用的信息!

    • Payload 2 : username=administrator/field/email%23

      • 发送后,响应恢复正常。这证明我们已经可以成功地控制 field 参数了。
  2. 寻找有价值的字段 :我们需要一个比 email 更有用的字段。

    • 回到 Burp 的 HTTP 历史,查看加载的 JS 文件,比如 /static/js/forgotPassword.js。

    • 在 JS 代码中,你会发现密码重置功能引用了一个名为 passwordResetToken 的参数。这就是我们的目标!

  3. 尝试泄露令牌:

    • Payload 3 : username=administrator/field/passwordResetToken%23

      • 发送后,收到一个 API 版本不支持此参数的错误。这又是一个关键线索!说明 passwordResetToken 字段是存在的,只是不在 v1 版本中。
  4. 最终攻击 Payload 🎯:结合路径遍历和参数污染,我们向上跳出当前错误的 API 版本路径,再进入正确的路径。

    • Final Payload : username=../../v1/users/administrator/field/passwordResetToken%23

    • 逻辑分解 : 假设原始后端请求是 .../internal/v1/users/{我们的输入}。

      • ../ 从 users 上升到 v1。

      • ../ 从 v1 上升到 internal。

      • 我们现在位于 /api 级别(根据之前的探测)。

      • v1/users/administrator/field/passwordResetToken 则是我们想要访问的目标路径和参数。

    • 发送这个请求,服务器响应中会直接包含 administrator 的密码重置令牌!

阶段四:获取权限并完成实验

  1. 重置密码 :复制泄露的令牌 (passwordResetToken)。

  2. 在浏览器中,访问密码重置链接,并附上令牌:

    bash 复制代码
    /forgot-password?passwordResetToken=ygkf8whspb1xb2j1oj0k5quba64t6517
    #泄露的令牌
  3. 设置一个新密码。

  4. 登录并删除用户 :使用 administrator 和你的新密码登录,进入管理面板,删除 carlos 用户

三、成功通关

相关推荐
AiMan26 分钟前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真29 分钟前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment31 分钟前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan43 分钟前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么1 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
QXWZ_IA1 小时前
定位数据怎么推给 IoT 平台?消息协议选型与接入准备
网络·人工智能·物联网·安全
上海懒图科技1 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥2 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
不庸.2 小时前
WPScan 实战入门:从 Docker 靶场到弱密码爆破
运维·安全·web安全·docker·容器·安全性测试·wpscan
陈随易2 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员