Используйте переполнение кучи для записи произвольных данных - PullRequest
22 голосов
/ 10 марта 2012

Я пытался изучить основы атаки переполнения кучи.Я в основном заинтересован в использовании повреждения или модификации метаданных чанка для основы атаки, но я также открыт для других предложений.Я знаю, что моя цель эксплойта - переписать указатель функции printf() на указатель функции challenge(), но я не могу понять, как добиться этой записи.У меня есть следующий фрагмент кода, который я хочу использовать, который использует malloc из glibc 2.11.2:

void challenge()
{
        puts("you win\n");
}

int main(int argc, char **argv)
{
        char *inputA, *inputB, *inputC;

        inputA = malloc(32);
        inputB = malloc(32);
        inputC = malloc(32);

        strcpy(inputA, argv[1]);
        strcpy(inputB, argv[2]);
        strcpy(inputC, argv[3]);

        free(inputC);
        free(inputB);
        free(inputA);

        printf("execute challenge to win\n");
}

Очевидно, что добиться фактической перезаписи метаданных выделенного фрагмента тривиально.Однако я не смог найти способ использовать этот код, используя какие-либо стандартные методы.Я прочитал и попытался реализовать методы из:

  • Бумага: w00w00 на Переполнение кучи
    • Хотя бумага очень прозрачная, unlinkТехника устарела в течение некоторого времени.
  • Malloc Maleficarum.txt
    • В этом документе рассматриваются методы эксплойтов с w00w00 days, а также рассказывается одля более новых версий glibc.Тем не менее, я не обнаружил, что, учитывая 5 методов, подробно описанных в статье, приведенный выше код соответствует любому из предварительных условий для этих методов.
  • Понимание кучи путем ее разрушения(pdf)
    • PDF дает довольно хороший обзор того, как работает куча, но фокусируется на двойных бесплатных методах.

Я изначально пробовалиспользовать этот код, манипулируя значением размера чанка для inputC, чтобы он указывал на начало чанка inputC.Когда это не сработало, я попытался указать назад на кусок inputB.Именно тогда я понял, что новый glibc выполняет проверку работоспособности значения размера.

Как пользователь может создать эксплойт, чтобы воспользоваться бесплатным, предполагая, что он имеет возможность редактировать метаданные выделенного чанка впроизвольные значения, и использовать его для перезаписи значения в GOT или записи на любой другой произвольный адрес?

Примечание. Когда я пишу «произвольный адрес», я понимаю, что страницы памяти могут быть только для чтения или защищены, я имею в видуадрес, на который я могу предположить, что могу написать.

Ответы [ 3 ]

11 голосов
/ 20 марта 2013

Примечание. Прежде чем ответить, скажу, что это чисто академический ответ, не предназначенный для использования в злонамеренных целях. Мне известно об упражнениях, которые выполняет OP, и они имеют открытый исходный код и не предназначены для того, чтобы побудить пользователей использовать эти методы в неутвержденных обстоятельствах.

Я подробно опишу нижеприведенную технику, но для справки я бы взглянул на хитрости Vudo malloc (на нее ссылается одна из ваших ссылок выше), потому что мой обзор будет кратким: http://www.phrack.com/issues.html?issue=57&id=8

Подробно о том, как malloc обрабатывает создание блоков памяти, извлечение памяти из списков и другие вещи. В частности, атака unlink представляет интерес для этой атаки (обратите внимание: вы правы, что glibc теперь выполняет проверку исправности размеров по этой конкретной причине, но вы должны использовать более старую версию libc для этого упражнения ... legacy bro).

На бумаге выделенный блок и свободный блок используют одну и ту же структуру данных, но данные обрабатываются по-разному. Смотрите здесь:

chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | prev_size: size of the previous chunk, in bytes (used   |
         | by dlmalloc only if this previous chunk is free)        |
         +---------------------------------------------------------+
         | size: size of the chunk (the number of bytes between    |
         | "chunk" and "nextchunk") and 2 bits status information  |
  mem -> +---------------------------------------------------------+
         | fd: not used by dlmalloc because "chunk" is allocated   |
         | (user data therefore starts here)                       |
         + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
         | bk: not used by dlmalloc because "chunk" is allocated   |
         | (there may be user data here)                           |
         + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
         |                                                         |
         |                                                         |
         | user data (may be 0 bytes long)                         |
         |                                                         |
         |                                                         |
 next -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | prev_size: not used by dlmalloc because "chunk" is      |
         | allocated (may hold user data, to decrease wastage)     |
         +---------------------------------------------------------+

Выделенные блоки не используют указатели fd или bk, но свободные будут. Это будет важно позже. Вы должны знать достаточно программирования, чтобы понять, что «блоки» в malloc Дуга Ли организованы в двусвязный список; есть один список для свободных блоков и другой для распределенных (технически есть несколько списков для свободных в зависимости от размеров, но это не имеет значения, поскольку код выделяет блоки одинакового размера). Поэтому, когда вы освобождаете определенный блок, вы должны исправить указатели, чтобы сохранить список в такте.

