Решение задания Nico для Ekoparty. IDA Pro «с нуля» ч.65

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


Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник 2020 года от EXELAB - вот тут.
ТУТОРИАЛ ДЛЯ ЗАДАНИЯ NICO ДЛЯ EKOPARTY 2018 - ЧАСТЬ 1

Давайте отреверсим шаг за шагом задание NICO для EKOPARTY 2018. Это сервер скомпилированный 64-битным компилятором и работающий конечно на WINDOWS.

Для начала я посмотрю на него в WINDOWS 7. В любом случае, часть статического реверсинга будет похожей.

При запуске мы видим следующее.

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

Описание находится здесь.

https://labs.bluefrostsecurity.de/blog/2018/09/11/bfs-ekoparty-2018-exploitation-challenge/

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

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

В окне строк мы ищем TOTAL RESERVES и получаем два результата.

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

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

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

И нажав клавишу X мы можем увидеть ссылки.

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

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

Здесь мы видим цикл со счетчиком. Когда он достигает нуля, программа переходит к TOTAL RESERVES : U$0, а если он больше нуля, программа переходит налево, чтобы вывести сумму, иначе программа идет туда, где находится строка THE CAPITAL FLIGHT HAS STOPPED.

Здесь мы видим десятичное значение 50000, которым инициализируется переменная CONTADOR_GUITA.

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

Здесь программа копирует переменную CONTADOR_GUITA в другую переменную.

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

Я переименую её.

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

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

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

Есть две переменные 130 и 134, которые передаются в качестве аргумента, и третья переменная, которая передается через регистр R8, которая является указателем на строку, которую я создал для печати.

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

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

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

С переменной 134 происходит то же самое, поэтому мы переименуем сейчас их в CONST_0x10 и CONST_0x18.

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

В 64х битных приложениях, если мы хотим, чтобы имена аргументов распространялись в родительскую функцию, мы должны установить тип с помощью SET TYPE в адресе функции.

Делаем правый щелчок и выбираем SET TYPE или клавишу Y. Мы можем определить функцию как USERCALL, так как вызов FASTCALL позволяет нам только устанавливать регистры в качестве аргументов функции.

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

__INT64 __USERCALL A_IMPRIMIR@<RAX>(INT CONST_0X10@<ECX>, INT CONST_0X18@<EDX>, CHAR *DEST@<R8>);

Мы видим, что программа изменила функцию, которая была __FASTCALL на USERCALL. Тип возвращаемого значения, я оставляю равным __INT64. Я добавляю после нового имени A_IMPRIMIR @<EAX>, что является регистром, в которой будет возвращать возвращаемое значение. Оно должно быть равно @<RAX>, но я уже сделал это, и это не влияет на анализ, так как программа не возвращает полезные значения только для печати, а затем три аргумента:

INT CONST_0X10@<ECX>
INT CONST_0X18@<EDX>
CHAR *DEST@<R8>

Два целых числа и указатель на строку DEST.

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

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

Мы видим, что в некоторых вызовах функции A_IMPRIMIR программа добавляет к постоянным переменным 0x10 и 0x18 значения перед вызовом, как в случае зеленого блока, который увеличивает регистр ECX и вычитает 4 из регистра EAX перед вызовом. Также, пока не станет ясно, что это значение мы не будем его переименовывать.

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

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

Программа сохраняет в стеке значения аргументов через регистры ECX, EDX и R8 в пространство, зарезервированное для родительской функцией, поверх ее локальных переменных. Я резервирую еще 4 QWORDS для передачи аргументов, и, поскольку они находятся ниже адреса возврата, они ведут себя как если аргументы были бы переданы через стек.

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

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

Если мы добавим опцию указателя стека.

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

Мы видим, что стек не изменяется. Нет ни PUSHа ни POPа, и вход и выход из функции не были изменены.

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

Мы видим, что это функции, относящиеся к RSP, не сохраняется регистр RBP в любое время, и все отсчитывается относительно RSP + XXX вместо RBP + XXX.

