Обход Cookie в уязвимом драйвере HACKSYS. IDA Pro «с нуля» ч.67

Обсудить статью на форуме


Свежая 2020 года подборка видеоуроков, инструментов крэкера, книг и статей - здесь.
Метод, который мы не рассмотрели, чтобы эксплуатировать одну из уязвимостей драйвера HACKSYS.

Мой друг попросил у меня несколько разъяснений о методе, используемом для обхода COOKIE на 32-битных машинах, когда у нас есть переполнение стека в ядре, и мы можем перезаписать адрес возврата, но есть COOKIE, который мешает нам завершить выполнение кода.

Очевидно, что если у нас есть другая уязвимость, которая допускает утечку данных, мы могли бы прочитать значение COOKIE и затем использовать его для отправки наших данных, для перезаписи, но есть метод, который я никогда не использовал на практике, который немного стар и в системах, отличных от WINDOWS 7 32 бит не будет работать, но было бы хорошо взглянуть на него, чтобы уточнить для моего друга и того, кто читает меня (и для меня самого).

Мы уже знаем, что уязвимый драйвер можно скачать отсюда.

https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/releases/download/v1.20/HEVD.1.20.zip

А сам инструмент для загрузки драйвера, можно загрузить отсюда.

http://www.osronline.com/OsrDown.cfm/osrloaderv30.zip?name=osrloaderv30.zip&id=157

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

Внутри ZIP архива находятся такие файлы.

HEVD.1.20\DRV\VULNERABLE\I386

IDA Pro взлом и реверсинг программ

Это драйвер и его символы.

IDA Pro взлом и реверсинг программ

При открытии драйвера в IDA, мы видим функцию DRIVERENTRY, первым аргументом которой всегда является указатель на объект _DRIVER_OBJECT.

IDA Pro взлом и реверсинг программ

Регистр ESI это указатель на объект _DRIVER_OBJECT.

Если мы перейдём во вкладку LOCAL TYPES.

IDA Pro взлом и реверсинг программ

Мы видим, что эта структура. Если мы поищем структуру _IRP, мы находим наиболее часто используемым для обращения структуры.

IDA Pro взлом и реверсинг программ

Мы будем отмечать структуры _DRIVER_OBJECT, _IRP, _DEVICE_OBJECT, _IO_STACK_LOCATION и PIRP и синхронизировать их, потому что именно их мы будем использовать чаще всего.

То что нам нужно сделать - это добавить структуру MAJORFUNCTION, которой нигде нет.

Напомним, что мы можем добавить структуру через вкладку LOCAL TYPES, используя правую кнопку мыши, пункт INSERT и вставить этот код.

struct __MajorFunction
{
SIZE_T _MJ_CREATE;
SIZE_T _MJ_CREATE_NAMED_PIPE;
SIZE_T _MJ_CLOSE;
SIZE_T _MJ_READ;
SIZE_T _MJ_WRITE;
SIZE_T _MJ_QUERY_INFORMATION;
SIZE_T _MJ_SET_INFORMATION;
SIZE_T _MJ_QUERY_EA;
SIZE_T _MJ_SET_EA;
SIZE_T _MJ_FLUSH_BUFFERS;
SIZE_T _MJ_QUERY_VOLUME_INFORMATION;
SIZE_T _MJ_SET_VOLUME_INFORMATION;
SIZE_T _MJ_DIRECTORY_CONTROL;
SIZE_T _MJ_FILE_SYSTEM_CONTROL;
SIZE_T _MJ_DEVICE_CONTROL;
SIZE_T _MJ_INTERNAL_DEVICE_CONTROL;
SIZE_T _MJ_SCSI;
SIZE_T _MJ_SHUTDOWN;
SIZE_T _MJ_LOCK_CONTROL;
SIZE_T _MJ_CLEANUP;
SIZE_T _MJ_CREATE_MAILSLOT;
SIZE_T _MJ_QUERY_SECURITY;
SIZE_T _MJ_SET_SECURITY;
SIZE_T _MJ_POWER;
SIZE_T _MJ_SYSTEM_CONTROL;
SIZE_T _MJ_DEVICE_CHANGE;
SIZE_T _MJ_QUERY_QUOTA;
SIZE_T _MJ_SET_QUOTA;
SIZE_T _MJ_PNP;
SIZE_T _MJ_PNP_POWER;
SIZE_T _MJ_MAXIMUM_FUNCTION;
};
IDA Pro взлом и реверсинг программ

Мы добавляем и синхронизируем структуру, и последнее что мы делаем – открываем во вкладке LOCAL TYPES структуру _DRIVER_OBJECT и изменяем ее так, чтобы последнее поле представляло собой структуру типа _MAJORFUNCTION.

IDA Pro взлом и реверсинг программ

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

IDA Pro взлом и реверсинг программ

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

Мы видим, что регистр ESI сохраняет значение указателя на объект _DRIVER_OBJECT в этой области, а по адресу 0x000160СF и это значение указателя затирается.

IDA Pro взлом и реверсинг программ

Таким образом, мы помечаем эту зону (это можно сделать с помощью ALT + L, спустится стрелкой курсора и затем снова нажать ALT + L для завершения) или если это небольшая область сделать это той же мышью.

IDA Pro взлом и реверсинг программ

