Проблема в том, что эта секция будет использоваться источником, и вам нужно скопировать данные до SEH, а затем завершить ввод, поэтому происходит сбой чтения перед копированием всего стека и сбой в стеке ядра.
Я поставлю эту IDA на паузу на одну минуту и открою другую, где у меня есть драйвер.
Одна вещь, которую я не видел и допустил ошибку - это то, что буфер назначения
Мы видим, что он инициализируется байтами 0x1FF, но непосредственно перед обнулением байта, который находится чуть выше, и место назначения начинается с VAR_21C, поэтому вам нужно исправить буфер назначения, чтобы иметь возможность хорошо вычислять размер, и теперь начинать с VAR_0x21C, и он будет равен 0x200 байт.
Теперь, если всё в порядке, я переименую его в BUFFER_DESTINO.
Это выглядит хорошо. Здесь прямо в функции MEMCPY, и мы можем скопировать количество байтов, которые нам нужны.
Очевидно, что мы не должны копировать с начала секции файлового отображения, потому что данные должны быть копированы только до SEH. Я должен увидеть, сколько байтов я должен скопировать.
Мы должны скопировать 0x200 байт, чтобы заполнить буфер. Еще 4, чтобы перезаписать COOKIE, а затем ещё идёт структура MS_EXC.
Внутри структуры есть 8 байтов, а затем NEXT и SEH, поэтому было бы так.
Всего cкопировано = 0x200 + 4 + 8 + NEXT + SEH.
Т.е. 0x214 байтами мы перезаписываем SEH.
Поскольку длина секции составляет 0x1000 байт, чтобы узнать, какое адрес передать, чтобы начать копирование, в начальный адрес секции я добавляю 0x1000, а затем вычитаю 0x214. При этом программа будет использовать этот новый адрес в качестве входного буфера, просто, чтобы перезаписать SEH и вызвать сбой при чтении.
Давайте посмотрим на это в отладчике, который был остановлен на эксплойте.
Мы видим, что адрес файлового отображения, хранится в регистре ESI и к нему добавляется значение 0xDEC. Т.е. 0x1000 – 0x214 = 0xDEC.
На моей машине 0x2C0DEC будет адресом, с которого начнется копирование 0x214 байт. Источник функции MEMCPY в стек.
Затем остается скопировать необходимый буфер, что и делается дальше.
С помощью функции MEMSET заполняется вcя секция буквами A (0x41)
Здесь заполняется входной буфер.
Мы видим, что в позицию 0x0204 записывается значение 0x42424242. Это предположительно говорит о том, что программа перезаписала COOKIE, так как буфер занимает 0x200, а COOKIE находится ниже. Для меня, так как это значение 0x204, перезаписывается DWORD чуть ниже COOKIE - первое поле структуры MS_EXC.
Затем программа записывает по адресу ESI + 4 значение 0x43434343.
Затем добавляет значение 8 к исходному регистру ESI и записывает NEXT и SEH.
Мы видим, что, как я уже сказал, COOKIE не перезаписался значением 0x41414141, и я затер чуть ниже 4 DWORD структуры MS_EXC.
Это 4 DWORD которые я перезаписал, поэтому последний DWORD - это SEH.
Чуть ниже SEH заканчивается секция. Поскольку мы хотим вызвать сбой при чтении мы продолжим чтение данных. Мы передадим размер немного больше, чем 0x214.
Я устанавливаю BP перед функцией DEVICEIOCONTROL, и когда я нажимаю RUN, мне нужно нажать клавишу в целевой маишине, чтобы пройти следующую системную паузу.
Давайте посмотрим аргументы, которые передаются функции.
Указатель на возвращенные байты передаются с помощью инструкции LEA. Затем идет PUSH 0 и PUSH 0 для выходного буфера. Его размер не имеет значения. Затем мы видим, что количество байтов, которые мы передает функции, чтобы она скопировала из входного буфера, равно 0x218 или на 4 байт больше, чем длина входного буфера, который был равен 0x214. Это приведет к сбою при чтении в конце источника.
Адрес входного буфера был оставлен в регистре EDI.
И затем передается код IOCTL 0x222007 от этой ошибки STACK OVERFLOW GS и дескриптор устройства, который находится в регистре EBX.
Мы уже проанализировали эксплойт. Поэтому теперь мы можем закрыть его и присоединить IDA с анализом драйвера к ЯДРУ и посмотреть, как копируются данные.
Прежде чем прикрепить IDA, я поставлю BP в начале уязвимой функции.
Готово. IDA уже обнаружила, что это тот же файл, который я проанализировал, и если я соглашусь и перемещу базу секции, IDA скажет, что это тот же файл.
Я запускаю эксплойт на целевой машине.
Мы останавливаемся на BP.
Как мы уже говорили, будут скопированы NEXT и SEH, которые мы должны будем перезаписать позже в функции MEMCPY.
Потому что, когда мы нажимаем RUN, мы будем копировать данные и продолжим, не имея возможности остановить этот процесс. Мы можем установить BPM ON WRITE, чтобы остановить отладчик, когда скопируется NEXT прямо перед сбоем. Поэтому мы посмотрим, все ли в порядке.
Я вставил это в панель WINDBG.
Я создаю сегмент и преобразовываю его в код.
Или если мне хочется посмотреть на сегмент в панели WINDBG, я делаю так.
Напомним, что когда я armada источник мы помещаем значение 0x44444444, чтобы перезаписать значение NEXT.
Это изображение выше было источником. Давайте посмотрим, хорошо ли оно перезаписано в стеке.
Вот оно. Я останавливаюсь на BPM ON WRITE сразу после копирования NEXT, и теперь я скопирую SEH. Я нажимаю F7.
Сюда я скопирую наш SEH.
Также я могу посмотреть на него в IDA.
Конечно, модуль эксплойта, куда будет переходить отладчик, скомпилирован без DEP и без SAFE SEH, поскольку это является частью эксплуатации. Если бы он был создан с PYTHON, проблем не было бы. Вам нужно было бы создать область памяти, которая позволила бы ему работать с функцией VIRTUALALLOC, скопировать туда код и указать адрес этой области как SEH.
Давайте не будем забывать, что это PRIVILEGE ESCALATION, поэтому у нас уже есть выполнение кода на машине, но с обычным пользователем. Идея состоит в том, чтобы масштабироваться до прав SYSTEM, чтобы мы могли выполнять действия на компьютере, ограниченные нашими привилегиями, но запускать EXE с теми же привилегией. Также, если бы это был PYTHON, мы должны установить PYTHON для запуска .PY.
Давайте посмотрим на процедуру обработчика исключений.
Я уже создал сегмент, я преобразовал его в код с C, и я создал функцию.
Здесь я не могу поставить BP в отладчике в пользовательском режиме на целевой машине, но могу сделать так.
Я помещаю эту команду в WINDBG. Затем я нажимаю RUN.
Отладчик остановился здесь. Наш обработчик исключений работает.
Конечно, этот код - это шелл-код который называется как TOKEN STEALER, который уже был проанализирован в предыдущих туториалах.
Ошибка в исходном коде была в отмеченной области после возврата, чтобы украсть системный токен и сохранить его, чтобы повысить привилегии нашему процессу. Есть инструкция POPAD, которая восстанавливает регистры, сохраненные в начале с помощью инструкции PUSHAD, И потом не так легко вернуться из ядра исключения к режиму пользователю без прерывания, поэтому мы следовали советам, используя инструкцию SYSEXIT.
В регистр EDX вы должны поместить регистр EIP, куда программа вернетесь, когда вернетесь в пользовательский режим, а в регистр ECX - регистр ESP. В моем случае, поскольку файл компилирован без ASLR, я помещаю в регистр EDX адрес чуть ниже вызова DEVICEIOCONTROL, а в регистр ESP адрес основания стека 0x12FF00, который не совпадает со значением, которое выполнялось до вызова функции DEVICEIOCONTROL, но, поскольку я сохранил адрес в секции данных в регистре ESP, которое у меня был, когда я вернусь, я смогу восстановить правильный регистр ESP.
В другой IDA с анализом модуля эксплойта я вижу адрес, куда я вернусь.
В текущей IDA, в которой я отлаживаю, я вижу ту же часть кода.
Я могу поставить здесь BP.
Я удаляю предыдущие BP.
И нажимаю RUN.
Я вижу, что программа вернулась в режим пользователя с регистрами EIP и ESP, которые я установил до вызова SYSEXIT.
Здесь восстанавливается регистр ESP. Идет чтение с того места, где вы его сохранили, в секции данных 0x4212B0.
Теперь я буду выполнять калькулятор или код, который я хочу, с привилегиями SYSTEM. Я мог бы, например, инжектировать код в какой-нибудь процесс SYSTEM, и выйти.
Я удаляю все BP и нажимаю RUN.
Давайте посмотрим, какой пользователь является владельцем.
Готово. Я закончил. Я могу повышать привилегии до SYSTEM.
Я приложил ZIP файл с измененным исходным кодом и скомпилированным исполняемым файлом. Помните, что если вы скомпилируете его самостоятельно, вы должны сделать это без DEP, без SAFE SEH и без ASLR, и он будет работать только в 32-разрядной версии WINDOWS 7 и отрегулировать.
Введение в реверсинг с нуля, используя IDA PRO. Часть 67. Часть 2.
Дата публикации 19 июн 2019
| Редактировалось 4 июл 2019