например. скажем, вы освобождаете блок y из списка ниже:

x <-> y <-> z

Обратите внимание, что на приведенной выше диаграмме места для bk и fd содержат необходимые указатели для итерации по списку. Когда malloc хочет удалить блок p из списка, он вызывает, среди прочего, макрос для исправления списка:

#define unlink( y, BK, FD ) {            
    BK = P->bk;                          
    FD = P->fd;                          
    FD->bk = BK;                         
    BK->fd = FD;                         
}

Сам макрос не сложен для понимания, но важно отметить, что в старых версиях libc он не выполняет проверку работоспособности размера или указателей, в которые записывается. В вашем случае это означает, что без какой-либо рандомизации адресов вы можете предсказуемо и надежно определить состояние кучи и перенаправить произвольный указатель на адрес по вашему выбору, переполнив кучу (через strncopy здесь) определенным образом. .

Есть несколько вещей, необходимых для того, чтобы атака сработала:

  • указатель fd для вашего блока указывает на адрес, который вы хотите перезаписать, минус 12 байт. Смещение связано с тем, что malloc очищает выравнивание при изменении списка
  • Указатель bk вашего блока указывает на ваш шелл-код
  • Размер должен быть -4. Это выполняет несколько вещей, а именно устанавливает биты состояния в блоке

Так что вам придется поэкспериментировать со смещениями в вашем конкретном примере, но общий вредоносный формат, который вы пытаетесь передать с помощью strcpy, имеет формат:

| мусор, чтобы заполнить законный буфер | -4 | -4 | адрес, который вы хотите перезаписать -12 (0x0C) | Адр вы хотите позвонить вместо

Обратите внимание, что отрицательное число устанавливает в поле prev_size значение -4, что заставляет свободную маршрутизацию полагать, что блок prev_size фактически начинается в текущем фрагменте, который вы контролируете / портите.

И да, правильное объяснение не будет полным без упоминания о том, что эта атака не работает на текущих версиях glibc; У размера есть проверка работоспособности, и метод unlink просто не будет работать. Это в сочетании с такими мерами, как рандомизация адресов, делает эту атаку нежизнеспособной, кроме устаревших систем. Но описанный здесь метод - это то, как я справился с этой задачей;)

3 голосов
/ 12 апреля 2012

Обратите внимание, что большинство методов, описанных в Malloc Malleficarum, теперь защищены. Glibc значительно улучшил все сценарии с двойной бесплатностью.

Если вы хотите улучшить свои знания о методах Malloc Malleficarum, прочитайте Malloc Des-Malleficarum и Дом знаний: Reloaded, написанный blackngel. Вы можете найти эти тексты в phrack.

Malloc Des-Malleficarum

Я тоже работаю над этим, и я могу сказать вам, что, например, Дом Разума больше не эксплуатируется, по крайней мере, как объясняется в текстах. Хотя может быть возможно обойти новые ограничения, добавленные в код. Добавьте, что самый простой способ выполнить ваш код - переписать адрес .dtors, поэтому ваш код всегда будет выполняться после завершения программы.

Если вы загрузите код glibc и изучите критические зоны malloc. И т. Д., Вы найдете проверки кода, которые не описаны в ранее упомянутых документах. Эти проверки были включены, чтобы остановить двойную свободную вечеринку.

С другой стороны, презентация Джастина Н. Фергюсона («Понимание кучи, разбив ее»), которую вы можете найти в youtube (BlackHat 2007), идеально подходит для понимания всей механики кучи, но я должен признать, что показанные методы далеко не надежны, но, по крайней мере, он открывает новое поле для эксплуатации кучи.

Понимание кучи путем ее разрушения

В любом случае, я тоже работаю над этим, поэтому, если вы хотите связаться со мной, мы можем поделиться нашими достижениями. Вы можете связаться со мной в домене overflowedminds.net как newlog (создайте почтовый адрес самостоятельно ^^).

0 голосов
/ 12 марта 2012

Переполнения кучи сложно осуществить, и они очень сильно зависят от компоновки кучи, хотя похоже, что вы идете после кучи Windows CRT, которая имеет множество мер по устранению, специально предназначенных для остановки этого типа атаки.

Если вы действительно хотите заниматься такими вещами, вам нужно с радостью перейти к WinDbg и перейти к функциям, таким как free, чтобы точно увидеть, что происходит внутри free, и, следовательно, какой тип управления вы можете использовать.достичь через переполнение кучи предыдущего значения.

Я не дам вам более конкретной помощи, чем по той простой причине, что демонстрации переполнения кучи обычно достаточно для защитной безопасности - эксперты по оборонной безопасности могут сообщитьпереполнение кучи без необходимости использовать его полностью.Единственные, кому do необходимо полностью использовать переполнение кучи на всем пути к удаленному выполнению кода, - это люди, использующие ошибки оскорбительно , и если вы хотите это сделать, высвой собственный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...