Мы видим, что щелкнув правой кнопкой мыши по одному из этих трех аргументов, который расположен ниже адреса возврата, мы подтверждаем, что это RSP+18h. (они находятся ниже адреса возврата).

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

Таким образом, отсюда это похоже на известную функцию. Аргументы ниже R и переменные выше. Регистр RBP не сохраняется, потому что это всё относительно RSP.

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

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

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

Структура имеет тип COORD, а переменная этого типа называется DWWRITECOORD.

В статическом представлении стека.
IDA Pro взлом и реверсинг программ

Мы можем дважды щелкнуть на COORD. Это приведет нас к определению.

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

Размер структуры равен 4 байта, и у неё есть два поля: WORD X и Y.

И в LOCAL TYPES также есть определение.

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

Т.е. теперь мы можем правильно переименовать аргументы.

Теперь смотрится красивее.

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

Мы знаем, что это не будет важной частью упражнения, но мы собираемся сделать всё это подробно.

Затем передаётся указатель на строку в функцию STRLEN, чтобы найти ее длину и сохранить ее в NLENGTH.

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

Затем вызывается функция GETSTDHANDLE, чтобы получить дескриптор стандартного устройства, которое может быть одним из трех в списке. (-10, -11 или -12 в зависимости от того, является ли оно вводом, выводом или ошибкой)

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

Также в IDA при правом щелчке и выборе пункта - USE STANDARD SYMBOLIC CONSTANT показывает в возможном списке значения, поэтому мы выбрали его оттуда.

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

В регистре RAX программа возвращает дескриптор HCONSOLEOUTPUT.

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

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

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

Как мы уже видели, первый аргумент передается через регистр RCX и является дескриптором HCONSOLEOUTPUT.

Второй находится в регистре RDX и является указателем на буфер для печати.

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

Третий через регистр R8D - это количество символов для печати NLENGTH.

Четвертый аргумент это структура COORD. Здесь программа показывает, что это поле X, но поскольку оно является первым полем, оно совпадает с началом того же поля, и при чтении DWORD читает 4 байта одного и того же поля, т.е. оба поля.

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

После выхода программа восстанавливает стек, который создала инструкция SUB RSP, 0x48 в начале. Теперь программа возвращает его в ноль с помощью инструкции ADD RSP, 0x48.

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

Хорошо. Эта функция уже завершена. Мы видим, что то, что вы добавляете в некоторых вызовах переменных X и Y начальных значений 0x10 и 0x18, - это запись в другую позицию.

Возвращаясь к основной функции, мы видим, что есть глобальная переменная, которая, если мы наведем курсор мыши, мы увидим, что она инициализирована 1. Если бы она была равна нулю, программа перенесла бы нас в зеленые блоки, где она не уменьшит значение счетчика, и выведет THE CAPITAL FLIGHT HAS STOPPED.

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

Существует значение 1, которое изначально имеет глобальная переменную.

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

Мы переименуем переменную в FLAG_FUGA, потому что, если она равна 1 т.е. если она истинна, то запасы уменьшаются, а если она равна нулю, то запасы восстанавливаются.

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

Мы также видим, что, если мы нажимаем X в указанной глобальной переменной, нет никакой ссылки на LEGAL, где она должна быть установлена в ноль. Проблема состоит в том, чтобы увидеть, как это сделать.

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

Здесь мы видим, что переменная находится в секции данных, что делает её доступным для записи, и мы увидим, как это сделать.

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

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

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

Также, если мы нажимаем X на имени, чтобы увидеть ссылки.

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

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

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

Затем есть переменная, которая, сохраняется здесь. Я называю ее CONST_1, также переименуем CONST_0x10 и 0x18 в имя COORD_X и Y.

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

Мы видим, что эта переменная CONST_1 lo que hace es que una vez que ya se detuvo запасы уменьшаются так как это цикл, который будет продолжать исполняться, измениться на нуль и не будет бесконечно повторять печать THE CAPITAL FLIGTH HAS STOPPED.

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