Как только зона отмечена, мы нажимаем T.

IDA Pro взлом и реверсинг программ

Конечно, мы выбираем регистр ESI в качестве базового регистра структуры и смещение, которое мы устанавливаем в нуль, потому что оно указывает на начало структуры, и мы выбираем структуру _DRIVER_OBJECT, и IDA обнаруживает 4 поля которые используются.

IDA Pro взлом и реверсинг программ

Для нас важно то поле, которое обрабатывает IOCTL, т.е. _MJ_DEVICE_CONTROL.

Если бы у нас не было символов, такая же работа выполнялась бы путем импорта файла .H с 32-битными структурами для реверсинга драйверов.

Файл .H с 32-битными структурами находится здесь.

https://drive.google.com/file/d/1VXwR45uvw1FtvzW2b9eNO1DLid9CIdx8/view?usp=sharing

И он импортируется в IDA отсюда.

IDA Pro взлом и реверсинг программ

При этом мы увидим необходимые структуры DRIVER_OBJECT, _IRP, _DEVICE_OBJECT, _IO_STACK_LOCATION и PIRP и _MAJORFUNCTION в LOCAL TYPES. Мы синхронизируем их и получим таким же образом возможность распознавать функцию, которая обрабатывает IOCTL.

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

IDA Pro взлом и реверсинг программ

Внутри этой функции, которая обрабатывает IOCTL, находятся различные уязвимые функции. В этом случае мы будем пытаться эксплуатировать функцию STACKOVERFLOWG.

IDA Pro взлом и реверсинг программ

Вызов идет сюда.

IDA Pro взлом и реверсинг программ

И затем сюда.

Мы видим, что есть функция MEMCPY, которая копирует буфер в стек. MAXCOUNT - количество байтов. Полностью отреверсив функцию мы увидим, что у неё есть COOKIE. Хотя мы это уже видели до адреса возврата, который в отличие от другого переполнения стека, который мы уже эксплуатировали.

IDA Pro взлом и реверсинг программ

Перед инструкцией RETN есть такой вызов.

IDA Pro взлом и реверсинг программ

Эта проверка и в начале функции она то же есть.

IDA Pro взлом и реверсинг программ

Возвращаясь к началу функции с именем IRPDEVICEIOCTLHANDLER, которая обрабатывает IOCTL, в регистре EDI передается указатель на структуру IRP. Мы уже видели в предыдущих туториалах, что в 32х битных системах по смещению 0x60 это был указатель на структуру IO_STACK_LOCATION, которая останется в регистре ESI.

И я нажимаю T на ESI + 0xC.

IDA Pro взлом и реверсинг программ

Как мы уже видели, что структура IO_STACK_LOCATION варьируется в зависимости от функции, в которой она используется , поскольку здесь мы используем её в случае функции, которая обрабатывает IOCTL. Мы должны выбрать DEVICEIOCONTROL.

IDA Pro взлом и реверсинг программ

Я оставлю всё это так. В этой функции, регистр ESI имеет указатель на IO_STACK_LOCATION, регистр EDX – это код IOCTL (IOCONTROLCODE) и EDI указатель на _IRP.

IDA Pro взлом и реверсинг программ

Регистр ESI и регистр EDI – это два аргумента вызова функции STACKOVERFLOWGSIOCTLHANDLER.

IDA Pro взлом и реверсинг программ

Конечно, поскольку у нас есть символы, мы можем видеть эти два аргумента в определении функции. Первый - это указатель на _IRP, а второй - указатель на IO_STACK_LOCATION.

IDA Pro взлом и реверсинг программ

Опять же, пытаясь определить поле _IO_STACK_LOCATION, мы должны выбрать случай, когда используется DEVICEIOCONTROL.

IDA Pro взлом и реверсинг программ

Мы видим, что то, что мы определили при реверсинге, совпадает с тем, что нам показывают символы.

IDA Pro взлом и реверсинг программ

Поле INPUTBUFFERLENGHT - это размер входного буфера из режима пользователя, а TYPE3INPUTBUFFER - указатель на этот пользовательский входной буфер, который мы также передаем.

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

IDA Pro взлом и реверсинг программ

Мы видим, что обе переменные используются без проверки или изменения в функции MEMCPY.

IDA Pro взлом и реверсинг программ

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

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Инициализируется только 0x1FF байт буфера. Также нет проблем, что некоторые байты ещё остались нетронутыми.

IDA Pro взлом и реверсинг программ

В начале функции мы видим, что выше адреса возврата есть структура CPPEH_RECORD.

IDA Pro взлом и реверсинг программ

Она находится чуть ниже буфера и поверх адреса возврата.

IDA Pro взлом и реверсинг программ

Мы видим, что в стек помещаются два аргумента. Константа 0x210 и указатель на структуру. Константа 0x210, так как это первый PUSH, будет чуть выше адреса возврата R, который я сохранил при входе в эту же функцию пролога.

IDA Pro взлом и реверсинг программ

Однако мы видим, что IDA показывает нам, что чуть выше "R" находится сохраненный регистр EBP т.е. "S".

IDA Pro взлом и реверсинг программ

Также, если мы войдем в функцию __SEH_PROLOG4_GS.

IDA Pro взлом и реверсинг программ

