Подтвердить что ты не робот

Используйте переполнение кучи для записи произвольных данных

Я пытаюсь изучить основы атаки переполнения кучи. Меня больше всего интересует использование коррупции или модификация метаданных фрагмента для основы атаки, но я также открыт для других предложений. Я знаю, что моя цель эксплойта должна быть перезаписана указателем функции 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 дней и учитывает новые версии glibc. Тем не менее, я не нашел, что, учитывая 5 методов, подробно описанных в документе, код выше соответствует любому из предпосылок для этих методов.
  • Понимание кучи, разбивая его (pdf)
    • В pdf файле дается довольно хороший обзор того, как работает куча, но фокусируется на двойных бесплатных методах.

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

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

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

4b9b3361

Ответ 1

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

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

Подробности о том, как malloc обрабатывает создание блоков памяти, вытягивая память из списков и других вещей. В частности, для этой атаки интерес представляет атака разблокировки (примечание: вы правы, что 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, но бесплатные. Это будет важно позже. Вы должны знать достаточно программирования, чтобы понять, что "блоки" в Doug Lea 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 | addr вы хотите перезаписать -12 (0x0C) | addr, который вы хотите вызвать вместо

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

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

Ответ 2

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

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

Malloc Des-Malleficarum

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

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

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

Понимание кучи, разбив ее

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

Ответ 3

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

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

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