Таким образом, мы можем изменить имя на FLAG_IMPRIMIR_STOP.

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

Мы помним что в IDA есть префиксы.

https://www.hex-rays.com/products/ida/support/idadoc/609.shtml


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

Эти префиксы, за которыми следуют подчеркивание (как OFF_) и затем адрес, эквивалентны скобкам [], а OFF указывает мне тип значения который находится в скобках.

Это было бы эквивалентно.

MOV RCX, [0x14000D088]

За исключением того, что программа добавляет, что содержимым является смещение.

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

Таким образом, вы должны увидеть содержимое, которое будет помещено в регистр RCX.

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

Здесь мы это видим. По адресу 0x14000D088 добавляется префикс OFF_, поскольку его содержимое является смещением или указателем. В этом случае его значение равно 0x14000D000, содержимое которого является строкой ASC, поэтому этот адрес имеет префикс ASC_ впереди.

Т.е., проще говоря, у нас есть строка, и этот другой адрес хранит смещение или её адрес.

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

Теперь смотрится лучше. Переименуйте глобальную переменную в строку со звездочками как STRING_EN_DATA, а другая сохраняет ее смещение или адрес.

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

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

Регистр RCX был адресом STRING_EN_DATA.

Другие три аргумента являются константами.

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

Я изменил эти имена.

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

С этим я могу продолжить реверсинг, но если я захочу распространить переменные.
__INT64 __USERCALL SUB_140001580@<RAX>(CHAR *STRING_EN_DATA@<RCX>, INT CONST_0XA@<EDX>, INT CONST_0X18@<R8D>, INT CONST_0X90@<R9D>);

И у меня получается ссылка.

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

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

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

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

И также есть локальная переменная COOKIE.

Перед входом в цикл скопируется адрес строки STRING_EN_DATA в другую переменную и инициализируется счетчик в ноль.

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

Затем программа вызывает функцию STRCHR. Она ищет байт 0xA. Функция возвращает указатель на первое вхождение этого символа в строке или ноль, если она не находит его.

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

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

Мы видим, что строка имеет несколько символов 0xA, другими словами это строка с несколькими строками.

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

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

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

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

Тем не менее, STRING_EN_DATA_2 в начале аналогична STRING_EN_DATA, но есть доступ на запись к указанной переменной, поэтому она изменит свое значение.

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

Мы видим, что перед выходом повторяется цикл.

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

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

Поэтому я переименую его в P_LINEA_STRING_EN_DATA, а другой изменю на P_SIGUIENTE_0XA, поскольку он всегда будет указывать на 0xA, как это выглядит в STRCHR.

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

Итак, мы видим, что цикл будет повторять строку за строкой, а поскольку P_LINEA_STRING_EN_DATA всегда указывает на следующую строку, когда строки заканчиваются и больше нет 0xA в строке программа выходит из цикла. Теперь давайте посмотрим, что программа делает в цикле.

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

Мы видим, что есть вызов функции STRNCPY. COUNT или количество копируемых байтов происходит из вычитания двух адресов. Из P_LINEA_STRING_EN_DATA и из следующего адреса 0xA. Т.е программа скопировала строку. Поскольку источник - это то же самое P_LINEA_STRING_EN_DATA и назначение это DEST, который является буфером назначения.

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

Если мы сделаем правой кнопкой мыши и выберем - ARRAY в DEST в представлении стека.

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

Здесь мы видим целевой буфер длиной 256 байт.

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

Снова пересчитывается размер строки, вычитая адрес 0xA из следующей строки от её начала и перемещая результат в регистр R9D.

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

Мы видим, что счетчик увеличивается при каждом цикле.

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

Но также счетчик добавляется к тому, что он читает из переменной CONST_0xA, а затем передает это значение в качестве второго аргумента, поэтому в регистре EDX будет CONST_0XA_MAS_COUNTER.

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