Мы видим, что после помещения в регистр EAX значения переменной CONS_0x210, программа сохраняет здесь регистр EBP, так что на самом деле выше "R" , наконец, остается "S" или сохраненный регистр EBP.

Затем, над сохраненным регистром EBP, помещается указатель на эту структуру которая передается сразу после инструкции PUSH 0x210.

IDA Pro взлом и реверсинг программ

По этому адресу находится структура STRU_0x12218. Программа сохраняет её чуть выше "S".

IDA Pro взлом и реверсинг программ

И чуть выше “S” находится переменная MS_EXC, которая является структурой типа CPPEH_RECORD, так что этот адрес будет последним полем этой структуры, и мы увидим это.

IDA Pro взлом и реверсинг программ

Здесь после сохранения сохраненного регистра EBP в переименую CONST_0X210 программа помещает адрес указанной переменной в регистр EBP. Это будет более или менее похоже на начало функции PUSH EBP, MOV EBP, ESP.

Оба должны сохранить значение регистра EBP родительской функции TRIGGERSTACKOVERFLOWGS и установить новый регистр EBP для неё через инструкцию LEA.

IDA Pro взлом и реверсинг программ

Затем программа освобождает место для переменных, выполняя инструкцию SUB ESP, EAX.

И также мы видим, что по адресу EBP-4 XORится значение, которое было там с COOKIE, которое читается из секции данных.

Напомним, что по адресу EBP-4 находится значение 0x12218. С этим значением XORится COOKIE и сохраняется по этому адресу.

IDA Pro взлом и реверсинг программ

Кроме того, XORится COOKIE с регистром EBP и полученное значение сохраняется по адресу EBP-1C.

IDA Pro взлом и реверсинг программ

Это то, что программа будет проверять в эпилоге.

IDA Pro взлом и реверсинг программ

И внутри функции __SECURITY_CHECK_COOKIE.

IDA Pro взлом и реверсинг программ

Программа сравнивает значения. Если они одинаковы, то всё хорошо, а если нет мне выкидывает BSOD.

Мы создадим стек с самого начала в соответствии с порядком, с которым программа размещает значения перед входом в пролог:

PUSH 0x210
PUSH 0x12218

Затем программа входит в пролог, который заставляет её сохранять адрес возврата в стеке, куда она будет возвращаться. Это будет адрес 0x000148E9, поскольку при выходе из пролога программа вернется туда.

IDA Pro взлом и реверсинг программ

Таким образом, при входе в пролог мы имеем в стеке два аргумента и адрес возврата, куда вернется программа.

IDA Pro взлом и реверсинг программ

Давайте продолжим смотреть на то, как аргументы помещаются в стек.

Затем есть еще две инструкции PUSH - адрес функции EXCEPTION_HANDLER4 и значение, которое содержит регистр FS:0.

IDA Pro взлом и реверсинг программ

Над обратным адресом тогда будут эти два значения.

IDA Pro взлом и реверсинг программ

Затем 0x210 перезаписывается STORED_EBP.

IDA Pro взлом и реверсинг программ

Мы знаем, что под сохраненным регистром EBP был адрес возврата в функцию TRIGGERSTACKOVERFLOWGS. Мы добавили его в наше представление стека.

IDA Pro взлом и реверсинг программ

Текущий регистр EBP остается с адресом STORE_EBP (смотри на адрес, а не значение)

Из регистра ESP вычитается значение 0x210 для пространства переменных, другими словами над адресом FS:0 - 0x210 останется регистр ESP.

IDA Pro взлом и реверсинг программ

Затем выше есть еще три PUSH - EBX, ESI и EDI.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Затем содержимое EBP-4 XORится с COOKIE.

Поскольку ТЕКУЩИЙ EBP продолжает указывать на адрес STORE_EBP, EBP-4 указывает на значение 0x12218, это значение XORится с COOKIE.

ЗНАЧЕНИЕ EBX
ЗНАЧЕНИЕ ESI
ЗНАЧЕНИЕ EDI




FS:0
__EXCEPT_HANDLER4
0x148E9 <---- АДРЕС ВОЗВРАТА В ПРОЛОГ
0x12218 <--------XORится с COOKIE
STORED_EBP <----- ТЕКУЩИЙ EBP - АДРЕС STORED_EBP
АДРЕС ВОЗВРАТА В ФУНКЦИЮ TriggerStackOverflowGS


Если мы сделаем так, чтобы уточнить первый столбец, с адресами ссылающимися на значение ТЕКУЩЕГО EBP.

ЗНАЧЕНИЕ EBX
ЗНАЧЕНИЕ ESI
ЗНАЧЕНИЕ EDI




EBP-10 FS:0
EBP-C __EXCEPT_HANDLER4
EBP-8 0x148E9 <---- АДРЕС ВОЗВРАТА В ПРОЛОГ
EBP-4 0x12218 <--------XORИТСЯ С COOKIE
EBP STORED_EBP <----- ТЕКУЩИЙ EBP - АДРЕС STORED_EBP
АДРЕС ВОЗВРАТА В
ФУНКЦИЮ TRIGGERSTACKOVERFLOWGS

Одна из проблем здесь заключается в том, что это не нормальная функция, которая при входе и выходе из ESP остается такой же, как и до помещения аргументов. Ваши аргументы хорошо сбалансированы. Это функция, которая является прологом функции TRIGGERSTACKOVERFLOWGS. Этот код должен быть частью той же функции и не должет быть идти отдельным CALL.

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

