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

18次阅读
没有评论

xss-labs Level4 代码审计报告

目标文件: level4.php | 漏洞类型: 反射型 XSS —— 去除尖括号后的属性事件注入 | CWE: CWE-79 / CWE-80 | 危害等级: 中危
风险路径: GET /level4.php?keyword=<payload> → <input value="..."> 属性注入(无需 </>)


一、漏洞代码定位

level4.php 第 17-22 行:

$str = $_GET["keyword"];
$str2 = str_replace(">", "", $str);        // L18 删除 >
$str3 = str_replace("<", "", $str2);       // L19 删除 <
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword  value="'.$str3.'">    // L22 危险:value 用删除了<>但未转义引号的 $str3
<input type=submit name=submit value=搜索 />
</form>
</center>';

漏洞点: L22。过滤思路是"删掉 < 和 > 就注入不了标签了",但忽略了:

  1. value 属性没有转义引号(" 未过滤)。
  2. 注入事件属性根本不需要 </>。

二、漏洞原理

  • 攻击者用双引号 " 闭合 value,注入 onfocus、autofocus 等事件/控制属性即可弹窗,全程不出现 </>。
  • 这是典型的黑名单过滤思维缺陷:只针对"已知攻击形态"(标签)防护,未做"输出编码 + 属性转义"这种根本性防护。
  • 顺带说明:str_replace(">","",...) / str_replace("<","",...) 还无法处理大小写/实体变体,过滤本身也不完备,但即便完备也堵不住属性注入。

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

Payload(URL 解码后):

?keyword=" onfocus=alert(1) autofocus="

渲染结果: <input name=keyword value="" onfocus=alert(1) autofocus="" type=submit...> → autofocus 聚焦触发 onfocus。

Yakit 可重放原始请求:

GET /level4.php?keyword=%22%20onfocus=alert(1)%20autofocus=%22 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: text/html
Connection: close

触发方式: 页面加载自动聚焦输入框 → onfocus=alert(1) 执行 → 命中通关逻辑跳转 level5。


四、修复建议

$str = $_GET["keyword"] ?? "";
$safe = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');   // 不要用 str_replace 删字符,直接输出编码
echo "<h2 align=center>没有找到和".$safe."相关的结果.</h2>"
   . '<center>
      <form action=level4.php method=GET>
      <input name=keyword  value="'.$safe.'">
      <input type=submit name=submit value=搜索 />
      </form></center>';

要点:

  1. 抛弃黑名单式 str_replace 删字符,改为对输出做上下文感知编码(htmlspecialchars ENT_QUOTES)。
  2. 删除式过滤还可能破坏业务数据(用户输入含 </> 会被静默篡改),属反模式。
  3. 纵深防御:加 CSP 头,禁止 unsafe-inline 脚本执行。

五、备注

  • 该关在所有 PHP 版本均可利用。
  • 审计启示: "过滤特殊字符" ≠ "安全";正确姿势是"编码输出 + 最小化特权(CSP)"。
正文完
 0