24
Введение в реверсинг с нуля, используя IDA PRO. Часть 18. В предыдущей части, мы распаковали исполняемый файл упражнения и сделали его рабочим. В этой части, мы будем его реверсить, чтобы увидеть , мож но ли сделать для него кейген в P YTHON . Хорошо помнить, что для статического анализа нет необходимости распаковывать файл . Нам просто нужно получить OEP и сделать TAKE MEMORY SNAPSHOT . Затем, нужно с копир овать файл . IDB в другое место и откры ть его там . Э того бы хватило, чтобы анализировать его статически, но хорошо иметь распакованный файл , это позволи т отлаживать файл и может иногда помогать. Я открываю распакованный файл в IDA , и первое, на что я обращаю внимание - это строки. Хорошо, мы знаем, что первое, что делаем программа после запуска - это печатает строку “ Pone un user” . Поэтому, я делаю двойной щелчок на этой строке в IDA и попадаю сюда .

Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

  • Upload
    others

  • View
    62

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Введение в реверсинг с нуля,используя IDA PRO. Часть 18.

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

Хорошо помнить, что для статического анализа нет необходимости распаковывать файл. Нампросто нужно получить OEP и сделать TAKE MEMORY SNAPSHOT. Затем, нужно скопировать файл.IDB в другое место и открыть его там. Этого бы хватило, чтобы анализировать его статически, нохорошо иметь распакованный файл, это позволит отлаживать файл и может иногда помогать.

Я открываю распакованный файл в IDA, и первое, на что я обращаю внимание - это строки.

Хорошо, мы знаем, что первое, что делаем программа после запуска - это печатает строку “Poneun user”.

Поэтому, я делаю двойной щелчок на этой строке в IDA и попадаю сюда.

Page 2: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

И ищу перекрёстную ссылку с помощью клавиши X.

Видно, что ссылка нашлась. Теперь можно перейти по ней.

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

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

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

Хорошо, делая двойной щелчок на любой переменной или аргументе, ЗАГРУЗЧИК показываетстатическое представление стека.

Page 3: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

Это тот же самый случай, как и в прошлый раз. Это функция MAIN и она имеет такие аргументы:ARGV и ARGC и т.д. Но, так как она не использует их внутри функции, то IDA не учитывает этиаргументы.

Page 4: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Давайте переименуем эту функцию в MAIN, и IDA добавит мне автоматически три аргумента.

Также, если мы нажмём клавишу X на любом из трёх аргументов.

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

Возвращаясь к статическому представлению стека, видим, что ниже адреса возврата, как иположено, есть аргументы. Затем идёт буква S, что означает STORED EBP. Как мы сказали, этозначение хранит EBP предыдущей функции, которое помещается в стек с помощью инструкцииPUSH EBP и выше есть место для переменных, которое обычно имеет переменную VAR_4, котораянужна для защиты стека от переполнения буфера.

Page 5: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Эта переменная имеет две перекрёстные ссылки. Одну в начале функции, когда программасохраняет значение SECURITY COOKIE(Печеньки безопасности. Прим. Яши) в стек.

Вышеупомянутое значение - это случайное значение, которое XORится с помощью EBP исохраняется в переменную VAR_4 в начале функции. А другая ссылка находиться здесь.

Где программа восстанавливает исходное сохраненное значение и XORит его с помощью EBP длявосстановления исходного значение в ECX, и внутри этого CALL, программа проверяет этозначение.

Page 6: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Если всё нормально, программа будет возвращаться, но если ECX не имеет первоначальногозначения __SECURITY_COOKIE, программа перейдёт в JMP, который ведёт на ВЫХОД и непозволит Вам достигнуть RET функции.

Плохой вариант может случиться и программа пойдёт на ВЫХОД, если произойдётПЕРЕПОЛНЕНИЕ, которое перезаписывает значение VAR_4 внутри функции. Сейчас давайпереименуем VAR_4 в CANARY(КАНАРЕЙКА) или SECURITY COOKIE.

Сейчас, листинг выглядит более красиво и читаемо.

Затем, видим две переменные, о которых мы ещё ничего не знаем и о которых мы ещё неговорили, как они используются. Они инициализируются нулями. Также есть переменная, котораяуже имеет имя SIZE и инициализируется числом 8.

Page 7: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Если посмотрим перекрёстные ссылки для переменной VAR_7D, увидим, что она используетсяздесь.

Программа сохраняет значение AL в эту переменную при возврате из CALL и затем перемещаетэтот байт в регистр EDX, для того, чтобы проверить равен он нулю или нет, чтобы сделать вывод отом, хорошие мы реверсеры или плохие. Так что, это переменная одного байта или флаг.Следовательно, мы можем переименовать её в FLAG_EXITO.

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

Нужно поменять ей имя с помощью клавиши N.

Page 8: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

Очевидно, если бы нам нужно было просто пропатчить этот переход JZ, это было бы то место, гденужно было это сделать, но мы будем стараться решить этот крекми правильным способом.

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

Page 9: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Видно, что VAR_84 - это счетчик этого ЦИКЛА, который складывает значения. Но видно, что циклскладывает только первые четыре байта, потому что он выходит, когда это значение больше илиравно 4.

Здесь видно этот СЧЁТЧИК и как он увеличивается.

Page 10: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Очевидно, этот счётчик также присутствует по адресу 0x231109 для чтения буфера BUF с самогоначала и нужен для сложения его следующих байтов.

