Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
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
virtualbox_e1000_0day — Escape de Convidado para Anfitrião no VirtualBox E1000 | Kitploit
Ferramentas/GitHubGitHub/mortenoir1/virtualbox_e1000_0day
Análise de VulnerabilidadesExploraçãoTestes de PenetraçãoSegurança de HardwareExploração de Binários
GitHubmortenoir1/virtualbox_e1000_0day

virtualbox_e1000_0day

Escape de Convidado para Anfitrião no VirtualBox E1000

Ver Repositório
1.4k19622há 7 anosRevisado pelo Kitploit

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

Porquê

Gosto do VirtualBox e isso não tem nada a ver com o motivo pelo qual publico uma vulnerabilidade 0day. A razão é o meu desacordo com o estado contemporâneo da segurança da informação, especialmente da pesquisa de segurança e bug bounty:

  1. Esperar meio ano até que uma vulnerabilidade seja corrigida é considerado aceitável.
  2. No campo de bug bounty, isto é considerado aceitável:
    1. Esperar mais de um mês até que uma vulnerabilidade submetida seja verificada e uma decisão de comprar ou não seja tomada.
    2. Mudar a decisão em tempo real. Hoje descobre-se que o programa de bug bounty comprará bugs num software, uma semana depois chega-se com bugs e exploits e recebe-se "não interessado".
    3. Não ter uma lista precisa dos softwares em que o bug bounty tem interesse em comprar bugs. Conveniente para os bug bounties, inconveniente para os investigadores.
    4. Não ter limites inferior e superior precisos dos preços das vulnerabilidades. Há muitas coisas que influenciam um preço, mas os investigadores precisam de saber o que vale a pena trabalhar e o que não vale.
  3. Ilusões de grandeza e tretas de marketing: nomear vulnerabilidades e criar websites para elas; fazer milhares de conferências por ano; exagerar a importância do próprio trabalho como investigador de segurança; considerar-se "um salvador do mundo". Desça do pedestal, Vossa Alteza.

Estou exausto dos dois primeiros, portanto a minha jogada é divulgação total. SegInfo, por favor, avance.

Informações Gerais

Software vulnerável: VirtualBox 5.2.20 e versões anteriores.

SO anfitrião: qualquer, o bug está numa base de código partilhada.

SO convidado: qualquer.

Configuração da VM: padrão (o único requisito é que a placa de rede seja Intel PRO/1000 MT Desktop (82540EM) e o modo seja NAT).

Como se proteger

Até que a versão corrigida do VirtualBox seja lançada, pode alterar a placa de rede das suas máquinas virtuais para PCnet (uma das duas) ou para Rede Paravirtualizada. Se não puder, altere o modo de NAT para outro. A primeira forma é mais segura.

Introdução

O dispositivo de rede virtual padrão do VirtualBox é Intel PRO/1000 MT Desktop (82540EM) e o modo de rede padrão é NAT. Referir-nos-emos a ele como E1000.

O E1000 tem uma vulnerabilidade que permite a um atacante com privilégios de root/administrador num convidado escapar para o ring3 do anfitrião. Depois, o atacante pode usar técnicas existentes para escalar privilégios para ring 0 via /dev/vboxdrv.

Detalhes da Vulnerabilidade

E1000 101

Para enviar pacotes de rede, um convidado faz o que um PC comum faz: configura uma placa de rede e fornece pacotes de rede para ela. Os pacotes são frames da camada de enlace de dados e outros cabeçalhos de nível superior. Os pacotes fornecidos ao adaptador são envolvidos em descritores Tx (Tx significa transmissão). O descritor Tx é uma estrutura de dados descrita na folha de dados do 82540EM (317453006EN.PDF, Revisão 4.0). Ele armazena meta-informações como tamanho do pacote, tag VLAN, flags de segmentação TCP/IP ativadas, etc.

A folha de dados do 82540EM prevê três tipos de descritores Tx: legacy, contexto, dados. Legacy está obsoleto, acredito. Os outros dois são usados juntos. A única coisa com que nos importamos é que os descritores de contexto definem o tamanho máximo do pacote e ativam a segmentação TCP/IP, e que os descritores de dados contêm endereços físicos dos pacotes de rede e seus tamanhos. O tamanho do pacote do descritor de dados deve ser menor que o tamanho máximo do pacote do descritor de contexto. Normalmente, os descritores de contexto são fornecidos à placa de rede antes dos descritores de dados.

