视频教程在我主页简介或专栏里
(不懂都可以来问我 专栏找我哦)
今天分享如何使用 十六进制溢出 绕过 BIG-IP Local Traffic Manager (F5 Networks) Web 应用防火墙(WAF) 的过程。
整个过程看似是一个顺畅的流程,但实际上,情况是相反的。更像是 先解决问题 ,然后再去理解 问题的本质。
XSS 攻击
最初,我注意到输入内容 未经过适当的过滤,于是我尝试了一个简单的 XSS 负载:
<svg onload=alert()>
结果,这个 payload 立即被拦截。
![](https://i-blog.csdnimg.cn/img_convert/8ede8b664c1ca1ecaf4d1e77837436c0.png)
于是,我开始不断尝试不同的输入,直到绕过拦截,最终发现 <svg onload>
可以成功通过。这意味着 onload=
(带等号) 其实是被拦截的。 看到这个情况后,我尝试了所有可能的事件处理程序,但没有一个成功。到此就没办法了吗?
引入------十六进制溢出(Hex Overflow)
十六进制(Hexadecimal) 是一种 以 16 为基数的数值系统 ,由 0-F 组成(即 0123456789ABCDEF ),其最大值为 FF 。 在 URL 编码中,根据 [RFC 1738 2.2[1]],保留字符或不安全字符 会被编码为 % 符号后跟随两个十六进制数字。例如,%23
代表 #
(井号/片段符号)。
十六进制溢出(Hex Overflow) 发生在错误实现的 URL 解码器 解析 URL 时,如果它允许超出 0-F
范围的字符(包括符号 [] { } ; : < > ! &
等),就会导致解析异常。
在我测试的目标系统上,解码器的行为非常混乱,完全不符合常规逻辑 。 它甚至可能使用了多种不同的解码逻辑,输出的字符全部变成小写,进一步增加了困惑。
那么,当你输入 %5% 时,预期会得到什么?
输出结果竟然是 :e
(即 0x55
)。你可能会好奇,为什么会这样?
解析器的处理过程如下:
1.解析器读取 %5
作为第一个部分,然后遇到了第二个 %
符号。
2.它将第二个 %
重新编码成 %25
,然后忽略 第一部分的 2
,只取 5
,最终变成 %55
。
3.由于这个字符属于溢出字符(Overflow Character) ,解析器会对结果的第一部分做 -1
处理 ,将 %55
变成 %45
,即大写字母 E
。
4.最终 %7%
解析为 %65
,即大写字母 E
。
同理:
%8%
→ %75
,即小写 u
%6%
→ %55
,即大写 U
。
那么,解析器如何处理十六进制中的字母呢?
在第一阶段 ,它能正常解析 abcdef
,但当发生溢出时,它会将字母当作索引处理 ,并且从 g
开始计数 0
。
![](https://i-blog.csdnimg.cn/img_convert/ad98411ca43a5720bcbeccce712cb3f0.png)
经过进一步观察,我发现这些字符可以分为两组不同的集合。而当它们混合使用时,情况会变得更加有趣,就像这样:
![](https://i-blog.csdnimg.cn/img_convert/bdd7d4d3c8a50559954efd736102123b.png)
如果两个集合中的字符被一起使用,并且其中一个字符来自绿色集合,那么第一位十六进制数字(nibble)会增加 1。例如,输入 %5g
,按照此表 %5g
解析为 %50
,但由于绿色集合的影响,最终输出 %(5+1)0
或 %60
,即反引号 `。
同样,如果输入 %hz
(其中 h 来自第二个集合),按照表格 %hz
解析为 %13
,但由于溢出机制,最终输出 %(1+2)3
或 %33
,即字符 '3'。
但是这种模式并不总是固定的,完整的工作流程也无法完全计算。有时会增加 1,有时会增加 2 或 3,而某些情况下第一位十六进制数字甚至会被减去。但即使如此,这些信息已经足够用于绕过 WAF。
绕过 WAF
在最初的测试中,我们发现几乎没有办法绕过 WAF,因为所有的事件处理程序都被屏蔽了,因此我们需要寻找其他方法。
利用 Hex Overflow ,我们可以用许多不同的方法来表示单个 ASCII 字符。例如,等号 =
(十六进制 %3d )也可以用 %3=
表示,其解释方式为 %3
%3d
,其中第一个 %3
被解析器忽略,使其仍然等于 %3d
。
此外,还可以使用 %zd
、%z=
、%jd
、%it
(在某些情况下第一位十六进制数字会被 -1 处理)。
因此,我们可以利用这些等价表示来绕过 WAF,例如:
<svg onload%jdonload=alert()>
![](https://i-blog.csdnimg.cn/img_convert/100d39d868c678db37be71045310beb6.png)
img
它再次拦截了我们的 Payload,原因?这次是 alert() 函数被屏蔽了。
这个问题可以通过 可选链(optional chaining) 轻松绕过 → alert?.()。
![](https://i-blog.csdnimg.cn/img_convert/f8ed69a33d1be9ac0875c11cd68405c5.png)
不仅仅限于此,使用许多其他方式也可以绕过,通过使用 Hex Overflow 生成 Payload 的不同部分,比如 %0d (CR) 转换为 '%0=' 或 '%w=' ,从而使 Payload 变为 <svg onload%w==alert()>。
结论
不过这种存在缺陷的解码器非常罕见,并且可能并非所有解码器都有相同的缺陷。
视频教程在我主页简介或专栏里
(不懂都可以来问我 专栏找我哦)
申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关