• Уменьшение отступа

    Обратная связь

    (info@ru-sfera.pw)

Информация Изучаем Гидру от АНБ. Небольшей манн от Хакера


virt

Просветленный
Просветленный
Регистрация
24.11.2016
Сообщения
706
Репутация
228
Приватная статья, наглый копипаст:

В марте 2019 года Агентство национальной безопасности США (NSA) опубликовало инструментарий для реверс-инжиниринга под названием Ghidra. Пару лет назад я уже это название из утечек на сайте WikiLeaks и был весьма заинтересован, чем же пользуются в NSA для реверса. Настала пора удовлетворить любопытство и посмотреть, хороша ли бесплатная «Гидра» в сравнении с зарекомендовавшими себя инструментами.

Проблема доверия

АНБ в рамках программы Technology Transfer Program уже открыло исходные коды 32 проектов ( можно посмотреть на GitHub). Конечно, не обходится без шуточек о том, что АНБ будет использовать эти средства для слежения за пользователями. С одной стороны, конечно, код продуктов открыт, а их пользователи достаточно хардкорны, чтобы не полениться провести аудит. С другой — первый же косяк нашелся сразу после релиза Ghidra.

Британский ИБ-эксперт и глава Hacker House Мэттью Хики (Matthew Hickey) заметил, что в отладочном режиме инструмент Ghidra открывает и слушает порт 18001. Это позволяет подключиться к Ghidra удаленно, через JDWP, — разумеется, с целью все той же отладки. Хики отмечает, что исправить проблему совсем несложно — достаточно поменять строку 150 в файле support/launch.sh со звездочки на 127.0.0.1.

Постепенно всплывают и другие баги. Например, была эксплуатировать XXE при условии, что пользователь Ghidra откроет специально сформированный проект. Так что будь начеку!

Скачать Ghidra можно с официального сайта , но есть небольшая проблема: сайт недоступен из российских сетей (и, по некоторым данным, из канадских). Но я думаю, что это не препятствие для читателей «Хакера». Можно воспользоваться любым VPN или на крайний случай Tor.


Архив Ghidra в распакованном виде

Итак, ты скачал архив ghidra_9.0_PUBLIC_20190228 и распаковал его. Давай немного пробежимся по основным папкам и посмотрим, что в них.

Настоятельно рекомендую заглянуть в папку docs — там много информации о самой Ghidra, о разработке плагинов для нее и обзор основных возможностей в виде слайдов и документов PDF. Вся информация, естественно, на английском.

Далее идут папки с лицензиями — в них ничего интересного. В папке server есть инструментарий для запуска сервера удаленной отладки. В папке support собраны вспомогательные инструменты, без которых программа работать не будет.

В папке Ghidra уже интереснее: в Processors можно ознакомиться со всеми поддерживаемыми архитектурами. Вот их полный список: 6502, 68000, 6805, 8051, 8085, AARCH64, ARM, Atmel, CR16, DATA, JVM, MIPS, PA-RISC, PIC, PowerPC, Sparc, TI_MSP430, Toy, x86, Z80.


Папки с инструкциями для разных архитектур

Настало время смотреть само приложение! Чтобы открыть Ghidra в Windows, запускаем ghidraRun.bat, в Linux — ghidraRun.sh. Проект написан в основном на Java, поэтому качай и ставь Java Runtime, если у тебя его нет.

Окно создания проекта

Первым делом нам предлагают создать проект, в который мы добавим нужные бинарные файлы для исследования. После этого становится активной иконка с зеленым драконом, которая и откроет для нас CodeBrowser — основную среду для работы.

Основное окно CodeBrowser

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

CodeBrowser

И вот мы оказываемся в заголовке нашего файла. Перед нами структура IMAGE_DOS_HEADER, а не точка входа. Интересно! Надо сказать, что все поля отображены корректно, да и выглядит все более-менее сносно и информативно.

При первом запуске приложения я столкнулся с немного неудобным отображением кода и других полей в различных окнах дизассемблера. Но все это можно настроить при помощи специальной кнопки Edit the listing fields в верхнем правом углу каждого окна.

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