В обычной функции регистр ESP при возврате равен тому же значения, что и перед передачей аргументов.

IDA Pro взлом и реверсинг программ

Но в данном конкретном случае эта специальная функция похожа на часть функции TRIGGERSTACKOVERFLOWGS, выполняемой в отдельном CALL.

Если принимать регистр ESP в качестве нуля в начале функции, я вижу, что при возврате из CALL регистр увеличивается на 0x234 байт, потому что внутри функции пролога было сделано несколько инструкций PUSH, была выполнена инструкция SUB ESP, 0x210, и был осуществлен возврат из функции без восстановления регистра ESP.

IDA Pro взлом и реверсинг программ

Многие скажут, но если регистр ESP не восстановлен, как найти адрес возврата в стеке, который намного ниже значения регистра ESP.

Мы говорили, что адрес EBP-8 указывает на адрес возврата, чтобы вернуться из функции пролога в TRIGGERSTACKOVERFLOWGS и ТЕКУЩИЙ ESP после того, как три PUSH из EBX, ESI и EDI остались выше.

IDA Pro взлом и реверсинг программ

Если мы посмотрим в функции пролога, увидим, что она возвращает адрес возврата с помощью инструкции PUSH - RET.

IDA Pro взлом и реверсинг программ

Помещенное в стек значение, указанное через адрес EBP-8, является адресом возврата. Программа помещает значение обратно в стек и затем выполняет инструкцию RET, и программа возвращается к функции TRIGGERSTACKOVERFLOWGS, не восстанавливая ESP и оставляя весь стек целым, как это было в прологе.

Между инструкцией PUSH и RET есть только инструкции MOV и LEA, поэтому стек не затрагивается, и это аналогично PUSH-RET.

Мы уже знаем, как функция начинается, как все устроено в стеке и как функция возвращается, у нас есть некоторые вещи которые находятся в середине после трех PUSH перед возвратом.

Мы создали стек здесь.

IDA Pro взлом и реверсинг программ

До этого момента он был создан так.

ЗНАЧЕНИЕ EBX
ЗНАЧЕНИЕ ESI
ЗНАЧЕНИЕ EDI




EBP-10 FS:0
EBP-C __EXCEPT_HANDLER4
EBP-8 0x148E9 <---- АДРЕС ВОЗВРАТА В ФУНКЦИЮ ПРОЛОГ
EBP-4 0x12218 <--------XORED COOKIE
EBP STORED_EBP <----- ТЕКУЩИЙ EBP - АДРЕС STORED_EBP
АДРЕС ВОЗВРАТА В ФУНКЦИЮ TRIGGERSTACKOVERFLOWGS

Мы уже знаем, что ничего из этого не будет потеряно, все, что я добавлю или изменю в прологе в стеке, не будет удалено, поскольку PUSH-RET покинет стек, как это было для функции TRIGGERSTACKOVERFLOWGS.

Еще одна вещь, которая уже настроена для функции TRIGGERSTACKOVERFLOWGS, это регистр EBP.

IDA Pro взлом и реверсинг программ

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

Я смотрю функцию TRIGGERSTACKOVERFLOWGS, чтобы попытаться увидеть, где это соответствует адресу EBP-1C, где программа хранит COOKIE.

IDA Pro взлом и реверсинг программ

Мы видим, что переменная MS_EXC находится по адрес EBP-0x18. Другими словами место, где программа хранит COOKIE, которое вы собираетесь проверить, находится чуть выше структуры MS_EXC.

Напомним, что буфер DST был инициализирован только с 0x1FF байтами, и мы сказали, что осталось несколько байтов чуть ниже него, поэтому, если мы поправим размер DST на 0x1FF, у нас будет переменная, в которой сохраняется COOKIE в стеке.

IDA Pro взлом и реверсинг программ

Здесь я назначаю новый размер и у меня остается четыре пустых байта между ними. Я нажимаю D, пока я не изменю на DWORD (DD), и переименую переменную в COOKIE.

IDA Pro взлом и реверсинг программ

Я вижу, что это по адресу EBP-1C (слева от названия есть позиция относительно EBP т.е. 0x0000001C).

Затем идет инструкция PUSH EAX и сохраняется текущее значение регистра ESP по адресу EBP-18, которое было внутри структуры MS_EXC, которая начинается здесь. Это первое поле той же структуры.

IDA Pro взлом и реверсинг программ

Если мы заглянем внутрь структуры, первым полем будет OLD ESP

IDA Pro взлом и реверсинг программ

Так что стек стал таким

ЗНАЧЕНИЕ EAX
ЗНАЧЕНИЕ EBX
ЗНАЧЕНИЕ ESI
ЗНАЧЕНИЕ EDI


EBP-10 FS:0
EBP-C __EXCEPT_HANDLER4
EBP-8 0x148E9 <---- АДРЕС ВОЗВРАТА В ПРОЛОГ
EBP-4 0x12218 <--------XORится с COOKIE
EBP STORED_EBP <----- ТЕКУЩИЙ EBP - АДРЕС STORED_EBP
АДРЕС ВОЗВРАТА В ФУНКЦИЮ TRIGGERSTACKOVERFLOWGS