Para fornecer descritores Tx à placa de rede, um convidado escreve-os no Tx Ring. Este é um buffer circular residente na memória física num endereço predefinido. Quando todos os descritores são escritos no Tx Ring, o convidado atualiza o registo MMIO TDT (Transmit Descriptor Tail) do E1000 para informar o anfitrião de que existem novos descritores para processar.

Input

Considere o seguinte array de descritores Tx:``` [context_1, data_2, data_3, context_4, data_5]

Vamos atribuir os campos da sua estrutura da seguinte forma (os nomes dos campos são hipotéticos para serem legíveis por humanos, mas mapeiam diretamente para a especificação 82540EM):```
context_1.header_length = 0
context_1.maximum_segment_size = 0x3010
context_1.tcp_segmentation_enabled = true

data_2.data_length = 0x10
data_2.end_of_packet = false
data_2.tcp_segmentation_enabled = true

data_3.data_length = 0
data_3.end_of_packet = true
data_3.tcp_segmentation_enabled = true

context_4.header_length = 0
context_4.maximum_segment_size = 0xF
context_4.tcp_segmentation_enabled = true

data_5.data_length = 0x4188
data_5.end_of_packet = true
data_5.tcp_segmentation_enabled = true

Aprenderemos por que eles devem ser assim em nossa análise passo a passo.

Análise de Causa Raiz

[context_1, data_2, data_3] Processamento

Vamos assumir que os descritores acima são escritos no Tx Ring na ordem especificada e o registrador TDT é atualizado pelo guest. Agora o host executará a função e1kXmitPending no arquivo src/VBox/Devices/Network/DevE1000.cpp (a maioria dos comentários são e serão removidos por questão de legibilidade):```c static int e1kXmitPending(PE1KSTATE pThis, bool fOnWorkerThread) { ... while (!pThis->fLocked && e1kTxDLazyLoad(pThis)) { while (e1kLocateTxPacket(pThis)) { fIncomplete = false; rc = e1kXmitAllocBuf(pThis, pThis->fGSO); if (RT_FAILURE(rc)) goto out; rc = e1kXmitPacket(pThis, fOnWorkerThread); if (RT_FAILURE(rc)) goto out; }

e1kTxDLazyLoad lerá todos os 5 descritores Tx do Tx Ring. Então e1kLocateTxPacket é chamado pela primeira vez. Esta função itera por todos os descritores para configurar um estado inicial, mas não os processa de fato. No nosso caso, a primeira chamada a e1kLocateTxPacket manipulará os descritores context_1, data_2 e data_3. Os dois descritores restantes, context_4 e data_5, serão manipulados na segunda iteração do loop while (abordaremos a segunda iteração na próxima seção). Essa divisão do array em duas partes é crucial para desencadear a vulnerabilidade, então vamos descobrir por quê.

e1kLocateTxPacket tem a seguinte aparência:```c
static bool e1kLocateTxPacket(PE1KSTATE pThis)
{
...
    for (int i = pThis->iTxDCurrent; i < pThis->nTxDFetched; ++i)
    {
        E1KTXDESC *pDesc = &pThis->aTxDescriptors[i];
        switch (e1kGetDescType(pDesc))
        {
            case E1K_DTYP_CONTEXT:
                e1kUpdateTxContext(pThis, pDesc);
                continue;
            case E1K_DTYP_LEGACY:
                ...
                break;
            case E1K_DTYP_DATA:
                if (!pDesc->data.u64BufAddr || !pDesc->data.cmd.u20DTALEN)
                    break;
                ...
                break;
            default:
                AssertMsgFailed(("Impossible descriptor type!"));
        }

O primeiro descritor (context_1) é do tipo E1K_DTYP_CONTEXT, então a função e1kUpdateTxContext é chamada. Esta função atualiza um Contexto de Segmentação TCP se a Segmentação TCP estiver habilitada para o descritor. Isso é verdade para context_1, então o Contexto de Segmentação TCP será atualizado. (O que realmente é a Atualização do Contexto de Segmentação TCP não é importante, e usaremos isso apenas para nos referir ao código abaixo).

O segundo descritor (data_2) é do tipo E1K_DTYP_DATA, então várias ações desnecessárias para a discussão serão realizadas.

O terceiro descritor (data_3) também é do tipo E1K_DTYP_DATA, mas como data_3.data_length == 0, nenhuma ação é realizada.

Baixar ferramenta