Exif注入
Exif 注入 (Exif Injection)是一种网络安全攻击技术。攻击者将恶意代码(如 PHP 脚本、JavaScript 等)隐藏在图片文件的Exif 元数据中,并利用目标系统对这些数据的处理缺陷,最终在服务器或用户的浏览器上执行恶意代码。
Exif 是什么?
Exif(Exchangeable Image File Format)是专门为数码照片设定的标准,用于记录照片的属性信息和拍摄数据。当你用手机或相机拍照时,文件内不仅包含图像本身,还包含很多文本标签(字段),例如:
- 相机品牌和型号 (Make / Model)
- 拍摄时间和日期
- GPS 地理位置信息
- 图像描述或备注 (Comment)
- 作者/艺术家 (Artist)
攻击者通常会使用类似exiftool的命令行工具,篡改一张正常图片中的 Exif 字段,将恶意 Payload 写入原本应该存放普通文本的地方。
例如,攻击者可以将一段 PHP 一句话木马写入图片的Comment(备注)字段:
exiftool-Comment="<?php system($_GET['cmd']); ?>"malicious.jpg经过修改后,malicious.jpg依然是一张可以正常打开的图片,但它的内部结构中已经潜伏了恶意代码。
常见的攻击与利用场景
Exif 注入本身相当于一个“特洛伊木马”,它通常需要结合目标网站的其他漏洞才能触发实质性的危害。以下是两种最经典的利用场景:
1. 结合文件包含漏洞 (LFI) 导致远程代码执行 (RCE)
这是 Exif 注入最危险的利用方式。
- 上传木马:目标网站可能对上传文件有严格的后缀名检查(仅允许
.jpg,.png),但由于修改了 Exif 的图片本质上仍是合法的图片格式,因此可以轻易绕过上传验证并保存在服务器上。 - 触发执行:如果该网站同时存在本地文件包含漏洞 (LFI)(例如代码中使用了不受信任的变量:
include($_GET['page']);),攻击者就可以通过 LFI 去“包含”刚才上传的图片(如?page=uploads/malicious.jpg)。 - 最终结果:当 PHP 引擎解析被包含的文件时,它会跳过图片的二进制乱码,一旦匹配到 Exif 数据中隐藏的
<?php ... ?>标签,就会将其作为后端的代码强制执行,导致服务器被攻陷。
2. 导致存储型跨站脚本攻击 (Stored XSS)
- 注入脚本:攻击者在 Exif 字段中注入恶意的 JavaScript 代码,例如
<script>alert(document.cookie)</script>。 - 触发执行:许多摄影社区或博客网站会自动读取用户上传图片的 Exif 信息,并在前端页面上展示(例如显示“照片由某某相机拍摄”)。如果网站后端在提取和存储这些 Exif 数据时没有进行过滤,前端在展示时也没有进行 HTML 实体转义。
- 最终结果:恶意脚本会被直接渲染在网页中。任何访问该页面的其他用户都会在其浏览器中执行这段恶意代码,可能导致会话劫持(Cookie 窃取)或账号被盗用。
防御与修复建议
要防范 Exif 注入,开发者在处理用户上传的媒体文件时应遵循以下安全实践:
- 强制剥离元数据 (Metadata Stripping):最根本的防御方法是在图片上传后,使用图像处理库(如 PHP 的 GD 库,或 Python 的 Pillow)重新渲染该图片,或者使用专用工具彻底清除图片中的所有 Exif 信息,然后再保存到服务器。
- 目录权限控制:确保存放用户上传文件的目录(例如
/uploads/)没有脚本执行权限。在 Web 服务器(如 Nginx 或 Apache)中配置该目录,禁止解析任何动态脚本(如.php)。 - 严格的数据转义:如果业务场景确实需要读取并展示图片的 Exif 信息,必须将其视为“不可信的用户输入”。在前端页面输出之前,务必进行严格的 XSS 过滤和 HTML 实体转义。
案例演示
这里拿xss-labs靶场的第14关来作为演示:
查看前端源码
既然前端是一个标准的<input type="file">,我们就来实打实地造一个“带毒”的图片。
随便找一张图片,修改它的 EXIF 信息,将作者名改成:"><script>alert(1)</script>(带上">是为了防止后端将信息输出在某个标签属性里,有备无患)。 我们使用kali自带的 ExifTool 工具。