Поскольку теперь обе функции совместно используют стек, если мы сравним их, мы увидим, что над STORED_EBP находится значение MS_EXC, поэтому внутри пролога чуть выше переменной "S" байты также являются полями указанной структуры.

IDA Pro взлом и реверсинг программ

Эти 4 DWORDS являются 4 нижними полями структуры MS_EXC.

IDA Pro взлом и реверсинг программ

Помните, что последние 4 поля структуры - это другая структура размером 0x10 байтов, т.е. 16 в десятичной системе (4 DWORDS), поэтому на изображении отмечены только те 4 DWORDS.

IDA Pro взлом и реверсинг программ

Двумя важными переменными являются NEXT и EXCEPTION HANDLER. Мы уже знаем их положение в стеке. Мы видим, что переменная NEXT в структуре имеет значение FS:0, а EXCEPTION HANDLER на данный момент имеет значение __EXCEPT_HANDLER4, хотя они еще не добавлены в цепочку SEH.

ЗНАЧЕНИЕ EAX
ЗНАЧЕНИЕ EBX
ЗНАЧЕНИЕ ESI
ЗНАЧЕНИЕ EDI




EBP-10 FS:0 - (NEXT)
EBP-C __EXCEPT_HANDLER4 - (EXCEPTION_HANDLER)
EBP-8 0x148E9 <---- АДРЕС ВОЗВРАТА В ПРОЛОГ -(SCOPETABLE)
EBP-4 0x12218 <--------XORится с COOKIE (TRYLEVEL)
EBP STORED_EBP <----- ТЕКУЩИЙ EBP - АДРЕС STORED_EBP
АДРЕС ВОЗВРАТА В ФУНКЦИЮ TRIGGERSTACKOVERFLOWGS

Хорошо. У нас создан стек, и мы видим справа синие поля структуры.

Поскольку адрес возврата уже помещен в стек, изменение значения сохраненной переменной не имеет значения.

IDA Pro взлом и реверсинг программ

Мы видим, что в по адресу EBP-8 (SCOPETABLE) программа сохраняет значение COOKIE, XORит его со значением 0x12218, которое было в EBP-4, а затем в том же EBP-4, что является TRYLEVEL, сохраняет значение 0xFFFFFFFE.

В конце программа сохраняет адрес EBP-10 - NEXT в регистр FS:0 с настроенным обработчиком исключений.

Мы знаем, что регистр FS:0 указывает на последний элемент в списке цепочки исключений, т.е на верхнюю часть всей цепочки.

Помните, что добавление нового элемента в список осуществляется с помощью этого кода

PUSH OFFSET HANDLER
PUSH FS:[0]
MOV FS:[0], ESP


Т.е. поскольку здесь выполняется следующая инструкция.

MOV LARGE FS:0, EAX

Этот регистр EAX является адресом стека, где находится новый NEXT и ниже SEH.

Так как регистр EAX является адресом EBP-10, здесь будет переменная NEXT и чуть ниже SEH, как мы уже говорили.

Если я отлаживаю код и отправляю данные эксплойту, который обходит правильный IOCTL для достижения уязвимой функции (Позже мы увидим, как это сделать. Сейчас же это просто для проверки).

IDA Pro взлом и реверсинг программ

Я вижу, что регистр FS:0 указывает на верхний элемент цепочки SEH. В моем случае он равен 9CCEFCC0. Если я посмотрю, здесь должны быть переменные NEXT и SEH. Переменная NEXT равна 0xFFFFFFFF, потому что это последний NEXT в цепочке исключений.

IDA Pro взлом и реверсинг программ

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

IDA Pro взлом и реверсинг программ

Если я продолжу трассировать пролог, я попадаю туда, где регистр EAX сохранится в регистр FS:0.

IDA Pro взлом и реверсинг программ

Здесь мы видим новый драйвер, добавленный в цепочку.

IDA Pro взлом и реверсинг программ

Как мы уже рассматривали, адрес EBP-10 будет новым NEXT, а ниже находится SEH, который будет являться _EXCEPT_HANDLER4. Это то значение, которое мы должны будем переписать для эксплуатации

IDA Pro взлом и реверсинг программ

Хорошо. У нас уже все хорошо расположено. Пора начинать писать эксплойт.

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

Идея состоит в том, что, поскольку сбой происходит при доступе на чтение к буферу пользовательского режима, это приводит к тому, что он обрабатывается как сбой в режиме пользователя и происходит переходит к SEH, а не обрабатывается как сбой ядра, что вызывает BSOD.

Метод работает, но эксплойт делаем сбой и вызывает BSOD. Так что нам нужно будет увидеть, где произошел сбой. Наверняка есть что-то что мы не видим.

Основное объяснение этого метода находится здесь:

http://poppopret.blogspot.com/2011/07/windows-kernel-exploitation-basics-part_16.html

И исходный код публичного эксплойта находится здесь:

https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/tree/master/Exploit

Я не собираюсь делать все это также на PYTHON, потому что это того не стоит, но давайте посмотрим, как автор это объясняет и исправим, то что не работает.

