Эксплоит для уязвимого драйвера. Два буфера. IDA Pro «с нуля» ч.61

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


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

Многие спрашивают меня, почему бы не проанализировать его непосредственно в C или C++. Проблема состоит в том, что некоторые из них уже сделаны на C и C++. Методы те же самые. Поэтому перенос их на PYTHON не только приносит что-то новое, но и заставляет нас практиковаться в PYTHON и библиотеке CTYPES, что является для нас важным.

Для тех, кто хочет увидеть методы, исходный код доступен здесь:

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

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

Мы же продолжим с PYTHON и будем использовать библиотеку CTYPES, что, хотя и немного раздражает, позволит нам делать почти то же самое.

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

Здесь у нас есть блок, который перемещает нас в IOCTL, где вызывается INTEGER OVERFLOW.

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

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

Регистр EAX у нас равен 0x0022201F.

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

И чтобы идти по правильному пути, я изменяю регистр EDX, содержащий наш IOCTL код. Он должен быть больше, чем регистр EAX.

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

Затем программа передает наше значение в регистр EAX и вычитает значение 0x00222023, и если оно не равен нулю, программа вычитает еще 4, что остаётся в регистре ECX. Затем идут инструкции PUSH 4 - POP ECX. Если результат равен нулю, программа перейдёт к правильному блоку.

IOCTL – 0x222023 – 0x4 = 0

IOCTL = 0x222023 + 0x4

Python>hex(0x222023 + 4)
0x222027

Этот IOCTL будет тем, который перенесет нас в блок, где срабатывает INTEGER OVERFLOW. Давайте проанализируем его.

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

Мы видим, что, как и в предыдущем случае, программа передает в функцию два аргумента: первый это адрес структуры IRP, а второй - _IO_STACK_LOCATION.

Поскольку мы уже импортировали структуру _IO_STACK_LOCATION, здесь программа перемещает её начальный адрес и начинается работа с ее смещениями. Поле 0x10. Давайте посмотрим, что это. Я нажимаю T и выбирает соответствующую структуру.

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

Мы видим, что

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

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

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

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

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

Здесь мы видим эти два аргумента. Программа также устанавливает переменную STATUS в нуль. А в стеке есть буфер с именем KERNELBUFFER. Давайте посмотрим его длину.

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

Длина равна 512 * 4, так как каждый компонент является DWORD (DD), поэтому общая длина будет равна.

Python>hex(512 * 4)
0x800

Программа инициализируйте в нуль этот буфер, сначала записав здесь первые 4 байта регистра EDI, который равен нулю. А затем вызывает функцию MEMSET из оставшихся 0x7FC байтов, добавив 4 к месту назначения в инструкции LEA, чтобы программа записывала данные начиная на 4 байтов больше.

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

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

Здесь также есть структура. Мы увидим, для чего она нужна. IDA обнаружил её.

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

Посмотрим, что она делает. Здесь сказано следующее.

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

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

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

Затем печатается 4 значения: размер, который мы передали из пользовательского буфера, указатель на пользовательский буфер, адрес KERNELBUFFER и его размер.

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

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

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

Мы видим, что блок принимает размер, который передается в регистре EBX и сравнивает его с константой 0x800, которая находится в регистре ESI.

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

Но прежде, в мой размер добавляет значение 4. И если он будет ниже, все будет нормально.

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

Мы уже видим проблему. Eсли мы передадим в качестве размера, например число 0XFFFFFFFF, при добавлении 4 произойдет INTEGER OVERFLOW, и результат будет таким.

Python>hex((0xffffffff + 4))
0x100000003L

Если мы сократим его до 32 бит как делает процессор, то получим

Python>hex((0xffffffff + 4) & 0xffffffff)
0x3L

Это дает нам в результате 3. И это меньше, чем 0x800, даже при сравнении без знака.

Затем программа берет исходный размер и делает с ним SHR или другими словами делит его на 4 с учетом знака. Это делается потому, что копируется DWORDS, а индекс идет один за другим. Поэтому размер - это общее число, разделенное на 4.

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

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

Если бы наш размер был равен 0XFFFFFFFF, то разделив его на 4, это дало бы нам значение 0x3FFFFFFF.

Мы видим, что это цикл, где регистр EDI является счетчиком.

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

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

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

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

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

Если программа прочитает буфер пользователя, в тот, что мы отправляем значение 0x0BAD0B0B0, она выйдет из цикла.

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

Наконец, она скопируйте в буфер ядра. Программа развернет выполнение с помощью регистра EDI, который является счетчиком умноженным на 4, то есть она скопирует 4 * 4 байтов.

Затем она складывает значение 4 с адресом буфера пользовательского режима, увеличивает регистр EDI, сохраняет его в переменную COUNT и готово. Это всё, что нужно. Поэтому мы можем спровоцировать переполнение стека, контролируя его большим размером. Мы даже можем выйти из него до того, как программа разрушит весь стек, так как это дает нам возможность выйти из цикла, обработанного нами.

С этими данными мы можем перезаписывать адрес возврата без проблем.

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

Перед тем, как сделать это в PYTHON, я запускаю исполняемый файл эксплойта, чтобы проверить, что он reversee, и при анализе мы используем IOCTL код равный 0x222027.

Затем программа достигает блока.

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

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

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

Здесь мы видим его содержимое.

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

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

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

И я вижу наш DWORD где-то здесь.

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

Я добираюсь до функции, которая вызывает INTEGER OVERFLOW.

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

Мы видим, что размер который мы передаём равен 0xFFFFFFFF.

Регистр EAX = 3, что меньше, чем 0x800.

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

После инструкции SHR.

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

Программа читает содержимое буфера пользовательского режима и оно равно 0x41414141.

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

Поскольку это не выходная константа равная 0x0BAD0B0B0, программа копирует ее в буфер ядра стека.

Я устанавливаю BP здесь для того, чтобы программа остановилась, когда закончиться копирование.

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

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

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

Как только я создаю сегмент, я создаю код клавишей C и создаю функцию с помощью CREATE FUNCTION, и теперь это смотрится лучше.

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

Здесь мы видим калькулятор с правами SYSTEM.

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

Теперь идея сделать то же самое, но только в PYTHON.

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

Я вижу, что буфер состоит из 2088 десятичных байт, когда элементом является байтом. Если это DWORD, то он должен быть умножен на 4

Python>hex(2088)
0x828

Другими словами, мой буфер будет равен 0x828 + адрес для перезаписи адреса возврата.

Я вижу, что адаптация скрипта переполнения стека работает.

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

Я меняю IOCTL; Я установил размер пользовательского буфера равным -1. Я передаю указатель на пользовательский буфер чтобы перезаписать адрес возврата. В эксплойте на C я создал два буфера: один для перезаписи адреса возврата и другой с шеллкодом, в который я поместил всё в одном.

Data = shellcode + ((0x828 -len(shellcode)) * "A") + struct.pack("<L",int(buf)) + struct.pack("<L",0x0BAD0B0B0 )

Это шеллкод. Затем он заполняется 0x828 байтами минус длина шелл-кода умноженного на “A”. Затем идет указатель на тот же буфер, который используется для перезаписи по адресу возврата, и выходной DWORD равный 0x0BAD0B0B0.

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

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


=======================================================
Автор текста: Рикардо Нарваха - Ricardo Narvaja (@ricnar456)
Перевод на русский с испанского: Яша_Добрый_Хакер(Ростовский фанат Нарвахи).
21.12.2018
Версия 1.0


Обсуждение статьи: Эксплоит для уязвимого драйвера. Два буфера. IDA Pro «с нуля» ч.61 >>>


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



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