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.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
house_of_apple_2 — Passo a passo interativo do GDB para a técnica FSOP House of Apple 2 no glibc 2.43, com um sandbox reproduzível cobrindo bypass de vtable, stack pivoting e ROP. | Kitploit
Ferramentas/GitHubGitHub/jazho76/house_of_apple_2
Forensia de MemóriaExploraçãoEngenharia ReversaShellcodeDepuradoresPapers e PesquisaAprendizado e EducaçãoDesenvolvimento de PayloadsExploração de BináriosLabs e Prática
GitHubjazho76/house_of_apple_2
51128há 1 mêsAinda 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

house_of_apple_2

Passo a passo interativo do GDB para a técnica FSOP House of Apple 2 no glibc 2.43, com um sandbox reproduzível cobrindo bypass de vtable, stack pivoting e ROP.

Ver Repositório

Explorando a House of Apple 2 em glibc moderno

Este repositório é um playground autocontido inspirado no módulo de Exploração de Estruturas de Arquivo do pwn.college. Ele não introduz uma nova variação da House of Apple 2, apenas responde à minha curiosidade sobre como a técnica se comporta em versões recentes da glibc e se ela continua sendo um caminho de exploração viável. O documento fornece um passo a passo interativo no GDB que os leitores podem acompanhar junto com o sandbox para desenvolver uma compreensão mais intuitiva da primitiva. Todos os experimentos usam glibc 2.43, conforme empacotada pelo Ubuntu 26.04 e Fedora 44 no momento da escrita.

File Stream Oriented Programming (FSOP). Trata-se de manipular estruturas de stream de arquivo da glibc para sequestrar o fluxo de controle. Uma forma de fazer isso é corromper o mecanismo de despacho da vtable de _IO_FILE_plus. A glibc moderna valida essa vtable, então a abordagem óbvia de substituí-la por um endereço arbitrário não funciona.

House of Apple 2, originalmente introduzida por Roderick, contorna essa restrição usando uma vtable válida de _IO_FILE_plus para alcançar a maquinaria de streams de caracteres largos, onde uma vtable secundária é despachada diretamente sem validação de intervalo. Isso fornece uma primitiva de chamada arbitrária que podemos escalar para um stack pivot e uma cadeia ROP.

Pré-requisitos de exploração

Esta exploração assume que podemos sobrescrever uma estrutura FILE e que temos tanto um heap leak quanto um libc leak. O binário alvo já fornece isso.

Ambiente de sandbox

O sandbox roda Ubuntu 26.04 LTS, nos dando um ambiente moderno para explorar a técnica.

A imagem inclui GDB, pwndbg, pwntools, ropper e tmux. Ela também contém um binário alvo com um menu interativo para invocar operações de stream de arquivo como fopen, fread, fwrite e fclose. Isso nos dá uma maneira conveniente de manipular streams durante a depuração e teste de ideias.

Compile e execute o sandbox com:``` ./build.sh ./run.sh

## Exploração

Vamos começar inspecionando as estruturas `_IO_FILE` e `_IO_FILE_plus`:```c
pwndbg> ptype struct _IO_FILE
type = struct _IO_FILE {
    int _flags;
    char *_IO_read_ptr;
    char *_IO_read_end;
    char *_IO_read_base;
    char *_IO_write_base;
    char *_IO_write_ptr;
    char *_IO_write_end;
    char *_IO_buf_base;
    char *_IO_buf_end;
    char *_IO_save_base;
    char *_IO_backup_base;
    char *_IO_save_end;
    struct _IO_marker *_markers;
    struct _IO_FILE *_chain;
    int _fileno;
    int _flags2 : 24;
    char _short_backupbuf[1];
    __off_t _old_offset;
    unsigned short _cur_column;
    signed char _vtable_offset;
    char _shortbuf[1];
    _IO_lock_t *_lock;
    __off64_t _offset;
    struct _IO_codecvt *_codecvt;
    struct _IO_wide_data *_wide_data;
    struct _IO_FILE *_freeres_list;
    void *_freeres_buf;
    struct _IO_FILE **_prevchain;
    int _mode;
    int _unused3;
    __uint64_t _total_written;
    char _unused2[8];
}
pwndbg> ptype struct _IO_FILE_plus
type = struct _IO_FILE_plus {
    FILE file;
    const struct _IO_jump_t *vtable;
}

Em termos práticos, _IO_FILE_plus é um _IO_FILE com um ponteiro de vtable. Isso imediatamente parece interessante: se conseguirmos controlar esse ponteiro, podemos ser capazes de redirecionar uma chamada indireta e sequestrar o fluxo de controle.

Inspecionando a vtable do fluxo de arquivo