Прежде всего, если бы мы сделали это в PYTHON, у нас была бы проблема, которую можно решить, но, компилируя его в C++, у нас уже есть модуль, который помимо запуска и экслуатации повышения привилегий, мы можем скомпилировать его по своему вкусу, например, без SAFESEH, или DEP или ASLR. В опциях VISUAL STUDIO позволят нам выбрать то что нужно, поэтому, если кто-то загружает решение, т.е. файл SLN в VISUAL STUDIO, вам придется изменить параметры по умолчанию.

IDA Pro взлом и реверсинг программ

Чуть выше находится это.

IDA Pro взлом и реверсинг программ

Хорошо. Я приложу скомпилированный файл с его символами HACKSYSEVDEXPLOIT.EXE и HACKSYSEVDEXPLOIT.PDB, чтобы его было легко увидеть в IDA.

Исполняемый файл скомпилирован для всех уязвимостей, которые есть у драйвера, и его выполнение в консоли в WINDOWS 7 32 с аргументами -G -C XXX.EXE достаточно, так как я уже добавляю в конце этого метода выполнение калькулятора c правами SYSTEM после поднятия прав. В остальных вместо XXX.EXE придется подставить CALC.EXE или CMD.EXE

Хорошо. Мы переходим к функции, которая использует эту уязвимость. В данном случае - STACKOVERFLOWGSTHREAD.

IDA Pro взлом и реверсинг программ

После исправления некоторых проблем консоли, которые не имеют отношения, давайте проанализируем эксплойт, который мы открываем в IDA, и видим, что эксплойт начинается здесь:

IDA Pro взлом и реверсинг программ

Внутри мы видим вызов функции CREATEFILE для получения дескриптора драйвера.

IDA Pro взлом и реверсинг программ

Все это так же, как и случаи, которые мы видели в предыдущих ядрах.

Регистр EBX остается с дескриптором драйвера, он используется только при вызове DEVICEIOCONTROL ниже.

IDA Pro взлом и реверсинг программ

Хорошо. Затем идет вызов функции CREATEFILEMAPPING, что является пространством виртуальной памяти, которое будет связано с содержимым файла. (Функция не резервирует память, только создает объект и возвращает дескриптор)

https://docs.microsoft.com/en-us/windows/desktop/memory/file-mapping

IDA Pro взлом и реверсинг программ

Но если мы посмотрим в описание функции CREATEFILEMAPPING, мы увидим, что первым аргументом является дескриптором файла, но нам также говорится, что может быть передан аргумент INVALID_HANDLE_VALUE. В этом случае, программа создаст отображение файла, не связывая его с файлом, и это будет общая анонимная память.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Хорошо. Это тот случай, поэтому мы видим, что когда вызывается эта API, вы передаете значение 0xFFFFFFFF, которое является INVALID_HANDLE_VALUE.

IDA Pro взлом и реверсинг программ

В исходном коде, под названием SHARED MEMORY, созданном здесь, мы видим, что функции передаются разрешение на выполнение, чтение и запись.

IDA Pro взлом и реверсинг программ

Хорошо. Она возвращает нам дескриптор файлового отображения.

IDA Pro взлом и реверсинг программ

Затем программа вызывает функцию MAPVIEWOFFILE, которая отображает объект в памяти, зарезервировав необходимое для него пространство.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Хорошо. Функция возвращает адрес начала секции, созданного для отображения файлов.

Чтобы отладить эксплойт в режиме пользователе, несмотря на драйвер, я копирую сервер IDA - WIN32_REMOTE.EXE в целевую машину и запускаю его.

IDA Pro взлом и реверсинг программ

Я запускаю его на сервере с правами администратора в целевой системе, а на машине, где я реверсил эксплойт, меняю отладчик на удаленный отладчик WINDOWS. В PROCESS OPTIONS я указываю IP-адрес и порт.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Напомним, что мы можем отлично отладить этот эксплойт в пользовательском режиме, но на шелл-код, который вызывается из ядра, мы не сможем поставить BP или что-либо еще, потому что это вызовет исключение INT3 в ядре, которое не обрабатывается как в пользовательском режиме, и будет создан BSOD.

Если мы запустим файл без аргументов, он покажет нам опции.

IDA Pro взлом и реверсинг программ

Я запускаю эксплойт с аргументами -G, чтобы задействовать уязвимость STACK OVERFLOW GS,

IDA Pro взлом и реверсинг программ

Теперь я ожидаю.

IDA Pro взлом и реверсинг программ

Так что я могу теперь прикрепить IDA, ту где я реверсил эксплойт (не ту, которой был проанализирован драйвер)

IDA Pro взлом и реверсинг программ

Нажав клавишу в целевой машине, чтобы пропустить паузу, мы останавливаемся на BP, который я ставлю после паузы.

IDA Pro взлом и реверсинг программ

Я дохожу до функции CREATEFILEMAPPING.

IDA Pro взлом и реверсинг программ

Пройдя вызов с помощью F8, мне возвращается дескриптор файла.

IDA Pro взлом и реверсинг программ

Как мы уже говорили, этот дескриптор передается в регистре ESI.

IDA Pro взлом и реверсинг программ

Здесь нам вернется адрес отображаемого файла.

IDA Pro взлом и реверсинг программ

Это секция будет из 0x1000 байт.

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

Я поставлю эту IDA на паузу на одну минуту и открою другую, где у меня есть драйвер.

