Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
house_of_apple_2 — Интерактивный разбор техники House of Apple 2 FSOP в GDB на glibc 2.43 с воспроизводимой песочницей, охватывающей обход vtable, перехват стека и ROP. | Kitploit
Инструменты/GitHubGitHub/jazho76/house_of_apple_2
Криминалистика памятиЭксплуатацияОбратная инженерияШелл-кодОтладчикиСтатьи и ИсследованияОбучение и ОбразованиеРазработка Полезной НагрузкиЭксплуатация Бинарных ФайловЛаборатории и Практика
GitHubjazho76/house_of_apple_2
511281 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

house_of_apple_2

Интерактивный разбор техники House of Apple 2 FSOP в GDB на glibc 2.43 с воспроизводимой песочницей, охватывающей обход vtable, перехват стека и ROP.

Репозиторий

Исследование House of Apple 2 на современном glibc

Этот репозиторий представляет собой самодостаточную площадку для экспериментов, вдохновлённую модулем File Struct Exploitation от pwn.college. Он не вводит новую вариацию House of Apple 2, а лишь отвечает на моё любопытство о том, как эта техника работает на последних версиях glibc и остаётся ли она жизнеспособным путём эксплуатации. Документ содержит интерактивное пошаговое руководство в GDB, которое читатели могут проходить параллельно с песочницей, чтобы развить более интуитивное понимание этого примитива. Все эксперименты используют glibc 2.43 в том виде, в каком она поставлялась в Ubuntu 26.04 и Fedora 44 на момент написания.

File Stream Oriented Programming (FSOP). Речь идёт о манипулировании структурами файловых потоков glibc для перехвата потока управления. Один из способов сделать это — повредить механизм диспетчеризации vtable в _IO_FILE_plus. Современный glibc проверяет эту vtable, поэтому очевидный подход с заменой её на произвольный адрес не работает.

House of Apple 2, изначально представленная Roderick, обходит это ограничение, используя действительную vtable _IO_FILE_plus для достижения механизма широкосимвольных потоков, где вторичная vtable вызывается напрямую без проверки диапазона. Это даёт примитив arbitrary call, который мы можем развить до переворота стека (stack pivot) и ROP-цепочки.

Предпосылки для эксплуатации

Это исследование предполагает, что мы можем перезаписать структуру FILE и что у нас есть как утечка кучи, так и утечка libc. Целевой бинарник уже предоставляет это.

Песочница

Песочница работает на Ubuntu 26.04 LTS, предоставляя нам современную среду для исследования этой техники.

Образ включает GDB, pwndbg, pwntools, ropper и tmux. Он также содержит целевой бинарник с интерактивным меню для вызова операций с файловыми потоками, таких как fopen, fread, fwrite и fclose. Это даёт нам удобный способ манипулировать потоками во время отладки и проверки идей.

Соберите и запустите песочницу с помощью:``` ./build.sh ./run.sh

## Исследование

Начнём с изучения структур `_IO_FILE` и `_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;
}

С практической точки зрения, _IO_FILE_plus — это _IO_FILE с указателем на vtable. Это сразу выглядит интересно: если мы сможем управлять этим указателем, мы, возможно, сможем перенаправить косвенный вызов и перехватить поток управления.

Изучение vtable потока файла

Чтобы изучить vtable, давайте рассмотрим указатель FILE, возвращаемый 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> }

Указатель указывает на таблицу `_IO_file_jumps`.

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

Это набор из 21 указателя на функции. Операции с файловыми потоками диспетчеризуются через различные записи в зависимости от пути выполнения.

### Прослеживание пути `fwrite`

В этом исследовании я сосредоточусь на пути `fwrite`. После установки точек останова на каждую функцию и вызова `fwrite` первая точка останова, которую мы достигаем, — это `_IO_file_xsputn`.

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

Вызов происходит по адресу `fwrite+216`. Это соответствует [исходному коду glibc](https://elixir.bootlin.com/glibc/glibc-2.43/source/libio/iofwrite.c#L44): `_IO_sputn` — это макрос, который выполняет диспетчеризацию через vtable, разрешаясь в `_IO_file_xsputn` для этого потока.```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]

Попытка заменить vtable

Для первой попытки перезапишем указатель vtable значением desired_func - 0x38 и установим точку останова на 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)

Выполнение прерывается до достижения точки останова. Ошибка указывает на то, что glibc проверяет указатель vtable перед выполнением косвенного вызова. Давайте изучим стек вызовов и посмотрим, где это происходит.

`fwrite` достигает `_IO_vtable_check`, который отклоняет поддельный указатель vtable.

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

Реализация содержит механизм для принятия сторонних vtable, но он не находится под нашим контролем. Соответствующий код доступен в [`vtables.c`](https://elixir.bootlin.com/glibc/glibc-2.43/source/libio/vtables.c#L504).

### Понимание проверки vtable
Скачать инструмент