Здесь есть 4 аргумента внутри функции.

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

Если я хочу распространить переменные с помощью с SET TYPE.
__INT64 __USERCALL SUB_140001580@<RAX>(CHAR * P_DEST@<RCX>, INT CONST_0XA_MAS_CONTADOR@<EDX>, INT CONST_0X18@<R8D>, INT NLENGHT@<R9D>);

И у меня получается ссылка.

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

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

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

Этот блок увеличивает счетчик на один внутри цикла.

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

И поскольку переменная считается от нуля и увеличивается на один каждый раз, выходной результат равен NLENGHT, т. е. длине строки. (JNB, если результат не ниже, т.е. если он равен или больше)

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

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

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

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

В HEX_DUMP я вижу строку. Это 0x20 (пробелы) и 0X2A (звездочки)

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

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

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

Мы помним, что когда ищем 0xA и сохраняем указатель INC EAX, чтобы пропустить 0xA, поэтому, если символ не является пробелом, он будет звездочкой, поскольку 0xA от начала пропускается путем увеличения указателя.

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

Таким образом, мы можем думать, что если это не пробел, то это звездочка.

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

Осталось также увидеть, что такое ARG_20, поскольку существует только 4 аргумента, а у дочерней функции только 5, 5тый - это ARG_20.

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

Напомним, что в этом компиляторе, родительская функция исполняет SUB RSP, 168 чтобы освободить место для собственных переменных, а также освободить место для аргументов, которым необходимо передать регистры в дочернюю функцию (4QWORDS),

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

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

На следующем рисунке я определил больше пространства, чем создала отцовская функция при выполнении SUB RSP, XXX, поверх той, которая ему нужна для локальных переменных, например, 4 QWORDS (VAR_168, VAR_160, VAR_158 и VAR_150)

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

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

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

Мы также видим, что существует массив слов с именем ATTRIBUTE. Я преобразую его в массив длиной 0x256 слов.

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

Мы также видим, что когда это пробел, программа записывает ноль в массив ATTRIBUTE, а когда это звездочка, программа записывает 0x90.

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

Другими словами для каждой строки запишется слово 0x00 в пробелах и слово 0x90, где были звездочки.

Мы видим, что программа собирается снова записать в консоль. Программа возвращается, чтобы найти дескриптор OUTPUT. Она передает координаты X и Y и в виде строки для печати передает указатель на ATTRIBUTE,

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

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

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

И создают цветную строку.

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

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

Так что я могу переименовать функцию в DIBUJAR_STRING.

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

Хотя я могу уточнить, что в этом вызове подтягивается BCRA.

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

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

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

А чуть ниже на красный.

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

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

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

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

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

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

Хорошо, 0x90 как мы писали в начало, это сумма этих двух констант

#define BACKGROUND_BLUE 0x0010
#define BACKGROUND_INTENSITY 0x0080

Вот почему это дает синий цвет.

Чтобы получить желтый цвет, нужно сочетание красного и зеленого.

#define BACKGROUND_GREEN 0x0020
#define BACKGROUND_RED 0x0040
#define BACKGROUND_INTENSITY 0x0080

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

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

Здесь мы видим, что программа вызывает все те же аргументы, кроме 0xE0 от Ox90, чтобы изменить цвет на желтый.

И красный цвет получается так

#define BACKGROUND_RED 0x0040
#define BACKGROUND_INTENSITY 0x0080

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

Помните, что CONTADOR_GUITA и CONTADOR_GUITA_2 равны в начале цикла

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

Далее вызывается GETTICKCOUNT.

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

Но мы можем считать, что программа возвращает значение, которое является случайным и увеличивается, и это значение делится на константу 0x7D0.

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

И результат сохраняется в EAX, остаток - в EDX.

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

Поэтому COUNTER_GUITA на этом этапе будет меньше, чем CONTADOR_GUITA₂.

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

