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

37次阅读
没有评论

xss-labs Level17 代码审计报告

目标文件: level17.php | 漏洞类型: Flash XSS —— <embed> 将用户输入透传给第三方 SWF 的 flashvars | CWE: CWE-79 / CWE-676(使用含已知漏洞/已废弃组件) | 危害等级: 中危(历史性,现代浏览器不可利用,见备注)
风险路径: GET /level17.php?arg01=a&arg02=<payload> → xsf01.swf?arg01=..&arg02=.. → SWF flashvars 注入


一、漏洞代码定位

level17.php 第 16 行:

echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";

漏洞点: 整行。arg01/arg02 两个用户参数直接拼进 <embed> 的 SWF 加载 URL 的查询串,成为该 SWF 的 flashvars,全程无任何校验/白名单。


二、漏洞原理

  • <embed src="xsf01.swf?arg01=...&arg02=...">: 浏览器请求 SWF 时会把查询串交给 Flash 运行时,SWF 通过 _root/loaderInfo.parameters 读取这些 flashvars。
  • htmlspecialchars 只做 HTML 实体转义(浏览器解析时会把 &amp; 还原成 &),不会阻止 flashvars 传递,攻击者可:
    1. 控制 arg01/arg02 的值;
    2. 通过把 arg02 写成 b&<额外参数>=<值>(URL 编码后的 & 进入 arg02 值),注入任意数量的自定义 flashvars(如 clickTAG、ftClickThrough 等)。
  • 已对 xsf01.swf 反编译分析: 该 SWF 为 FlashTalking 广告 SDK(含 mainClick、ftLinkMode、ftStatBaseURL、_url、customTracking_* 等参数),该类广告 SDK 的 flashvars 中 URL 类参数会被其内部 getURL/navigateToURL 用于跳转,历史上存在通过 javascript: 协议执行任意 JS 的公开漏洞(CWE-79/Flash gadget)。
  • 具体可利用参数名需对该 SWF 做反编译(如 FFDec/jpff 反编译 ActionScript)确认;本报告给出代表性 payload 与验证方法。

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

注入思路: 向 arg02 追加 &<gadget参数>=javascript:...,使其成为 SWF 的 flashvars。

代表性 Payload(URL 解码后):

?arg01=a&arg02=b&clickTAG=javascript:alert(1)

(arg02 实际取值 b&clickTAG=javascript:alert(1),其中 & 需编码为 %26 以被 PHP 当作 arg02 的值,而非拆成独立 GET 参数。)

Yakit 可重放原始请求:

GET /level17.php?arg01=a&arg02=b%26clickTAG%3Djavascript:alert(1) HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: text/html
Connection: close

触发方式: 页面加载后嵌入的 SWF 读取到注入的 flashvar,在用户点击广告区域(或特定交互)时执行 javascript:alert(1)。是否自动触发取决于该 SDK 具体实现(通常为点击触发)。

验证建议: 用 Yakit 重放后查看响应中的 <embed src="xsf01.swf?arg01=a&arg02=b&clickTAG=javascript:alert(1)"...>;再对 xsf01.swf 反编译,确认其 URL 类参数的读取与 getURL 调用点,替换参数名后实测。


四、修复建议

// 1. 根本修复:移除 Flash 组件(Flash 已于 2020 年 EOL,不应再使用)
// 2. 若暂不能移除:绝不允许把用户参数透传给 SWF
$arg01 = preg_match('/^[a-zA-Z0-9]{1,32}$/', $_GET['arg01'] ?? '') ? $_GET['arg01'] : 'a';
$arg02 = preg_match('/^[a-zA-Z0-9]{1,32}$/', $_GET['arg02'] ?? '') ? $_GET['arg02'] : 'b';
// 仅允许字母数字,彻底阻断 flashvars 注入
echo '<embed src="xsf01.swf?arg01='.$arg01.'&arg02='.$arg02.'" width=100% height=100%>';
// 3. 输出侧:属性加引号 + 编码,避免引号逃逸

要点:

  1. 使用已废弃且有历史漏洞的 Flash 组件本身即安全债(CWE-676/1104);长期方案是迁移到 HTML5 视频/富媒体并移除 SWF 依赖。
  2. 透传给第三方可执行组件的参数必须强校验白名单(严格字符集/长度),不允许携带 &、=、: 等结构字符。
  3. 若必须保留下发参数,由服务端按业务构造完整的、不可被客户端改写的 flashvars。

五、备注

  • 可利用性说明(重要): Flash Player 已停止支持,主流浏览器(Chrome 88+、Edge 88+、Firefox 84+、Safari 14+)已彻底移除 Flash 运行时。因此本关及 level18-20 在当前浏览器中已无法直接触发,属于历史性漏洞;审计价值在于识别"透传不可信输入给第三方可执行组件 + 引入含已知漏洞组件"的架构缺陷。
  • 反编译结论: xsf01.swf 为 FlashTalking 广告 SDK 压缩包(CWS 头,zlib 压缩),字符串中含 mainClick/ftLinkMode/ftStatBaseURL 等参数。
  • 通用教训: 只要参数被交到可执行运行时(Flash/小程序/插件),就必须按"可注入面"对待,HTML 转义不能代表任何防护。
正文完
 0