从PNG tEXt到存储型XSS
字数 1200 2025-08-18 11:37:15

PNG tEXt 块到存储型XSS漏洞利用技术详解

漏洞背景

本教学文档详细分析了一种通过PNG图像文件的tEXt块实现存储型XSS攻击的技术。这种攻击方式特别适用于那些严格限制上传文件类型(仅允许PNG)但又能通过特定方式解析上传文件的网站系统。

漏洞发现过程

初始测试环境

  • 目标站点有严格的文件上传过滤机制,只接受.PNG扩展名
  • 意外发现一个上传点允许上传带有.html扩展名的文件

初步尝试

  1. 尝试直接上传包含HTML内容的伪PNG文件:
    {
      "Name": "image.png.html",
      "Data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
    }
    
    • 这是一个简单的1像素红点PNG图像
    • 尝试修改数据类型为data:htmlurl等,但验证失败
    • 直接修改PNG内容为非合法PNG也会导致验证失败

技术难点

  • 系统会解码Base64并执行内容
  • 尝试在Base64末尾添加"/><script>alert("xss");</script>,但JS未执行
  • 系统可能检查PNG的魔术字节头(前8个字节应为0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A

绕过尝试

  1. 构造包含魔术字节的"假"PNG,并附加XSS代码:

    • 验证仍然失败
    • 推测系统使用.NET的Image.FromStream方法验证图像有效性
  2. 尝试在合法PNG的不同位置插入XSS代码字节数组:

    • 通过迭代方式在位置1、位置2...插入或追加
    • 所有尝试均未成功

成功利用技术

PNG tEXt块特性

  • PNG规范允许通过tEXt块添加文本元数据(如版权、标题等)
  • 这是PNG文件的合法组成部分,不会影响图像有效性

利用工具

使用ImageMagick工具注入恶意tEXt块:

convert Head_red.png \
  -set 'Copyright' '/><script>alert("1");</script>' \
  -set 'Title' '/><script>alert("2");</script>' \
  -set comment '/><script>alert("3");</script>' \
  OUT.png

攻击步骤

  1. 创建包含恶意tEXt块的PNG文件
  2. 通过允许上传.html文件的上传点提交文件:
    {
      "Name": "image.png.html",
      "Data": "data:image/png;base64,<恶意PNG的Base64编码>"
    }
    
  3. 系统解码Base64并生成HTML页面
  4. 当用户访问该HTML页面时,嵌入在tEXt块中的XSS代码被执行

防御建议

  1. 输入验证

    • 严格验证上传文件的真实类型(检查魔术字节)
    • 不仅验证文件扩展名,还要验证实际内容
  2. 内容过滤

    • 对PNG等图像文件中的元数据进行检查和过滤
    • 移除或转义可能危险的tEXt块内容
  3. 输出编码

    • 在显示用户上传内容时进行适当的HTML编码
  4. 文件处理

    • 在处理上传文件时,使用安全的API和方法
    • 考虑重新编码或清理上传的图像文件
  5. 扩展检查

    • 不要仅依赖文件扩展名判断文件类型
    • 实现多层次的验证机制

扩展风险

  • 类似漏洞不仅存在于PNG文件,JPEG、GIF等图像格式也支持元数据块
  • 许多非图像文件类型也可能包含可执行内容
  • 开发人员应全面考虑各种文件类型的潜在风险

总结

本技术展示了如何利用PNG规范中的合法特性(tEXt块)绕过严格的文件上传限制,实现存储型XSS攻击。这种攻击方式特别隐蔽,因为它使用的是完全符合规范的PNG文件。防御此类攻击需要多层次的验证和过滤机制,而不仅仅是简单的文件扩展名检查。

PNG tEXt 块到存储型XSS漏洞利用技术详解 漏洞背景 本教学文档详细分析了一种通过PNG图像文件的tEXt块实现存储型XSS攻击的技术。这种攻击方式特别适用于那些严格限制上传文件类型(仅允许PNG)但又能通过特定方式解析上传文件的网站系统。 漏洞发现过程 初始测试环境 目标站点有严格的文件上传过滤机制,只接受 .PNG 扩展名 意外发现一个上传点允许上传带有 .html 扩展名的文件 初步尝试 尝试直接上传包含HTML内容的伪PNG文件: 这是一个简单的1像素红点PNG图像 尝试修改数据类型为 data:html 或 url 等,但验证失败 直接修改PNG内容为非合法PNG也会导致验证失败 技术难点 系统会解码Base64并执行内容 尝试在Base64末尾添加 "/><script>alert("xss");</script> ,但JS未执行 系统可能检查PNG的魔术字节头(前8个字节应为 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A ) 绕过尝试 构造包含魔术字节的"假"PNG,并附加XSS代码: 验证仍然失败 推测系统使用.NET的 Image.FromStream 方法验证图像有效性 尝试在合法PNG的不同位置插入XSS代码字节数组: 通过迭代方式在位置1、位置2...插入或追加 所有尝试均未成功 成功利用技术 PNG tEXt块特性 PNG规范允许通过tEXt块添加文本元数据(如版权、标题等) 这是PNG文件的合法组成部分,不会影响图像有效性 利用工具 使用ImageMagick工具注入恶意tEXt块: 攻击步骤 创建包含恶意tEXt块的PNG文件 通过允许上传.html文件的上传点提交文件: 系统解码Base64并生成HTML页面 当用户访问该HTML页面时,嵌入在tEXt块中的XSS代码被执行 防御建议 输入验证 : 严格验证上传文件的真实类型(检查魔术字节) 不仅验证文件扩展名,还要验证实际内容 内容过滤 : 对PNG等图像文件中的元数据进行检查和过滤 移除或转义可能危险的tEXt块内容 输出编码 : 在显示用户上传内容时进行适当的HTML编码 文件处理 : 在处理上传文件时,使用安全的API和方法 考虑重新编码或清理上传的图像文件 扩展检查 : 不要仅依赖文件扩展名判断文件类型 实现多层次的验证机制 扩展风险 类似漏洞不仅存在于PNG文件,JPEG、GIF等图像格式也支持元数据块 许多非图像文件类型也可能包含可执行内容 开发人员应全面考虑各种文件类型的潜在风险 总结 本技术展示了如何利用PNG规范中的合法特性(tEXt块)绕过严格的文件上传限制,实现存储型XSS攻击。这种攻击方式特别隐蔽,因为它使用的是完全符合规范的PNG文件。防御此类攻击需要多层次的验证和过滤机制,而不仅仅是简单的文件扩展名检查。