И когда COUNTER_GUITA будет меньше 30000, а COUNTER_GUITA_2 будет больше, программа изменит вывод на желтый, то же самое произойдет, когда COUNTER_GUITA будет меньше 10000, а COUNTER_GUITA_2 больше 10000.

До тех пор пока COUNTER_GUITA не станет равным нулю, и программа перейдет к красному блоку, который завершает программу.

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


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

Хорошо. Давайте начнем анализировать главную функцию, где создан поток, который мы видели ранее.

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

Здесь мы видим, что с помощью SUB RSP, RAX, резервируются 0x1088 байтов пространства в стеке для локальных переменных, буферов и т.д. Мы также переименовываем переменную, в которой хранится COOKIE.

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

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

Первое, что делаете программа в первом вызове, это вызывает функцию WSASTARTUP.

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


IDA показывает нам аргументы. Первый из которых передается в ECX, и это версия. Здесь он устанавливается в 0x202 и сохраняется в указанной переменной WVERSIONREQUESTED, затем ECX читается как первый аргумент.

Второй аргумент, который передается через EDX, является структурой типа WSADATA.

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

Если мы перейдем на вкладку структуры, мы увидим это

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

Также в LOCAL TYPES.

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

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

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

Переменная равна 1, если поле WVERSION, которое было заполнено при вызове WSASTARTUP, равна переменной WVERSIONREQUESTED, которую мы передали ему в качестве аргумента.

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

Я переименовал функцию в нечто более близкое к тому, что она делает

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

Если переменная равно 1, все в порядке, и программа продолжается здесь

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

Первый аргумент в RCX - это адрес строки "0.0.0.0"

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

Это произойдет на моей машине по адресу 0X13F7ED238. Не путайте с именем A0000.

IDA всегда помещает строки в имя, которое начинается с A, а затем имеет некоторое описание строки, например, означающее, что оно указывает “A 0 0 0 0

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

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

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

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

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

Я делаю двойной щелчок здесь.

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

Отлично, продолжаем.

EDX будет иметь значение 41414, которое будет портом, в котором программа будет прослушиваться.

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

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

NETSTAT -ano в консоли с правами администратора покажет нам процессы и порты. В этом случае вы видите 41414.

И третий аргумент в R8 это указатель на QWORD с именем S

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

Мы видим другую переменную, которая сохранит флаг, если программа может выполнить успешное прослушивание. Поэтому мы переменовываем переменную в FLAG_LISTEN

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

Затем вызовите HTONS, чтобы перевести значение порта в BIG_ENDIAN (darlo vuelta en criollo)

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

Существует также переменная имени типа SOCKADDR.

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

В структурах.

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

И в LOCAL TYPES.

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

Затем вызывается сокет.

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

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

Мы видим, что в поле SA_FAMILY сохраняется 2, и затем три аргумента для сокета передаются непосредственно как константы, а в AF, что является семейством адресов, программа передает 2 напрямую. (IPV4)

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

Тип это 1 (SOCK_STREAM) что соответствует TCP.

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

И протокол будет нулевым (НЕ ОПРЕДЕЛЕН)

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

И возвращаемое значение будет дескриптором сокета. (То, что мы обычно называем дескриптором сокета)

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

Затем вызывается BIND с тремя аргументами: длина имени структуры SOCKADDR, затем указатель на то же имя структуры и сокет S.

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

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

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

Если программа получит ноль, она вызовет LISTEN.

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

Здесь мы видим информацию, что один из аргументов - это сокет, а другой - число, называемое BACKLOG, которое в нашем случае будет равно нулю.

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

Здесь есть нулевое значение, что делает

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

Также, если все правильно, программа возвратит нуль.

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

Сокет, который был в локальной переменной S, сохранит его в содержимом P_S для использования в родительских функциях

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

Я дал имя функции.

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

Если возвращается 1, программа продолжает выполнение здесь.

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

Первый вызов - эта функция без аргументов.

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

Посмотрим что делает эта функция.

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