Одна вещь, которую я не видел и допустил ошибку - это то, что буфер назначения

IDA Pro взлом и реверсинг программ

Мы видим, что он инициализируется байтами 0x1FF, но непосредственно перед обнулением байта, который находится чуть выше, и место назначения начинается с VAR_21C, поэтому вам нужно исправить буфер назначения, чтобы иметь возможность хорошо вычислять размер, и теперь начинать с VAR_0x21C, и он будет равен 0x200 байт.

IDA Pro взлом и реверсинг программ

Теперь, если всё в порядке, я переименую его в BUFFER_DESTINO.

Это выглядит хорошо. Здесь прямо в функции MEMCPY, и мы можем скопировать количество байтов, которые нам нужны.

IDA Pro взлом и реверсинг программ

Очевидно, что мы не должны копировать с начала секции файлового отображения, потому что данные должны быть копированы только до SEH. Я должен увидеть, сколько байтов я должен скопировать.

Мы должны скопировать 0x200 байт, чтобы заполнить буфер. Еще 4, чтобы перезаписать COOKIE, а затем ещё идёт структура MS_EXC.

Внутри структуры есть 8 байтов, а затем NEXT и SEH, поэтому было бы так.

Всего cкопировано = 0x200 + 4 + 8 + NEXT + SEH.

IDA Pro взлом и реверсинг программ

Т.е. 0x214 байтами мы перезаписываем SEH.

IDA Pro взлом и реверсинг программ

Поскольку длина секции составляет 0x1000 байт, чтобы узнать, какое адрес передать, чтобы начать копирование, в начальный адрес секции я добавляю 0x1000, а затем вычитаю 0x214. При этом программа будет использовать этот новый адрес в качестве входного буфера, просто, чтобы перезаписать SEH и вызвать сбой при чтении.

Давайте посмотрим на это в отладчике, который был остановлен на эксплойте.

IDA Pro взлом и реверсинг программ

Мы видим, что адрес файлового отображения, хранится в регистре ESI и к нему добавляется значение 0xDEC. Т.е. 0x10000x214 = 0xDEC.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

На моей машине 0x2C0DEC будет адресом, с которого начнется копирование 0x214 байт. Источник функции MEMCPY в стек.

Затем остается скопировать необходимый буфер, что и делается дальше.

С помощью функции MEMSET заполняется вcя секция буквами A (0x41)

IDA Pro взлом и реверсинг программ

Здесь заполняется входной буфер.

IDA Pro взлом и реверсинг программ

Мы видим, что в позицию 0x0204 записывается значение 0x42424242. Это предположительно говорит о том, что программа перезаписала COOKIE, так как буфер занимает 0x200, а COOKIE находится ниже. Для меня, так как это значение 0x204, перезаписывается DWORD чуть ниже COOKIE - первое поле структуры MS_EXC.

Затем программа записывает по адресу ESI + 4 значение 0x43434343.

IDA Pro взлом и реверсинг программ

Затем добавляет значение 8 к исходному регистру ESI и записывает NEXT и SEH.

IDA Pro взлом и реверсинг программ

Мы видим, что, как я уже сказал, COOKIE не перезаписался значением 0x41414141, и я затер чуть ниже 4 DWORD структуры MS_EXC.

IDA Pro взлом и реверсинг программ

Это 4 DWORD которые я перезаписал, поэтому последний DWORD - это SEH.

IDA Pro взлом и реверсинг программ

Чуть ниже SEH заканчивается секция. Поскольку мы хотим вызвать сбой при чтении мы продолжим чтение данных. Мы передадим размер немного больше, чем 0x214.

Я устанавливаю BP перед функцией DEVICEIOCONTROL, и когда я нажимаю RUN, мне нужно нажать клавишу в целевой маишине, чтобы пройти следующую системную паузу.

IDA Pro взлом и реверсинг программ

Давайте посмотрим аргументы, которые передаются функции.

IDA Pro взлом и реверсинг программ

Указатель на возвращенные байты передаются с помощью инструкции LEA. Затем идет PUSH 0 и PUSH 0 для выходного буфера. Его размер не имеет значения. Затем мы видим, что количество байтов, которые мы передает функции, чтобы она скопировала из входного буфера, равно 0x218 или на 4 байт больше, чем длина входного буфера, который был равен 0x214. Это приведет к сбою при чтении в конце источника.

Адрес входного буфера был оставлен в регистре EDI.

IDA Pro взлом и реверсинг программ

И затем передается код IOCTL 0x222007 от этой ошибки STACK OVERFLOW GS и дескриптор устройства, который находится в регистре EBX.

Мы уже проанализировали эксплойт. Поэтому теперь мы можем закрыть его и присоединить IDA с анализом драйвера к ЯДРУ и посмотреть, как копируются данные.

Прежде чем прикрепить IDA, я поставлю BP в начале уязвимой функции.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Готово. IDA уже обнаружила, что это тот же файл, который я проанализировал, и если я соглашусь и перемещу базу секции, IDA скажет, что это тот же файл.

Я запускаю эксплойт на целевой машине.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Мы останавливаемся на BP.

IDA Pro взлом и реверсинг программ

Как мы уже говорили, будут скопированы NEXT и SEH, которые мы должны будем перезаписать позже в функции MEMCPY.

IDA Pro взлом и реверсинг программ

