ksmbd streams_xattr OOB write → local LPE (CVE-2025-37947)
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.
Esta página documenta uma escrita determinística fora dos limites em o tratamento de streams do ksmbd que permite uma escalada confiável de privilégios no kernel Linux no Ubuntu 22.04 LTS (5.15.0-153-generic), contornando KASLR, SMEP e SMAP usando primitivas padrão de heap do kernel (msg_msg + pipe_buffer).
- Componente afetado: fs/ksmbd/vfs.c — ksmbd_vfs_stream_write()
- Primitive: page-overflow OOB write além de um buffer kvmalloc() de 0x10000 bytes
- Pré-requisitos: ksmbd em execução com um share autenticado e gravável usando vfs streams_xattr
Example smb.conf
[share]
path = /share
vfs objects = streams_xattr
writeable = yes
Causa raiz (allocation clamped, memcpy at unclamped offset)
- A função calcula size = *pos + count, faz clamp de size para XATTR_SIZE_MAX (0x10000) quando excedido, e recalcula count = (*pos + count) - 0x10000, mas ainda assim executa memcpy(&stream_buf[*pos], buf, count) em um buffer de 0x10000 bytes. Se *pos ≥ 0x10000, o ponteiro de destino já está fora da allocation, produzindo um OOB write de count bytes.
streams_xattrarmazena SMB alternate data streams dentro de POSIX extended attributes, então o teto de 0x10000 vem do Linux single-xattr size limit e não de um campo do protocolo SMB. Isso torna o bug prático apenas quando o share habilita explicitamentevfs objects = streams_xattre o filesystem suporta xattrs.
Por que o write offset importa
- O caminho vulnerável não é apenas “escrever mais que 64KiB”. A checagem ausente era que
*posnão era validado contra o tamanho atual do stream (v_len) antes da lógica de append/copy rodar. - Upstream corrigiu isso rejeitando writes em que
*pos >= v_lencom-EINVAL. Antes do fix, um atacante podia reutilizar um handle autenticado válido para um named stream e enviar um SMB2 WRITE bruto cujofile_offsetjá aponta para ou além do fim do stream existente, o que transforma omemcpy()pós-clamp em um page overflow determinístico. - A PoC pública demonstra isso autenticando com
libsmb2, abrindo um path de stream como1337:, extraindoSessionId/TreeId/FileId, e então enviando um SMB2 WRITE montado manualmente comfile_offset = 0x10018e umLengthpequeno.
Trecho da função vulnerável (ksmbd_vfs_stream_write)
```c // https://elixir.bootlin.com/linux/v5.15/source/fs/ksmbd/vfs.c#L411 static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, size_t count) { char *stream_buf = NULL, *wbuf; size_t size; ... size = *pos + count; if (size > XATTR_SIZE_MAX) { // [1] clamp allocation, but... size = XATTR_SIZE_MAX; count = (*pos + count) - XATTR_SIZE_MAX; // [1.1] ...recompute count } wbuf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO); // [2] alloc 0x10000 stream_buf = wbuf; memcpy(&stream_buf[*pos], buf, count); // [3] OOB when *pos >= 0x10000 ... kvfree(stream_buf); return err; } ```Offset steering and OOB length
- Exemplo: defina o offset do arquivo (pos) para 0x10018 e o length original (count) para 8. Após o clamping, count’ = (0x10018 + 8) - 0x10000 = 0x20, mas memcpy escreve 32 bytes começando em stream_buf[0x10018], ou seja, 0x18 bytes além da alocação de 16 páginas.
Triggering the bug via SMB streams write
- Use a mesma conexão SMB autenticada para abrir um arquivo no share e emitir uma write para um named stream (streams_xattr). Defina file_offset ≥ 0x10000 com um length pequeno para gerar uma OOB write determinística de tamanho controlável.
- libsmb2 pode ser usada para autenticar e montar writes desse tipo sobre SMB2/3.
- Na prática, reutilizar a sessão SMB negociada é conveniente porque o exploit só precisa alterar alguns campos dinâmicos no request WRITE (
TreeId,SessionId,FileId) e então pode transmitir o pacote malformado diretamente no mesmo socket.
Minimal reachability (concept)
// Pseudocode: send SMB streams write with pos=0x0000010018ULL, len=8
smb2_session_login(...);
smb2_open("\\\\host\\share\\file:stream", ...);
smb2_pwrite(fd, payload, 8, 0x0000010018ULL); // yields 32-byte OOB
Comportamento do allocator e por que o page shaping é necessário
- kvmalloc(0x10000, GFP_KERNEL|__GFP_ZERO) solicita uma alocação de ordem 4 (16 páginas contíguas) do buddy allocator quando o tamanho > KMALLOC_MAX_CACHE_SIZE. Isso não é um objeto de cache SLUB.
- memcpy ocorre imediatamente após a alocação; o spray pós-alocação é ineficaz. Você deve pre-groom da memória física para que um target escolhido fique imediatamente após o bloco alocado de 16 páginas.
- No Ubuntu, GFP_KERNEL frequentemente aloca a partir do tipo de migração Unmovable em zone Normal. Exaure as freelists de ordem 3 e ordem 4 para forçar o allocator a dividir um bloco de ordem 5 em um par adjacente de ordem 4 + ordem 3, e então posicione um slab de ordem 3 (kmalloc-cg-4k) diretamente após o stream buffer.
Estratégia prática de page shaping
- Faça spray de ~1000–2000 objetos msg_msg de ~4096 bytes (encaixa em kmalloc-cg-4k) para popular slabs de ordem 3.
- Receba algumas mensagens para abrir holes e incentivar a adjacência.
- Dispare o ksmbd OOB repetidamente até que o stream buffer de ordem 4 caia imediatamente antes de um slab msg_msg. Use eBPF tracing para confirmar endereços e alinhamento, se disponível.
Observability útil
# Check per-order freelists and migrate types
sudo cat /proc/pagetypeinfo | sed -n '/Node 0, zone Normal/,/Node/p'
# Example tracer (see reference repo) to log kvmalloc addresses/sizes
sudo ./bpf-tracer.sh
O que rastrear durante o tuning
kvmalloc_node(0x10000)confirma quando a escrita vulnerable em stream realmente consome uma alocação de ordem-4.load_msg/kretprobe:load_msgpermite estimar quantas alocaçõesmsg_msgsegestão anexadas a cada mensagem sprayed, o que é útil ao ajustar os tamanhos de mensagem primária/secundária para uma build específica do kernel.- Se o exploit for portado para outra distro/kernel, verifique novamente nomes de cache, tamanhos de payload inline de
msg_msg, offsets deanon_pipe_buf_opse endereços de gadget em vez de assumir que os constantes do Ubuntu 22.04 LTS5.15.0-153-genericainda correspondem.
Plano de exploitation (msg_msg + pipe_buffer), adaptado de CVE-2021-22555
- Faça spray de muitas mensagens System V
msg_msgprimárias/secundárias (tamanho de 4KiB para caber em kmalloc-cg-4k). - Dispare o OOB do ksmbd para corromper o ponteiro next de uma mensagem primária, de forma que duas primárias compartilhem uma secundária.
- Detecte o par corrompido marcando filas e fazendo scan com
msgrcv(MSG_COPY)para encontrar tags incompatíveis. - Liberte a secundária real para criar um UAF; reocupe-a com dados controlados via sockets UNIX (crie um
msg_msgfalso). - Faça leak de ponteiros da heap do kernel abusando do over-read de
m_tsemcopy_msgpara obtermlist.next/mlist.prev(SMAP bypass). - Com um spray de
sk_buff, reconstrua ummsg_msgfalso consistente com links válidos e liberte-o normalmente para estabilizar o estado. - Reocupe o UAF com objetos
struct pipe_buffer; faça leak deanon_pipe_buf_opspara calcular a base do kernel (derrote KASLR). - Faça spray de um
pipe_buf_operationsfalso comreleaseapontando para um stack pivot/ROP gadget; feche os pipes para executar e obter root.
Bypasses and notes
- KASLR: faça leak de
anon_pipe_buf_ops, calcule a base (kbase_addr) e os endereços dos gadgets. - SMEP/SMAP: execute ROP no contexto do kernel via o fluxo
pipe_buf_operations->release; evite dereferências em userspace até depois da cadeiadisable/prepare_kernel_cred/commit_creds. - Hardened usercopy: não se aplica a este primitive de overflow de página; os alvos da corrupção são campos não relacionados a usercopy.
Reliability
- Alta uma vez que a adjacência é obtida; falhas ocasionais ou panics (<10%). Ajustar sprays e contagens de free melhora a estabilidade. Sobrescrever os 2 LSBs de um ponteiro para induzir colisões específicas foi relatado como eficaz (por exemplo, escrever o padrão
0x0000_0000_0000_0500no overlap).
Parâmetros-chave para tuning
- Número de sprays de
msg_msge padrão de holes - Offset do OOB (
pos) e o comprimento OOB resultante (count') - Número de sprays de sockets UNIX,
sk_buffepipe_bufferdurante cada etapa
Mitigações e alcançabilidade
- Correção: limitar tanto a alocação quanto o destino/comprimento, ou impor limite ao
memcpycontra o tamanho alocado; patches upstream acompanham como CVE-2025-37947. - Exploração remota exigiria adicionalmente um infoleak confiável e heap grooming remoto; este texto foca em LPE local.
See also
Ksmbd Attack Surface And Fuzzing Syzkaller
References PoC and tooling
- libsmb2 para autenticação SMB e writes de streams
- script tracer eBPF para registrar endereços de
kvmalloce histogramar alocações (por exemplo,grep 4048 out-4096.txt) - Um PoC mínimo de alcançabilidade e o exploit local completo estão publicamente disponíveis (ver References)
References
- ksmbd - Exploiting CVE-2025-37947 (3/3) — Doyensec
- Linux upstream fix:
ksmbd: prevent out-of-bounds stream writes by validating *pos - KSMBD-CVE-2025-37947 PoC repository
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.