Мы видим, что она не имеет аргументов, непосредственно резервирует пространство для переменных с помощью Sub RSP, 0x168.

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

Мы видим вызов MEMSET с аргументом 0x20. Другими словами должен заполниться буфер, длина которого в аргументе SIZE равна 0x100. Также в IDA, если я перехожу к статическому представлению стека, я могу сделать это, дважды щелкнув по CHARACTER или любой переменной.

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

Я вижу пустое пространство в буфере. Если щелкнуть правой кнопкой мыши и выбрать ARRAY мне говорится, что длина равна 256.

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

Здесь существует буфер с именем CHARACTER размером 256 байт или 0x100H.

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

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

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

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

Ещё раз получается хэндл вывода и вызывается WRITECONSOLEOUTPUTCHARACTERA,

Если я запускаю программа, в этом я не вижу записи буфера со значением 0x2020 в каждом слове, так как буфер инициализируется пробелами 0x20. Это просто нужно для рисования в консоли, Здесь нет ничего интересного нет. Продолжаем.

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

Затем устанавливается позиция курсора, обнуляя поля X и Y, передавая их как DWORD, поскольку они являются последовательными, и каждое из них является словом.

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

Затем создаётся поток, который мы уже проанализировали с помощью CREATETHREAD, передав его в качестве начального адреса STARTADDRESS. Эта функция уже проанализирована.

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

После запуска потока, программа напечатает TCP SERVER ACTIVATED.

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

Y ya empezaría la parte interesante, normalmente uno en un server buscaría el recv y empezaría a reversear desde allí, pero acá la idea es aprender y ser detallado para practicar, así que seguimos.

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

Перемещается курсор, так как Y теперь равен 1.

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

Происходит вывод “WAITING FOR CLIENT CONNECTIONS” и вызывается функция ACCEPT.

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

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

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

Здесь находятся 3 аргумента: указатель на ADDRLEN, в данном случае 0x10, указатель на ADDR, который получает адрес того, что подключается, и последний - сокет S. В регистре RAX возвращается дескриптор этого соединения, который был установлен.

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

Мы видим, что если я запущу сервер и установлю BP при возврате ACCEPT, то IDA не остановится, если я не отправлю правильный пакет на правильный порт, как в этом случае. Здесь отправил пакет и отладчик остановился.

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

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

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

Мы это уже проходили, я не собираюсь анализировать это снова.

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

Здесь печатается NEW CONECTION ACCEPTED и идет переход в функцию в RECV, где начинается то что нужно, поскольку, когда она получает данные, которые я могу отправить ей, если в программе есть какая-либо уязвимость, она может на нее повлиять.

Мы видим, что длина того, что вы можете получить, будет максимум 0x1000, флаги будут равны нулю, то, что я отправлю в буфере BUF, будет сохранено, и первым аргументом в RCX будет HANDLE_CONNECTION.

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

Если все прошло хорошо, возвращаемым значением будет количество полученных байтов.

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

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

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

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

Так что все в порядке, буфер не переполнится.

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

Мы видим, что переменная ADDRLEN, которая в ACCEPT использовала ее для длины ADDR, теперь повторно использует ее для получения количества полученных байтов.

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

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

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

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

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

Она имеет два аргумента. Первый в ECX - количество полученных байтов, а второй в RDX - указатель на буфер, в котором я храню данные, которые отправляю.

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

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

Если бы я хотел распространить с SET TYPE, то делаю так.

__INT64 __USERCALL FUNCION_2@<RAX>(INT CANTIDAD_BYTES_RECIBIDOS@<RCX>, CHAR * P_BUF@<EDX>);

Здесь нужно распространить переменные.

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

Мы видим, что программа сравнивает с помощью STRNCMP первые 6 байтов данных, которые вы отправляете, со строкой "Hello".

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

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

Если функция возвращает ноль, то они равны, и флаг установлен в 1.

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

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

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

Хорошо, как мы видим, если мы передали “Hello” будет действительным рукопожатие.

