Эксплойт переполнения кучи

Я понимаю, что эксплуатация переполнения требует трех шагов:

1. Внедрение произвольного кода (шеллкода) в память целевого процесса.

2.Взять под контроль eip.

3. Установите eip для выполнения произвольного кода.

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

Другими словами, я понимаю шаг 2.

Я не понимаю шаги 1 и 3.

  1. Как мне ввести свой код в пространство памяти процесса?

  2. На шаге 3 я переопределяю указатель функции указателем на мой шелл-код. Как я могу вычислить\узнать, по какому адресу был введен мой внедренный код? (Эта проблема решается в stackoverflow с помощью «jmp esp»).


person Michael    schedule 28.05.2012    source источник


Ответы (3)


При переполнении кучи, если предположить, что в системе не активирован ASLR, вы будете знать адреса фрагментов памяти (т. е. буферов), которые вы используете при переполнении.

Одним из вариантов является размещение шелл-кода там, где находится буфер, при условии, что вы можете управлять содержимым буфера (как пользователь приложения). После того, как вы поместили байты шелл-кода в буфер, вам нужно только перейти к этому адресу буфера.

Один из способов выполнить этот переход — например, перезаписать запись .dtors. После завершения работы уязвимой программы шелл-код, помещенный в буфер, будет выполнен. Сложной частью является перезапись .dtors. Для этого вам придется использовать опубликованные методы эксплуатации кучи.

Условием является деактивация ASLR (чтобы узнать адрес буфера перед выполнением уязвимой программы) и область памяти, в которой размещен буфер, должна быть исполняемой.

Более того, шаги 2 и 3 одинаковы. Если вы управляете eip, логично, что вы укажете его на шеллкод (произвольный код).

P.S.: Обойти ASLR сложнее.

person newlog    schedule 28.09.2012

Шаг 1 требует наличия уязвимости в атакуемом коде. Общие уязвимости включают в себя:

  • переполнение буфера (распространенный код на языке C, происходит, если программа считывает произвольную длинную строку в фиксированный буфер)
  • оценка непроверенных данных (обычно в SQL и языках сценариев, но может встречаться и в других языках)

Шаг 3 требует детального знания целевой архитектуры.

person Klas Lindbäck    schedule 28.05.2012
comment
Я понимаю. Не могли бы вы привести пример того, как найти адрес шелл-кода в случае переполнения кучи? - person Michael; 29.05.2012
comment
Нет, у меня нет привычки создавать вирусы, поэтому я никогда не удосужился этим заняться. - person Klas Lindbäck; 29.05.2012
comment
Способов в сети много. Например. иногда вы не можете контролировать, куда именно идет eip, поэтому люди используют nop-следы с перезаписью больших объемов памяти (поищите по термину) в надежде, что при случайном переключении памяти они попадут в nop-следы, скользящие вниз к эксплойту. . Иногда эксплойты кучи (не только переполнение) могут привести к произвольной записи 4 байтов.. (поэтому, если вы знаете адрес стека, вы можете просто перезаписать возвращенный eip). Эксплойты кучи немного сложнее эксплойта по сравнению с переполнением буфера. - person Dan; 22.10.2012

  1. Как внедрить свой код в пространство процесса?

    Это довольно утверждение/вопрос. Для этого требуется «эксплуатируемая» область кода в указанном пространстве процесса. Например, Windows в настоящее время переписывает большинство функций strcpy() в strncpy(), если это вообще возможно. Я говорю если возможно

    потому что не все области кода, использующие strcpy, можно успешно заменить на strncpy. Почему? ПОТОМУ ЧТО ~@ этой сути в различии, показанном ниже;

    strcpy($buffer, $copied);
    

    or

    strncpy($buffer, $copied, sizeof($copied));
    

    Именно поэтому strncpy так сложно реализовать в реальных сценариях. Для большинства операций strncpy необходимо установить «магическое число» (оператор sizeof() создает это «магическое число»)

    Как программистов, нас учат использовать жестко закодированные значения, такие как строгое соблюдение char buffer[1024]; - действительно плохая практика кодирования.

    НО ~ для сравнения - использование buffer[]=""; или buffer[1024]=""; является сердцевиной эксплойта. ОДНАКО, если, например, мы изменим этот код на последний, мы получим еще один эксплойт, введенный в систему...

    char * buffer;
    char * copied;
    
    strcpy(buffer, copied);//overflow this right here...
    

    ИЛИ ЭТО:

    int size = 1024;
    
    char buffer[size];
    char copied[size];
    
    strncpy(buffer,copied, size);
    

    Это предотвратит переполнение, но создаст доступную для использования область в ОЗУ из-за предсказуемого размера и структурирования в 1024 блока кода/данных.

    Следовательно, оригинальный постер, ищущий, например, strcpy в адресном пространстве программы, сделает программу пригодной для эксплуатации, если strcpy присутствует.

    Есть много причин, по которым программисты предпочитают strcpy strncpy. Магические числа, переменный размер входных/выходных данных...стили программирования...и т.д...

  2. КАК Я НАЙДУ СЕБЯ В МОЕМ КОДЕ (МОЕ МЕСТОПОЛОЖЕНИЕ)

    Посмотрите различные хакерские книги, чтобы найти примеры этого ~

    НО, попробуйте;

    label:
    pop eax
    pop eax
    call pointer
    
    jmp label
    pointer:
    mov esp, eax
    jmp $
    

    Это пример, который не работает из-за того, что я НЕ хочу нести ответственность за написание следующего червя Морриса! Но любой порядочный программист поймет суть этого кода и сразу поймет, о чем я говорю.

    Я надеюсь, что твои методы переполнения будут работать в будущем, сын мой!

person shotting.cc    schedule 10.11.2016