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

Дата публикации 4 янв 2018 | Редактировалось 5 янв 2018
Здесь мы нажимаем T, чтобы освежить информацию.

Наконец, я переименовываю функцию в ENTER.

1.png

Мы видим, что три первые функции вызывают ENTER передавая адрес PEPE и три следующие передают адрес JUAN.

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

2.png

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

3.png

Здесь на переменной _STRUCT я делаю правый щелчок и выбираю пункт CONVERT TO STRUCT *.

4.png

Сейчас, это адрес структуры MYSTRUCT и, как и раньше, мы увидим поля только нажав клавишу T в соответствующем месте.

5.png

Здесь мы видим, что программа сравнивает поле NUMERO, которое мы передали, с числом 0x10 и поскольку сравнение знаковое, любое отрицательное число может пройти. Например число 0xFFFFFFFF, которое равно -1 и которое меньше 0x10.

6.png

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

Я иду в MYSTRUCT и по смещению 0x0 нажимаю D один раз, чтобы создать единственное байтовое поле.

7.png

Теперь, здесь, я делаю правый щелчок и выбираю ARRAY.

8.png

Размер буфера будет равен 16 байт. Я соглашаюсь с этим значением.

Переименовываю это поле в BUFFER.

9.png

Размер поля теперь равен 16 десятичных байт.

Давайте продолжим реверсить.

10.png

Проблема состоит в том, что с помощью функции GETS_S буфер может быть переполнен, так как функция CHECK позволяет передавать отрицательные значении при использовании в качестве размера. Они будут восприниматься как беззнаковые значения и будут очень большими.

Если, например, мы передадим 0xFFFFFFFF в сравнение, значение будет равно -1, потому что оно идет как знаковое и будет меньше чем 0x10, но используя его как размер, оно будет большим положительным значением 0xFFFFFFFF, которое позволяет нам передавать количество символом, которое мы хотим через функцию GET_S в буфер и переполнить его.

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

11.png

У меня есть третья функция. Аргумент тот же, поэтому я повторяю процедуру, нажимаю F5 и изменяю тип аргумента.

12.png

Я продолжаю реверсить.

13.png

Мы видим, что есть ещё одно поле, поскольку оно пытается сравнить значение [EAX+0x18], которое мы не определили, так как наше последнее поле структуры MYSTRUCT равно 0x14. Давайте добавим его.

14.png

Мы помещаем указатель на слове ENDS и нажимаем D до тех пор пока не создадим новое поле DD.

15.png

Я переименовываю это поле в COOKIE.

16.png

Я возвращаюсь в нашу функцию и нажимаю T для обновления информации.

17.png

Мы видим, что существует ещё другое поле. Это единственный байт.

18.png

Поэтому мы возвращаемся назад в структуру MYSTRUCT и на слове ENDS нажимаем D один раз и у нас появляется поле из одного байта.

19.png

Я переименовываю это поле во FLAG, чтобы он совпадал с исходным кодом.

Теперь возвращаемся в функцию.

20.png

Если переменная COOKIE равна 0x99989796, тогда программа будет устанавливать флаг структуры в 1.

21.png

Если для некоторых изменений, которые не распространялись хорошо, переменные функции MAIN сломаются, и мы не сделали снимок, как это случилось со мной, то делаем так.

22.png

Я иду в начало поломанной функции и нажимаю U.

24.png

Я соглашаюсь на вопрос программы «сломать» функцию.

25.png

Затем, там же, в начале функции, я нажимаю C.

26.png

И затем я делаю правый щелчок и выбираю пункт CREATE FUNCTION.

27.png

Теперь всё хорошо.

Посмотрим в статическое представление стека.

28.png

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

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

29.png

30.png

Мы видим, что со структурой JUAN программа будет делать то же самое что и с PEPE. Структуры будут передавать свои адреса функциям ENTER и CHECK. Но программа имеет ещё третью функцию. Давайте посмотрим, что она делает.

31.png