Затем программе возвращает в SEND строку, которая начинается с “Hi и несколько пробелов” длиной 8, чтобы не путать с другим BUF, который находится в секции данных. Я собираюсь переименовать его, чтобы избежать проблем.

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

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

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

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

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

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

Мы видим, что у него есть единственный аргумент - HANDLE_CONNECTION.

После сохранения аргумента резервируется место для переменных

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

Тот, кто хочет распространять нужно написать так

__INT64 __USERCALL FUNCION_2@<RAX>(__INT64 HANDLE_CONEXION@<RCX>);

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

Затем вызывается другой RECV с тем же HANDLE_CONNECTION, но длиной 0x10. Давайте посмотрим буфер, в который поступают данные.

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

Поскольку размер буфера составляет 0x10 т.е. 16 байтов, он будет включать переменную BUF и три переменные 224, 220 и 21C.

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

Если я хочу, я могу создать структуру для этого буфера.

Здесь у меня есть 16 байтов длиной с 4 DWORDS, тогда я увижу, какое конкретное имя поставить каждому из них.

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

И переменную переименую в MY_BUF.

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

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

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

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

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

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

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

Мы видим, что этот буфер составляет 512 байт, и я мог бы отправить ему больше данных, так как размер RECV, который я обрабатываю через CAMPO_0. Проблема заключается в том, что вы перезаписываете COOKIE, и это приводит к закрытию программы, и в 64-битных файлах нет исключения в стеке, так что это пока не приведет к переполнению.

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

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

Также, я переименую переменную в BUF_512_TERCER_RECV.

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

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

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

Y bueno quedo largo pero yo me entiendo jeje, con las variables reusadas pasa esto.

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

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

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

Я переименую переменную.

Затем идет сравнение без знака, только если CAMPO_2 меньше или равно 0x200.

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

Я переименую её.

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

Кроме того, сообщения об ошибках дают мне представление об именах полей, CAMPO_3 будет смещением, а CAMPO_2 будет равно уровню.

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

Сейчас смотрится лучше.

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

Поле 1 является операцией сравнения с 0x11111111 или 0x22222222, и если , то программа идет на INVALID OPERATION, поэтому мы переименовываем его. Мы видим структуру второго пакета.

Мы видим структуру второго пакета.

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

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

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


В этом компиляторе резервируются 4 QWORDS над пространством переменных, так что дочерняя функция хранит аргументы, которые передаются через регистры.

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

Таким образом, поскольку дочерняя функция имеет 5 аргументов, 5-й будет VAR_248.

Я переименую переменную в CONST_0, так как программа пишет туда ноль.

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

Давайте сначала проанализируем операцию 0x22222222.

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

Другие 4 аргумента такие.

__INT64 __USERCALL OP_0X22222222@<RAX>(INT LEVEL_MENOR_O_IGUAL_QUE_0X200 @<ECX>, CHAR * P_BUF_512_TERCER_RECV@<RDX>, INT BYTES_RECIBIDOS_3ER_RECV@<R8D>, INT OFFSET_VALOR_NEGATIVO@<R9D>);

Здесь распространяются аргументы.

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

Дело в том, что это рекурсивная функция, одинаковая в каждом вызове.

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

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

Другими словами, функция будет продолжать повторяться только уменьшая уровень и больше ничего не будет делать.

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

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

Это всё будет повторяться, ничего не делая, пока уровень не уменьшится и не достигнет нуля.

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

В этом случае программа перейдёт к этому блоку, где вы перепишите с помощью OK на некоторую часть стека выше BUFFER_512_TERCER_RECV, так как указатель на него добавляет отрицательное смещение.

Мы видим, что OK - это строка из 2 байтов и конечного нуля.

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

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

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

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

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

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

Дело в том, что переменная CONST_0 всегда будет равна 0 и программа не будет переходить к функции STRNCAT, которая будет пропущена, до уровня 0X1FF, который был выполнен первым и который имеет переменную CONST_0, и которую мы перезаписали с помощью OK, поэтому существует только один раз перейти к функции STRNCAT.

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