Потому что, когда мы нажимаем RUN, мы будем копировать данные и продолжим, не имея возможности остановить этот процесс. Мы можем установить BPM ON WRITE, чтобы остановить отладчик, когда скопируется NEXT прямо перед сбоем. Поэтому мы посмотрим, все ли в порядке.

IDA Pro взлом и реверсинг программ

Я вставил это в панель WINDBG.

IDA Pro взлом и реверсинг программ

Я создаю сегмент и преобразовываю его в код.

IDA Pro взлом и реверсинг программ

Или если мне хочется посмотреть на сегмент в панели WINDBG, я делаю так.

IDA Pro взлом и реверсинг программ

Напомним, что когда я armada источник мы помещаем значение 0x44444444, чтобы перезаписать значение NEXT.

IDA Pro взлом и реверсинг программ

Это изображение выше было источником. Давайте посмотрим, хорошо ли оно перезаписано в стеке.

IDA Pro взлом и реверсинг программ

Вот оно. Я останавливаюсь на BPM ON WRITE сразу после копирования NEXT, и теперь я скопирую SEH. Я нажимаю F7.

IDA Pro взлом и реверсинг программ

Сюда я скопирую наш SEH.

Также я могу посмотреть на него в IDA.

IDA Pro взлом и реверсинг программ

Конечно, модуль эксплойта, куда будет переходить отладчик, скомпилирован без DEP и без SAFE SEH, поскольку это является частью эксплуатации. Если бы он был создан с PYTHON, проблем не было бы. Вам нужно было бы создать область памяти, которая позволила бы ему работать с функцией VIRTUALALLOC, скопировать туда код и указать адрес этой области как SEH.

Давайте не будем забывать, что это PRIVILEGE ESCALATION, поэтому у нас уже есть выполнение кода на машине, но с обычным пользователем. Идея состоит в том, чтобы масштабироваться до прав SYSTEM, чтобы мы могли выполнять действия на компьютере, ограниченные нашими привилегиями, но запускать EXE с теми же привилегией. Также, если бы это был PYTHON, мы должны установить PYTHON для запуска .PY.

Давайте посмотрим на процедуру обработчика исключений.

IDA Pro взлом и реверсинг программ

Я уже создал сегмент, я преобразовал его в код с C, и я создал функцию.

IDA Pro взлом и реверсинг программ

Здесь я не могу поставить BP в отладчике в пользовательском режиме на целевой машине, но могу сделать так.

IDA Pro взлом и реверсинг программ

Я помещаю эту команду в WINDBG. Затем я нажимаю RUN.

Отладчик остановился здесь. Наш обработчик исключений работает.

IDA Pro взлом и реверсинг программ

Конечно, этот код - это шелл-код который называется как TOKEN STEALER, который уже был проанализирован в предыдущих туториалах.

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

IDA Pro взлом и реверсинг программ

В регистр EDX вы должны поместить регистр EIP, куда программа вернетесь, когда вернетесь в пользовательский режим, а в регистр ECX - регистр ESP. В моем случае, поскольку файл компилирован без ASLR, я помещаю в регистр EDX адрес чуть ниже вызова DEVICEIOCONTROL, а в регистр ESP адрес основания стека 0x12FF00, который не совпадает со значением, которое выполнялось до вызова функции DEVICEIOCONTROL, но, поскольку я сохранил адрес в секции данных в регистре ESP, которое у меня был, когда я вернусь, я смогу восстановить правильный регистр ESP.

В другой IDA с анализом модуля эксплойта я вижу адрес, куда я вернусь.

IDA Pro взлом и реверсинг программ

В текущей IDA, в которой я отлаживаю, я вижу ту же часть кода.

IDA Pro взлом и реверсинг программ

Я могу поставить здесь BP.

IDA Pro взлом и реверсинг программ

Я удаляю предыдущие BP.

IDA Pro взлом и реверсинг программ

И нажимаю RUN.

IDA Pro взлом и реверсинг программ

Я вижу, что программа вернулась в режим пользователя с регистрами EIP и ESP, которые я установил до вызова SYSEXIT.

Здесь восстанавливается регистр ESP. Идет чтение с того места, где вы его сохранили, в секции данных 0x4212B0.

IDA Pro взлом и реверсинг программ

Теперь я буду выполнять калькулятор или код, который я хочу, с привилегиями SYSTEM. Я мог бы, например, инжектировать код в какой-нибудь процесс SYSTEM, и выйти.

IDA Pro взлом и реверсинг программ

Я удаляю все BP и нажимаю RUN.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Давайте посмотрим, какой пользователь является владельцем.

IDA Pro взлом и реверсинг программ

Готово. Я закончил. Я могу повышать привилегии до SYSTEM.

Я приложил ZIP файл с измененным исходным кодом и скомпилированным исполняемым файлом. Помните, что если вы скомпилируете его самостоятельно, вы должны сделать это без DEP, без SAFE SEH и без ASLR, и он будет работать только в 32-разрядной версии WINDOWS 7 и отрегулировать.

Обсуждение статьи: Обход Cookie в уязвимом драйвере HACKSYS. IDA Pro «с нуля» ч.67 >>>


При перепечатке ссылка на https://exelab.ru обязательна.



Видеокурс ВЗЛОМ