Нажимая T в полях, мы видим, что функция похожа на функцию “DESICION”, только константа с которой сравнивается поле COOKIE структуры JUAN отличается. В этом случае константа равна 0x33343536.

Другими словами, поле COOKIE структуры PEPE должно быть равно значению 0x99989796 и поле структуры JUAN должно быть равно 0x33343536. Только так флаги каждой структуры будут равны 1.

32.png

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

Это упражнение имеет много решений, потому что структура JUAN находится выше в стеке.

33.png

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

Чтобы перезаписать флаг, у меня есть 16 десятичных байт, плюс к этому значению 3 DWORD или это будет 12 байт.

Общая сумма байт будет равна: 16 + 12 = 28 байт.

34.png

Поэтому количество фруктов будет равно: FRUTA = 28*A+\x01

35.png

Конечно, для каждой из структур Вы должны передать -1 или отрицательное значение, которое пройдет проверку против числа 0x10, а затем должен следовать фруктовый-шеллкод )).

36.png

Если мы немного поотлаживаем, мы увидим значение -1, которое помещается в поле NUMERO структуры PEPE.

37.png

38.png

Программа проходит проверку и достигает функцию GETS_S. Здесь и читаются переданные фрукты.

39.png

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

40.png

Здесь я вижу наши ФРУКТЫ, которые я посылаю программе. Если я хочу сконвертировать эти данные в структуру, то я нажимаю ALT + Q.

41.png

И выбираю пункт MYSTRUCT.

42.png

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

43.png

Мы видим, что программа сравнивает COOKIE со значением 0x99989796 и поскольку это разные значения, программа не изменят флаг. Но флаг уже равен 1, поэтому это не так важно.

Тот же процесс будет повторяться и мы переходим в функцию DECISION2.

44.png

Я начинаю трассировать с помощью клавиши F7.

45.png

Регистр EAX имеет начало структуры JUAN. Давайте посмотрим на эту структуру в стеке.

46.png

Здесь, я также нажимаю сочетание ALT + Q, чтобы из байтов собрать структуру. Снова выбираем нашу структуру MYSTRUCT.

47.png

Так же как и раньше флаг будет равен 1. Сравнение с COOKIE не будет равно, но программа продолжит выполняться, потому что с флагом уже всё хорошо.

48.png

Поле PEPE.FLAG равно 1 и это хорошо, поэтому продолжаем трассировку.

49.png

Поле JUAN.FLAG также правильное, поэтому я достигаю хорошего сообщения.

50.png

Готово. Теперь пример решен. Мы победили.
Увидимся в 28 части.

=====================================================
Автор текста: Рикардо Нарваха - Ricardo Narvaja (@ricnar456)
Перевод на английский: IvinsonCLS (@IvinsonCLS)
Перевод на русский с испанского+английского: Яша_Добрый_Хакер(Ростовский фанат Нарвахи).
Перевод специально для форума системного и низкоуровневого программирования — WASM.IN
05.01.2018
Версия 1.0

5 1.421
yashechka

yashechka
Ростовский фанат Нарвахи
Команда форума

Регистрация:
2 янв 2012
Публикаций:
67

Комментарии


      1. yashechka 13 янв 2018
        Когда их нет - не зло.
      2. Fail 13 янв 2018
        Деньги - зло:)
        [​IMG]
      3. yashechka 13 янв 2018
        Донатов нет, даже после такой мощной главы :unsure::unsure::unsure::dntknw::dntknw::dntknw:
      4. yashechka 5 янв 2018
      5. yashechka 5 янв 2018
        Когда я увидел эти 40 страниц текста, я понял, что не смогу перевести нормально. Оказалось, что я ошибся)) Не смотря на то, что я не профессиональный переводчик, этот перевод получился самым лучшим, из тех что я делал, жаль что я не успел к Н.Г. Единственное, что осталось не так - это - Мы видим, мы видим, мы видим. Но я правда устал от этой главы. При втором проходе всё исправим.