Para inspecionar a vtable, vamos examinar um ponteiro FILE retornado por fopen.```c pwndbg> p *(struct _IO_FILE_plus *)0x37ecf010 $4 = { file = { _flags = 0xfbad2480, _IO_read_ptr = 0x0, _IO_read_end = 0x0, _IO_read_base = 0x0, _IO_write_base = 0x0, _IO_write_ptr = 0x0, _IO_write_end = 0x0, _IO_buf_base = 0x0, _IO_buf_end = 0x0, _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x7f58a7f4b4a0 <IO_2_1_stderr>, _fileno = 0x3, _flags2 = 0x0, _short_backupbuf = "", _old_offset = 0x0, _cur_column = 0x0, _vtable_offset = 0x0, _shortbuf = "", _lock = 0x37ecf0f0, _offset = 0xffffffffffffffff, _codecvt = 0x0, _wide_data = 0x37ecf100, _freeres_list = 0x0, _freeres_buf = 0x0, _prevchain = 0x7f58a7f4b480 <_IO_list_all>, _mode = 0x0, _unused3 = 0x0, _total_written = 0x0, _unused2 = "\000\000\000\000\000\000\000" }, vtable = 0x7f58a7f49030 <_IO_file_jumps> }

O ponteiro aponta para a tabela `_IO_file_jumps`.

![3](https://assets.kitploit.com/production/public/readmes/56272/9fe7069dbb47c87d81c704a23ff483a6c630d5506150361db4aefee1516d0423/054e7475018b9adcfdb102b7e142ea8ad09116b38787416fdc30f8cb2f209bfa-display-v1.webp)

Este é um conjunto de 21 ponteiros de função. As operações de fluxo de arquivo são despachadas através de diferentes entradas dependendo do caminho de execução.

### Seguindo o caminho do `fwrite`

Para esta exploração, vou focar no caminho do `fwrite`. Depois de colocar breakpoints em cada função e chamar `fwrite`, o primeiro breakpoint que atingimos é `_IO_file_xsputn`.

![4](https://assets.kitploit.com/production/public/readmes/56272/f77a8ff4f3d548b46916a97897b811b5cfb650de4843184b6574bdac51e1c2d0/e7de50a63631e0e1b18e8aa0b2d0852b62457428b4be3936ea3ea6a776531329-display-v1.webp)

A chamada ocorre em `fwrite+216`. Isto corresponde ao [código-fonte da glibc](https://elixir.bootlin.com/glibc/glibc-2.43/source/libio/iofwrite.c#L44): `_IO_sputn` é uma macro que despacha através da vtable, resolvendo para `_IO_file_xsputn` para este fluxo.```asm
   0x00007fd5181d362a <+202>:	mov    rdx,rcx
   0x00007fd5181d362d <+205>:	mov    rdi,rbx
   0x00007fd5181d3630 <+208>:	mov    QWORD PTR [rbp-0x30],r8
   0x00007fd5181d3634 <+212>:	mov    QWORD PTR [rbp-0x28],rcx
   0x00007fd5181d3638 <+216>:	call   QWORD PTR [rax+0x38]

Tentando substituir a vtable

Como primeira tentativa, vamos sobrescrever o ponteiro da vtable com desired_func - 0x38 e definir um breakpoint em fwrite+216.```c pwndbg> p &win $3 = (<text variable, no debug info> *) 0x4019e1 pwndbg> p/x &win - 0x38 $4 = 0x4019a9 pwndbg> set ((struct _IO_FILE_plus *)0x5334010)->vtable = (void *)0x4019a9 pwndbg> b *fwrite+216 Breakpoint 4 at 0x7fd5181d3638: file ./libio/libioP.h, line 1042.

![5](https://assets.kitploit.com/production/public/readmes/56272/68d9bb8c66bf4088af2741eebea1ecb9b56d047f77983d068d26c9566a97e533/1c9d22964dbe7735df03440da27a86e739989f7cf62bd6e126cecf1083b2cf4b-display-v1.webp)

A execução é abortada antes de atingir o breakpoint. O erro sugere que a glibc valida o ponteiro da vtable antes de realizar a chamada indireta. Vamos inspecionar o backtrace e ver onde isso acontece.

`fwrite` atinge `_IO_vtable_check`, que está rejeitando o ponteiro de vtable forjado.

![6](https://assets.kitploit.com/production/public/readmes/56272/5d88a98e9a1a20ab8c510aad7374f24884a05f363bd46f94d0d05cad513c7c0a/6974f1daec533bb453c59cff614c11f59c29bb1f85a0d23235e05c22433c0b48-display-v1.webp)

A implementação contém um mecanismo para aceitar vtables externas, mas não está sob nosso controle. O código relevante está disponível em [`vtables.c`](https://elixir.bootlin.com/glibc/glibc-2.43/source/libio/vtables.c#L504).

### Entendendo a validação da vtable
Baixar ferramenta