Вкладка Functions

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

Начальный код дизассемблированной функции

Это самое начало функции с ее сигнатурой, передаваемые в нее значения и их типы, возвращаемое значение, конвенция вызова и сам дизассемблерный листинг. В самом верху есть кнопка Display Function Graph, я ее выделил на скриншоте. Жмем на нее.

Графическое представление кода в Ghidra

Графическое представление кода в IDA Pro

При наведении на кодовые блоки появляется забавная анимация (видна на скриншоте). Я специально сделал два скриншота одной и той же функции: один в представлении графа в Ghidra, другой — в IDA Pro. Не знаю, как тебе, но, на мой взгляд, информативнее граф в Ghidra. К тому же Ghidra помечает прямо в графе конструкции if… else. Я понимаю, что это все ребячество, но лично для меня графическое представление кода в Ghidra более информативно и удобно, нежели в IDA Pro. Кроме того, графическое представление весьма гибко настраивается.

Также у Ghidra широкие возможности поиска — чтобы увидеть все варианты, достаточно выбрать в меню фреймворка пункт Search и посмотреть выпадающий список. Например, вот так выглядит диалог поиска по строкам.

Окно поиска по строкам

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

В Ghidra есть встроенный шестнадцатеричный просмотрщик. Чтобы его увидеть, нужно открыть меню «Windows → Bytes».

Встроенный HEX-просмотрщик

Ghidra из коробки поддерживает патчинг ассемблерного кода. Чтобы воспользоваться этой функцией, нужно выделить строчку кода и нажать комбинацию Ctrl + Shift + G либо выбрать соответствующий пункт в контекстном меню. Есть интересная визуальная фишка — если выделить какой-нибудь код в окне декомпилятора, то такой же код автоматически выделяется в окне дизассемблерного листинга.

Выделение кода в Ghidra

Еще одна интересная фишка Ghidra — это Script Manager, набор скриптов на все случаи жизни, поставляющийся из коробки. Если какого-то скрипта не хватает, разумеется, его можно добавить. Все скрипты написаны на Java. Чтобы ты понимал, о чем идет речь, прилагаю полный листинг скрипта CreateExportFileForDll.java. Что он делает, думаю, понятно из названия!

Код:
import generic.jar.ResourceFile;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.opinion.LibraryLookupTable;

public class CreateExportFileForDLL extends GhidraScript {
  @Override
  public void run() throws Exception {
    // Push this .dll into the location of the system .exports files.
    // Must have write permissions.
    ResourceFile file = LibraryLookupTable.createFile(currentProgram, false, true, monitor);

    println("Created .exports file : " + file.getAbsolutePath());
  }
}

Это листинг Ghidra:

Код:
undefined8 FUN_1400010b0(void)
{
ushort uVar1;
longlong *plVar2;
LPCSTR lpMultiByteStr;
ushort *puVar3;
longlong *plVar4;
longlong in_GS_OFFSET;
ushort local_d8 [104];

plVar2 = *(longlong **)(*(longlong *)(*(longlong *)(in_GS_OFFSET + 0x60) + 0x18) + 0x18);
lpMultiByteStr = FUN_140001448(&DAT_140003000);
MultiByteToWideChar(0,1,lpMultiByteStr,-1,(LPWSTR)local_d8,100);
plVar4 = plVar2;
do {
plVar4 = (longlong *)*plVar4;
if (plVar4[6] != 0) {
  puVar3 = local_d8;
  while( true ) {
    uVar1 = *(ushort *)((plVar4[0xc] - (longlong)local_d8) + (longlong)puVar3);
    if ((uVar1 == 0) && (*puVar3 == 0)) goto LAB_140001140;
    if ((uVar1 < *puVar3) || (uVar1 >= *puVar3 && uVar1 != *puVar3)) break;
    puVar3 = puVar3 + 1;
  }
}
} while (plVar2 != plVar4);
LAB_140001140:
return plVar4[6];
}

