- Вопрос или проблема
- Ответ или решение
- Ответ на вопросы по эксплуатации кучи GLIBC (House of Force)
- 1. Почему формула для расчета оборачиваемого адреса выглядит следующим образом?
- 2. Почему используется 0xffffffffffffffff для вычитания x и затем прибавления y? Как это дает нам разницу в расстоянии? Почему мы используем 0xffffffffffffffff?
- 3. Когда используется __malloc_hook для выполнения функции system, как бинарный файл знает, где находится аргумент для вызова функции? Указатель на аргумент расположен по адресу malloc((heap + 0x30) ""), но как функция знает, что он там, и почему heap + 0x30?
- Заключение
Вопрос или проблема
Это связано с видео Мака Кэмпера о эксплуатации кучи GLIBC и статьями, которые я прочитал
- https://www.crow.rip/crows-nest/binexp/heap/house-of-force-i
- https://www.crow.rip/crows-nest/binexp/heap/house-of-force-i/house-of-force-ii
У меня есть несколько вопросов о видео и статьях.
- Почему формула для вычисления адреса с обертыванием следующая?
def diff(x, y):
return (0xffffffffffffffff - x) + y
Почему используется 0xffffffffffffffff, чтобы вычесть x, а затем прибавить y? Как это дает нам разницу в расстоянии? Почему используется 0xffffffffffffffff?
- Когда используется __malloc_hook для выполнения функции
system
, как бинарный файл знает, где находится аргумент для вызова функции? Указатель на аргумент расположен по адресуmalloc((heap + 0x30) "")
, но как функция знает, что он там, и почемуheap + 0x30
?
Почему формула для вычисления адреса с обертыванием следующая?
Вы можете представить эту функцию обертывания как часы. Для часов функция обертывания будет следующей:
def diff(x, y):
return (12 - x) + y
Давайте проведем пример.
>>> diff(7, 1)
6
>>> diff(8, 1)
5
>>> diff(9, 1)
4
Это дает нам, сколько часов от x часов до y часов.
Подобно часам, куча также будет оборачиваться вокруг виртуальной памяти после 0xffffffffffffffff, что является максимальным 64-битным целым числом.
Поэтому мы хотим рассчитать расстояние обертывания до достижения цели, которая находится перед нашим вводом.
Почему используется 0xffffffffffffffff, чтобы вычесть x, а затем прибавить y? Как это дает нам разницу в расстоянии? Почему используется 0xffffffffffffffff?
Это связано с тем, что вы установили верхний кусок в 0xffffffffffffffff, что говорит кучи, сколько памяти осталось для выделения. Верхний кусок должен быть 0xffffffffffffffff, чтобы мы могли создать максимально возможный кусок. Если общий размер кусков в куче превышает 0xffffffffffffffff, он будет оборачиваться, потому что максимальный размер виртуальной памяти составляет 0xffffffffffffffff.
Когда используется __malloc_hook для выполнения функции system, как бинарный файл знает, где находится аргумент для вызова функции? Указатель на аргумент расположен по адресу malloc((heap + 0x30) “”), но как функция знает, что он там, и почему heap + 0x30?
Мы не можем напрямую передать /bin/sh в __malloc_hook (который теперь указывает на system). В ассемблере первый аргумент функции передается через регистр RDI. Мы не можем установить RDI, подавая, так как строка находится в куче, а не в стеке. После перезаписи __malloc_hook мы делаем вызов malloc с первым аргументом, установленным на адрес /bin/sh (который мы уже записали в кучу). Этот вызов функции malloc установит первый аргумент в RDI, который указывает на /bin/sh, и вызовет __malloc_hook (который теперь указывает на system), что приведет к выполнению оболочки.
Ответ или решение
Ответ на вопросы по эксплуатации кучи GLIBC (House of Force)
1. Почему формула для расчета оборачиваемого адреса выглядит следующим образом?
def diff(x, y):
return (0xffffffffffffffff - x) + y
Рассмотрим оборачивающую функцию как часы. Например, функция для часов будет:
def diff(x, y):
return (12 - x) + y
Для примера, попробуем выполнить несколько расчётов:
>>> diff(7, 1)
6
>>> diff(8, 1)
5
>>> diff(9, 1)
4
Это показывает, сколько часов от x до y. Аналогично часам, куча в виртуальной памяти также оборачивается после 0xffffffffffffffff, что является максимальным значением для 64-битного целого числа. Мы хотим вычислить расстояние оборачивания, чтобы достичь цели, которая находится перед нашим входным значением.
2. Почему используется 0xffffffffffffffff для вычитания x и затем прибавления y? Как это дает нам разницу в расстоянии? Почему мы используем 0xffffffffffffffff?
Это значение используется, потому что вы установили верхний кусок (top chunk) равным 0xffffffffffffffff, что указывает куче, сколько памяти осталось для выделения. Верхний кусок должен быть равным 0xffffffffffffffff, чтобы мы могли создать максимально возможный кусок. Если общий размер кусков в куче превышает 0xffffffffffffffff, произойдет оборачиваение кучи, поскольку максимальный размер виртуальной памяти составляет 0xffffffffffffffff.
3. Когда используется __malloc_hook
для выполнения функции system
, как бинарный файл знает, где находится аргумент для вызова функции? Указатель на аргумент расположен по адресу malloc((heap + 0x30) "")
, но как функция знает, что он там, и почему heap + 0x30
?
Мы не можем напрямую передать строку /bin/sh
в __malloc_hook
(который теперь указывает на system
). В ассемблере первый аргумент функции передается через регистр RDI. Мы не можем установить RDI с помощью команды pop
, поскольку строка находится в куче, а не в стеке. После перезаписи __malloc_hook
мы вызываем функцию malloc
, передавая в качестве первого аргумента адрес /bin/sh
(который мы уже записали в кучу). Этот вызов функции malloc
установит первый аргумент в RDI, который указывает на /bin/sh
и активирует __malloc_hook
(который теперь указывает на system
), что приведет к открытию оболочки.
Заключение
Эти вопросы позволяют глубже изучить принцип работы с кучи в GLIBC и механизмов эксплуатации, таких как House of Force. Понимание этих концепций имеет важное значение для успешного выполнения подобных атак на приложение.