В данной статье разберемся с декомпиляцией MIPS бинарника в Ghidra и пореверсим программу, написанную на golang, в IDA.

Часть 1 — C, C++ и DotNet decompile.

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

  • PWN;
  • криптография (Crypto);
  • cетевые технологии (Network);
  • реверс (Reverse Engineering);
  • стеганография (Stegano);
  • поиск и эксплуатация WEB-уязвимостей.

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

Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

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

ELF MIPS




Скачиваем и проверяем файл.



Это 32-x битный исполняемый файл для процессоров архитектуры MIPS. Для решения этого задания будем использовать Ghidra. Открываем гидру, создаем новый проект и добавляем в наш исполняемый файл.



Теперь открываем исследуемый файл, и перемещаемся в окно Symbol Tree. В поиске набираем main, чтобы найти точку входа программы.



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



Давайте преобразуем код.



Видим, что в переменную local_54 считывается 64 байта, давайте переименнуем ее в input (hotkey L) и сделаем из нее char массив длинной 64 символа (hotkey Ctrl+L). Также можно переименовать переменную sVar1.





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



Анализируем код. Вводимая нами строка должна состоять из 19 символов. На какой позиции какой символ должен быть понятно из кода. При этом с 8-ой по 17-ю должен быть символ ‘i’. Восстанавливаем, сдаем пароль.

Golang basic




В данном задании нам предоставляют исполняемый файл написанный на языке Go. Можно даже выяснить какая версия. Я закидываю в IDA. Стоит сразу сказать, что основная функция не называется main, а называется main_main. Поэтому выполним поиск по функциям и перейдем на реальную основную.



Давайте разбирать код. Начнем с самого начала.



Присутствуют определения a, key, input. Левый блок отвечает за завершение функции main_main. Рассмотрим левый блок.



Функция fmt_Scanln предназначена для считывания строки из консоли. Также наблюдаем уже сохраненные в программе данные main_statictmp_2.



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



На начало этого среза будет указывать key.ptr. Глянем что идет дальше.



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



Вызывается функция bytes_Compare, которая взависимости от результата сравнения выводит одну из строк.





С выводом программы разобрались, теперь пойдем посмотрим на преодразования строк (по левой ветке).



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



Таким образом, в EDX помещается байт из статически заданной строки и ксорится с r10, где находится байт из среза. Далее счетчик r9 увеличивается. Два средних смежных блока скорее всего нужны для контроля длины среза.

Совместим все воедино: введенная строка ксорится со срезом и сравнивается со статически заданной строкой. Давайте проксорим, чтобы узнать верный пароль.



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

На этом пока все. Продолжение следует… Вы можете присоединиться к нам в Telegram. Там можете предлагать свои темы и участвовать в голосовании на выбор темы для следующих статей.