А это листинг IDA Pro Hex-Rays:
Код:
__int64 sub_1400010B0()
{
unsigned __int64 v0; // rax
_QWORD *v1; // rdi
_QWORD *v2; // rbx
const CHAR *v3; // rax
WCHAR *i; // rax
WCHAR v5; // cx
WCHAR WideCharStr; // [rsp+30h] [rbp-D8h]

v0 = __readgsqword(0x60u);
v1 = *(_QWORD **)(*(_QWORD *)(v0 + 24) + 24i64);
v2 = *(_QWORD **)(*(_QWORD *)(v0 + 24) + 24i64);
v3 = (const CHAR *)sub_140001448(&unk_140003000);
MultiByteToWideChar(0, 1u, v3, -1, &WideCharStr, 100);
while ( 1 )
{
v2 = (_QWORD *)*v2;
if ( v2[6] )
  break;
LABEL_9:
if ( v1 == v2 )
  return v2[6];
}
for ( i = &WideCharStr; ; ++i )
{
v5 = *(WCHAR *)((char *)i + v2[12] - (_QWORD)&WideCharStr);
if ( !v5 && !*i )
  break;
if ( v5 < *i || v5 > *i )
  goto LABEL_9;
}
return v2[6];
}

Как по мне, так листинг Ghidra читается попроще. Да, я знаю, что вывод Hex-Rays гибко настраивается. Помимо этого, есть плагин HexRaysPyTools, который помогает еще улучшить результат. Но мы-то прежде всего говорим о том, что идет в комплекте, а Hex-Rays еще и стоит отдельных денег.

Так или иначе, модуль декомпиляции в Ghidra могучий и вполне может составить конкуренцию Hex-Rays. А если зайти в папку \Ghidra\Processors, затем выбрать любую архитектуру и далее зайти в \data\languages, можно увидеть файлы с расширениями *.slaspec и *.pspec и еще некоторые. Глядя на них, понимаешь, что написать поддержку своей архитектуры — вполне реальная задача. Да, все-таки открытости кода сильно не хватает IDA Pro!

Заключение

Итак, мы рассмотрели фреймворк для реверс-инжиниринга Ghidra. Сможет ли он заменить IDA Pro? Я думаю, что на данном этапе своего существования — нет. Дело в том, что Java в качестве языка для написания подобных программ, на мой взгляд, не лучший выбор. И дело, конечно, в скорости.

Дизассемблер работает небыстро, особенно на тяжелых файлах. Скажу больше: файлы размером свыше 150 Мбайт реверсить на Ghidra — то еще испытание. С другой стороны, Ghidra кросс-платформенна, и для кого-то это может быть важно.

Следующий момент — это количество поддерживаемых архитектур и загрузчиков файлов: у IDA Pro их значительно больше. Еще очень не хватает такой же плотной интеграции с отладчиками, как в IDA Pro. Опять же, открытость кодов (если NSA выполнит обещание) — это хорошо, да и возможность добавлять поддержку других архитектур — по-настоящему крутая фишка. Но пока будет выполнена эта работа (и исправлены баги), пройдут годы.

Вообще, у меня сложилось стойкое впечатление, что Ghidra — это не конечный продукт. В том виде, в котором этот фреймворк доступен сейчас, он тянет на бета-версию с публичным доступом, но никак не на версию под номером девять. Кстати, в названии архива есть слово PUBLIC. Наверняка где-то есть еще и версия PRIVATE.

Безусловно, у Ghidra есть свои сильные стороны, и в чем-то она уже превосходит IDA Pro, но слабых мест пока что намного больше. А вот разработчикам IDA есть что позаимствовать в новом инструменте.

Например, мне понравилась повышенная информативность кода, представленного в виде графа. Да и само построение графа кода выглядит более строго и упорядоченно. Есть патчинг инструкций без дополнительных плагинов и без разделения на x64 и x86. Зачем держать два ярлыка на рабочем столе, если достаточно одного? В общем, Ильфаку еще есть куда двигаться!
 
Верх Низ