文章总结: PixelSmash是FFmpegMagicYUV解码器中的高危漏洞(CVE-2026-8461),攻击者通过50KB恶意视频文件可在Jellyfin、Nextcloud等媒体服务器实现远程代码执行。漏洞根因为色度平面行数计算不一致导致堆越界写入,进而劫持AVBuffer函数指针。建议立即升级FFmpeg或禁用MagicYUV解码器。 综合评分: 87 文章分类: 漏洞分析,WEB安全,应用安全,供应链安全,云安全
PixelSmash:一个50KB的视频文件,如何让全球数百万服务器沦陷?
原创
利刃信安 利刃信安
利刃信安
2026年6月24日 10:30 北京
在小说阅读器读本章
去阅读
PixelSmash:一个50KB的视频文件,如何让全球数百万服务器沦陷?
摘要:2026年6月,JFrog安全研究团队披露了一个名为 PixelSmash(CVE-2026-8461,CVSS 8.8)的FFmpeg高危漏洞。攻击者只需上传一个精心构造的50KB AVI视频文件,即可在Jellyfin、Nextcloud等媒体服务器上实现远程代码执行,Kodi、mpv、OBS等桌面应用亦受波及导致崩溃。漏洞根因是MagicYUV解码器中一个看似微小的取整误差——帧分配器与解码器对色度平面行数的计算不一致,导致堆越界写入,进而劫持AVBuffer函数指针执行任意系统命令。
一、一个解码器Bug,打穿整个媒体生态
FFmpeg是全球部署最广泛的媒体处理框架。从桌面播放器(mpv、VLC)、自建媒体服务器(Jellyfin、Emby),到云转码管线(AWS MediaConvert)、Linux桌面环境(GNOME缩略图生成器),几乎所有涉及视频处理的应用都链接了FFmpeg的 libavcodec。
PixelSmash正是寄生在libavcodec的MagicYUV解码器中的一个堆越界写入漏洞。MagicYUV是一个面向高性能视频剪辑工作流的无损编码器,虽然不如H.264知名,但它的解码器默认编译进每一个FFmpeg构建,注册在AVI、MKV、MOV三种容器格式下。这意味着,任何能打开视频文件的应用,都可能触发这个解码器。
这是一起典型的软件供应链安全事件:一个底层依赖库中某个冷门编解码器的Bug,通过依赖链向上传播,波及数百个下游项目。Jellyfin、mpv、Nextcloud、Immich、OBS、vLLM等项目没有引入这个Bug,却因为依赖FFmpeg而被迫继承——且绝大多数项目缺乏独立检测或缓解该漏洞的能力。
受影响的不仅限于服务器:
| 场景 | 触发方式 | | — | — | | 桌面端 | 用户打开恶意视频文件,或仅浏览到包含该文件的文件夹(缩略图生成器即触发) | | 服务端 | 上传恶意文件至Jellyfin、Nextcloud、Discord等平台的媒体处理管线 | | 嵌入式/IoT | NAS设备(群晖、QNAP)、智能电视等自动生成视频缩略图的场景 |
无需认证、无需特权、无需预先访问——只需要交付一个媒体文件。
二、根因分析:差一行导致的堆溢出
2.1 背景知识:Slice与YUV色彩空间
在视频压缩中,Slice(切片) 是一帧内水平分割出的独立解码区域。数字视频不使用标准RGB,而是采用 YUV色彩空间:
- • Y(亮度平面):图像的明暗细节,人眼对此极其敏感;
- • U/V(色度平面):颜色信息,人眼对色度细节的敏感度远低于亮度。
在YUV420P等亚采样格式下,色度平面的垂直分辨率是亮度平面的一半。解码器需要将亮度行的Slice高度转换为色度行高度——这里用到了向上取整的右移运算(AV_CEIL_RSHIFT)。
而这个看似合理的取整,正是漏洞的根源。
2.2 致命的不一致
问题出在两个计算之间的分歧:
第一步:帧分配器计算色度缓冲区大小
// update_frame_pool (get_buffer.c)
allocated chroma rows = AV_CEIL_RSHIFT(FFALIGN(32, 32), 1) = 16
色度缓冲区只分配了 16行。
第二步:解码器从攻击者控制的比特流中读取slice_height
s->slice_height = bytestream2_get_le32u(&gb); // 攻击者填入 31
当 slice_height = 31、coded_height = 32 时:
nb_slices = (32 + 31 - 1) / 31 = 2; // 2个切片
int sheight = AV_CEIL_RSHIFT(31, 1) = 16; // 每个切片占用16色度行
第二个切片的目标地址:
dst = p->data[1] + 1 * 16 * stride; // 写入第16行(缓冲区只有0-15行!)
色度缓冲区只有行0-15(共16行),解码器却向第16行写入攻击者控制的数据——整行越界。
2.3 为什么校验没拦住?
现有校验代码(magicyuv.c:566-568)仅覆盖了隔行扫描模式:
if (s->interlaced) {
if ((s->slice_height >> s->vshift[1]) < 2)
// 仅隔行模式才有此校验
}
非隔行模式——也就是我们利用的路径——完全没有对齐检查。补丁仅需7行代码即可修复。
三、从堆溢出到远程代码执行
堆溢出本身能造成拒绝服务(DoS),但JFrog研究团队将其升级为可靠的任意命令执行。
3.1 攻击目标:AVBuffer结构体
FFmpeg的堆布局中,每个平面的像素数据之后紧邻着 AVBuffer——引用计数的缓冲区管理结构。当FFmpeg完成一帧解码后,调用 av_frame_unref → av_buffer_unref,引用计数归零时触发:
buf->free(buf->opaque, buf->data); // 通过堆上的函数指针间接调用
这是一个间接调用。如果能覆盖 buf->free 为 libc 的 system() 地址、buf->opaque 为shell命令字符串指针,那么:
system(cmd_string); // 攻击者的命令被执行
3.2 精确堆布局
640字节的越界写入恰好落在Cb色度平面的AVBuffer上(Jellyfin捆绑的jellyfin-ffmpeg 7.1.3):
OOB + 0: [88字节零值 —— 命令字符串槽位]
OOB + 88: [glibc堆块头部 —— 必须原样保留]
OOB + 256: AVBuffer结构体:
.data = Cb数据指针
.size = 0x284f
.refcount = 1 ← 写入1,令引用计数归零
.free = &system ← 覆盖为system地址
.opaque = &cmd ← 覆盖为命令字符串地址
当帧清理流程触发 av_buffer_unref 时,间接调用变成 system("攻击者命令")。fork出的shell子进程在执行命令后,父进程才因后续堆损坏崩溃——但攻击已经完成。
3.3 三个工程难题
- 1. 堆布局校准:利用GDB自动捕获越界前的精确堆状态,提取所有堆块元数据,生成”外科手术级”的利用文件。
- 2. 保留glibc堆完整性:640字节越界区域内包含33个glibc堆块头部(空闲链表指针、块大小、PREV_INUSE标志),任何一个损坏都会触发glibc完整性检查导致进程终止,必须逐字节原样保留。
- 3. Cr平面越界保护:Cr色度平面同样存在越界写入,其越界区域包含tcache条目和glibc top chunk,top chunk大小若被破坏,
system()内部的fork()/exec()会失败,因此必须编码保留Cr平面的堆元数据。
四、真实攻击演示:Jellyfin服务器沦陷
JFrog团队在 Jellyfin 10.11.9(仅次于Plex的第二大自建媒体服务器)上实现了完整的远程代码执行:
已关注
关注
重播 分享 赞
关闭
观看更多
更多
退出全屏
切换到竖屏全屏退出全屏
利刃信安已关注
分享视频
,时长00:52
0/0
00:00/00:52
切换到横屏模式
继续播放
[ ]
进度条,百分之0
播放
00:00
/
00:52
00:52
倍速
全屏
倍速播放中
0.5倍 0.75倍 1.0倍 1.5倍 2.0倍
超清 流畅
继续观看
PixelSmash:一个50KB的视频文件,如何让全球数百万服务器沦陷?
观看更多
原创
,
PixelSmash:一个50KB的视频文件,如何让全球数百万服务器沦陷?
利刃信安已关注
分享点赞在看
已同步到看一看写下你的评论
视频详情
- • 攻击路径:通过Jellyfin的媒体库自动扫描功能,上传一个50KB的恶意AVI文件;
- • 结果:Jellyfin后台FFmpeg进程自动解码该文件 → 触发越界写入 → 劫持AVBuffer → 执行反向Shell命令;
- • Nextcloud 上同样验证了通过视频预览提供者的RCE攻击。
关于ASLR的说明:演示中关闭了ASLR。在默认启用ASLR的环境下,由于需要硬编码system()地址,该利用无法直接落地。研究团队同时发现FFmpeg的FlashSV解码器存在一个未初始化堆内存泄露(自2022年7月存在至今),理论上可配合PixelSmash绕过ASLR,但完整链路尚未演示。
五、检测与修复
检测是否受影响
ffmpeg -decoders 2>/dev/null | grep magicyuv
若输出包含 VFS..D magicyuv,说明你的FFmpeg构建存在漏洞。MagicYUV解码器在所有主流发行版(Ubuntu、Debian、Fedora、Arch、Alpine)的FFmpeg包中默认启用。
修复方案一:升级
升级至FFmpeg官方修复版本。
修复方案二:禁用解码器
./configure --disable-decoder=magicyuv [其他参数]
make && make install
修复方案三:最小补丁
在 libavcodec/magicyuv.c 中增加7行校验,拒绝非法的 slice_height 值。正常MagicYUV编码器始终产生对齐的Slice高度,此补丁仅拦截恶意输入。
六、结语
PixelSmash再次印证了一个安全铁律:底层基础设施中一行代码的疏忽,足以摧毁整个上层应用生态的安全假设。 FFmpeg作为互联网媒体处理的基石,其代码质量直接影响数亿终端和百万服务器的安全边界。
对于安全从业者,这个案例提醒我们关注四件事:供应链依赖中冷门组件的攻击面、编解码器解析外部输入路径的覆盖度、堆元数据在利用中的关键角色、以及纵深防御中ASLR等缓解措施的实际价值。
对于运维和开发者,一句话建议:检查你的FFmpeg版本,立刻升级。
参考来源:JFrog Blog – PixelSmash: Critical FFmpeg Vulnerability Turns Media Files into Weapons[1]
引用链接
[1] JFrog Blog – PixelSmash: Critical FFmpeg Vulnerability Turns Media Files into Weapons: https://jfrog.com/blog/pixelsmash-critical-ffmpeg-vulnerability-turns-media-files-into-weapons/
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:利刃信安 利刃信安 利刃信安《PixelSmash:一个50KB的视频文件,如何让全球数百万服务器沦陷?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论