Хорошо, мы уже видели, что этот ЦИКЛ читает байты из буфера BUF, затем суммирует их исохраняет эту сумму в SUMATORIA. Теперь давайте посмотрим, что находится в BUF.

Page 11: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Видно, что размер BUF равен 8 байтами и это максимальная длина для имени пользователя.Функция GETS_S используется для получения данных с клавиатуры.

Нам нужно поменять функцию по адресу 0x002310A0 на PRINTF.

Готово.

Также, в статическом представлении стека мы видим длину буфера BUF с помощью правогощелчка и выбора пункта ARRAY.

Page 12: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Размер совпадает с исходным кодом.

Представление стек становится для нас более ясным.

Page 13: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

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

И если длина буфера меньше чем 4, программа идет на ВЫХОД.

Из всего этого, уже можно сделать вывод, что этот ЦИКЛ складывает первые четыре байтапользователя, которые мы ввели. Поэтому давайте перегруппируем блоки, для того чтобы они немешались и смотрелись лучше. Щелкаем в панели каждого блока зажав CTRL.

Page 14: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Сейчас выглядит намного лучше. С помощью правого щелчка GROUP NODES и выбора пунктаUNGROUP я могу разгруппировать блоки, если нам это понадобится.

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

Снова программа использует функцию STRLEN, чтобы узнать размер буфера и если он меньше чем4, программа отправляет нас на ВЫХОД.

Page 15: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

Затем, она берет пароль и конвертирует его в HEX значение с помощью функции ATOI. В PYTHONдля этой же цели можно использовать функцию HEX.

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

Page 16: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Мы видим, что программа будет сравнивать сумму первых 4 байт пользователя и HEX значениепароля обработанное операцией XOR с ключом 0x1234 в этой функции, которую мы назовёмCHEQUEO_EXITO. Результат функции определит переход программы в хорошее сообщение илиплохое.

Здесь, мы видим два аргумента. ARG_4 будет тем, который помещается первым.

Так что давайте переименуем внутри функции оба этих аргумента.

Пришло время правильно настроить аргументы для этой функции, для этого делаем правыйщелчок и выбираем SET TYPE.

Смотрим на результат после проделанной операции.

Page 17: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Смотрим, распространились ли теперь ссылки?

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

Я вижу, что перед сравнением значений, программа делает SHL EAX, 1 что равносильноумножению аргумента на 2.

Значит, если они равны, программа перейдёт в зеленый блок, где она поместит 1 в регистр AL, иона будет возвращать значение как флаг FLAG_EXITO, который должен определить, хорошие мыреверсеры или плохие.

Обобщим всё это.

Программа берет первые 4 байта имени ПОЛЬЗОВАТЕЛЯ и складывает их.

ПАРОЛЬ переводится в HEX и он XORится с помощью ключа 0x1234 и затем умножается на 2.

Page 18: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Теперь будем делать формулу, предполагая, что мы знаем имя ПОЛЬЗОВАТЕЛЯ, так как кейгеноснован на знании этого имени. С помощью определённого имени ПОЛЬЗОВАТЕЛЯ, кейген будетнаходить соответствующий пароль.

X = ПАРОЛЬ конвертируется в HEX

(X ^ 0x1234) * 2 = СУММА

Если поделим на 2

X ^ 0x1234= (СУММА/2), то получится так

X = (СУММА/2) ^ 0x1234

Функция XOR обратима и она работает с членами так:

A ^ B = C

A = B ^ C

Хорошо, значение X, которое нужно найти, рассчитывается по следующей формуле

X = (СУММА/2) ^ 0x1234

Если моё имя было бы например pepe, которое действительно, потому что оно меньше чем 8байт, сумма байтов рассчитывалась бы так.

Здесь, мы получили сумму для моего пользователя pepe.

Page 19: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

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

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

Page 20: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Видно, что используя RAW_INPUT(Считывает и возвращает строку входных данных. Прим. Яши)мы получаем всё, что мы печатаем через консоль.

Результат для pepe схожий. Сумма равна 0x1AA. Но я могу получить её и для любогопользователя, например fiaca.

Мы получаем такую формулу:

X = (СУММА/2) ^ 0x1234

Поэтому сумма должна делиться на 2 и XORиться с помощью ключа 0x1234, чтобы находитьпароль в HEX виде.

Page 21: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

Теперь у нас есть кейген. Сейчас, нам не нужно делать преобразование пароля из HEX вдесятичное значение, потому что PYTHON всегда печатает в десятичном формате по умолчанию.

Page 22: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

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

До 7 символов программа функционирует хорошо.

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

Page 23: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

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

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

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

До встрече в 19-той части.

Page 24: Введение в реверсинг с нуля, используя IDA PRO ...yasha.su/VVRSNIIP_18.pdfВведение в реверсинг с нуля, используя IDA

Автор текста: Рикардо Нарваха - Ricardo Narvaja (@ricnar456)

Перевод на английский: IvinsonCLS (@IvinsonCLS)

Перевод на русский с испанского+английского: Яша_Добрый_Хакер(Ростовский фанат Нарвахи).

Перевод специально для форума системного и низкоуровневого программирования — WASM.IN

15.10.2017

Версия 1.0

***Всем, кому интересна судьба этого и следующих проектов, прошу посетить ресурс yasha.su***

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