Этот уровень будет 0x200, так как это максимальный уровень и он будет счетчиком STRNCAT, поэтому вы должны попытаться отправить максимально возможное значение, в данном случае 0x200, чтобы объединить много данных.

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

SOURCE - это указатель на пакет, отправленный RECV ему в третьем параметре, который будет скопирован после строки OK, поэтому я могу перейти к переменным в стеке, которые находятся ниже CONST_0, включая очень ценную переменную, такую как размер SEND.

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

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

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

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

Здесь я помещу такие аргументы и если я хочу распространять их, нужно ввести следующее

__INT64 __USERCALL OP_0X11111111@<RAX>(INT LEVEL_MENOR_O_IGUAL_QUE_0X200 @<ECX>, CHAR * P_BUF_512_TERCER_RECV@<RDX>, INT BYTES_RECIBIDOS_3ER_RECV@<R8D>, INT OFFSET_VALOR_NEGATIVO@<R9D>);

Здесь распространяются значения.

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

Мы видим, что так же, как в OP_0X22222222 программа будет повторять ту же функцию, только изменяя уровень, который уменьшается. В то время как он будет повторяться до 0x200 раз в зависимости от уровня, который мы установили, и по мере его снижения счетчик достигнет ноль. Когда он это сделает, программа перейдет к STRCPY.

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

Здесь программа достигает функции STRCPY с уровнем равным 0.

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

В этом случае программа не добавляет отрицательное смещение к DESTINO, поэтому программа будет писать только OK в начале третьего буфера пакета.

Также следует отметить, что строка OK не совпадает с функцией 0x22222222, она имеет длину пять символов и имеет три точки после “OK…”.

Здесь есть обе строки.

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

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

Затем, возвращаясь к адресу возврата при каждом повторения, программа переходит к функции STRNCAT.

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

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

DESTINATION будет буфером THIRD_RECV, где в начале будет “OK…” куда я копирую в функцию strcpy, но после того, как эта строка заканчивается, это будет зависеть от того, что мы указываем в SOURCE, который будет тем же указателем плюс отрицательное смещение. Другими словами, мы можем добавить данные из верхней части буфера и вставить их в конце.

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

Также может случиться утечка, так как строка, которая будет в DEST в буфере, будет маленькой (для строки "OK ...", которую я копирую, будет только 5 байтов, и она заканчивается нулем, что сделает ее зависимой от того, что находится над буфером, например, адрес возврата повторений, хотя не COOKIE, он не будет выше буфера.

Мы также помним, что в случае функции OP_0X22222222 программа только один раз прибыла бы в функцию STRNCAT. В случае OP_0X11111111 необходимо помнить, что когда она уменьшается и достигает уровня 0, программа идет в функцию STRCPY и оттуда, поскольку она не зависит ни от каких CONST_0 во всех выходах всех уровней программа переходит в функцию STRNCAT.

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

Кроме того, поскольку количество, которое копирует в COUNT, является значением текущего уровня, и оно будет уменьшено, скопировано на уровень 1 будет только 1 байт. Далее, когда программа выйдет из LEVEL2_COPIARA и так далее, до последнего уровня, который скопирует 0x1ff и затем уже перейдет к отцовской функции.

Очевидно, что скопируется это количество байтов если нет нулей, потому что копируются строки, если уровень равен 0x150, и есть ноль, копируюся только из SOURCE в ноль, а не в полный размер.

Хорошо. Таким образом, существует много возможностей. Мы можем сделать утечку данных на первом этапе и получить COOKIE и адреса исполняемых файлов, которые позволят нам переполнить во втором пакете и выполнить ROP и записать флаг, чтобы избежать утечки средств и запустить CALC.

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

Обсуждение статьи: Решение задания Nico для Ekoparty. IDA Pro «с нуля» ч.65 >>>


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



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