Категория > Новости > Круче кучи! Разбираем в подробностях проблемы heap allocation - «Новости»
Круче кучи! Разбираем в подробностях проблемы heap allocation - «Новости»2-04-2022, 00:00. Автор: Fulton |
Некоторые уязвимости возникают из‑за ошибок с управлением памятью, выделенной на куче. Механизм эксплуатации этих уязвимостей сложнее, чем обычное переполнение на стеке, поэтому не все умеют с ними работать. Даже курс Cracking the perimeter (OSCE) не заходил дальше тривиальной перезаписи SEH. В этой статье я расскажу и на практике покажу механику работы кучи. Практиковаться мы будем на реализации кучи ptmalloc2, которая сейчас используется по умолчанию в glibc, поэтому нам понадобятся машина с Linux и необходимый софт. Установим отладчик GDB, GCC (можно сразу поставить весь пакет build-essential) и отладочную версию библиотеки libc, позволяющую видеть подробную информацию о куче. Также поставим pwngdb и его зависимость — peda, чтобы получить удобные команды
sudo apt install gdb build-essential libc6-dbg
git clone https://github.com/scwuaptx/Pwngdb.git ~/Pwngdb
cp~/Pwngdb/.gdbinit ~/
git clone https://github.com/longld/peda.git ~/peda
Основы GDBДля изучения работы наших тестовых программ понадобится знание базовых команд GDB:
Команды peda и pwngdb:
Структура чанковКогда программа запрашивает буфер для данных (например, размером в 10 байт) с помощью Структура чанка, используемая в ptmalloc2, приведена ниже. Из нее можно понять, что перед указателем на выделенный буфер памяти, который возвращается пользователю (
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk,if unallocated (P clear) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk,in bytes |A|M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
..
.(malloc_usable_size()bytes).
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (size of chunk,but used for application data) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of next chunk,in bytes |A|0|1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Сам чанк имеет такую структуру:
struct malloc_chunk {
INTERNAL_SIZE_Tmchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_Tmchunk_size;/* Size in bytes, including overhead. */
struct malloc_chunk* fd;/* double links — used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links — used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
Чтобы получить из указателя на чанк (служебную структуру) указатель на буфер памяти, который можно использовать, к первому прибавляют значение
#define chunk2mem(p) ((void*)((char*)(p) + 2*SIZE_SZ))
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
Важный момент: поле АренаСтарые менеджеры кучи использовали одну кучу на весь процесс и синхронизировали доступ к ней разных потоков с помощью мьютексов. Как несложно догадаться, положительно на производительности это не сказывалось. Ptmalloc2 использует арены — области памяти для того, чтобы каждый поток мог там хранить свою кучу. Но поскольку на практике потоков в приложении может быть слишком много, максимальное количество создаваемых арен вычисляется по следующей формуле (
#define NARENAS_FROM_NCORES(n) ((n) * (**sizeof** (**long**) == 4 ? 2 : 8))
Пока количество арен меньше максимального, менеджер кучи создает новую арену на каждый новый поток. После этого, увы, нескольким потокам придется делить между собой одну арену. Первая созданная менеджером кучи арена называется основной (main). Однопоточное приложение использует только основную арену. ФлагиОстановимся подробнее на флагах чанка. Поле размера предыдущего чанка (
BinsДля повышения быстродействия чанки используют повторно (и именно эту особенность учитывают при эксплуатации кучи). Ранее использованные и освобожденные чанки складывают в бины (bins). В нашей реализации кучи существует пять типов бинов:
Small bins
Large bins
Перейти обратно к новости |