Pull to refresh
0
Digital Security
Безопасность как искусство

Точки соприкосновения JavaScript и Reverse Engineering

Reading time 8 min
Views 25K


Если вы посмотрите описания вакансий на позицию Reverse Engineer, то вряд ли встретите там требование знания JavaScript. А если и встретите, то только в контексте его деобфускации на разных вредоносных страницах, обычно используемых эксплойт-паками.
И возможно ли вообще сосуществование JS (который некоторые даже называют веб-ассемблером) и мира low level с Assembler во главе?

Если веб-порталами с:
– или фаззерами-браузерами (Surku, Nduja) на JS особо никого не удивить, то программируемые инструменты отладки и анализа бинарного кода – уже другое дело.
В данной статье хотелось бы представить действительно интересные и полезные проекты (сразу отмечу, что она не является призывом к изучению JS для задач reverse engineering).

Node Capstone


Совсем недавно на свет появился фреймворк для дизассемблирования – Capstone. Проект сразу получил поддержку сообщества и огромную популярность. Это и понятно: он прост в использовании и сразу поддерживает большое количество архитектур: ARM, ARM64 (ARMv8), MIPS, PowerPC, SPARC, ОС Windows и *nix (Mac OSX, iOS, Android, Linux, *BSD и Solaris). Со временем фреймворк обрастал биндингами к различным языкам, и уже есть: Python, Ruby, C#, Java, GO, C++, OCaml, Vala и NodeJS. Да, NodeJS!
Вот непосредственно сам биндинг: github.com/parasyte/node-capstone
А это пример кода, в котором происходит дизассемблирование 64-битного кода для x86-архитектуры и его последующий вывод в консоль:

var capstone = require("capstone");

var code = new Buffer([
    0x55, 0x48, 0x8b, 0x05, 0xb8, 0x13, 0x00, 0x00
]);

var cs = new capstone.Cs(capstone.ARCH_X86, capstone.MODE_64);

cs.detail = true;
cs.disasm(code, 0x1000).forEach(function (insn) {
    console.log(
        "0x%s:\t%s\t%s\t%s",
        insn.address.toString(16), insn.mnemonic, insn.op_str,
        JSON.stringify(insn.detail)
    );
});

cs.close();


pe.js


github.com/mihailik/pe.js



В процессе написания эксплойта для браузера для обхода ASLR часто используется утечка адреса, относительно которого потом строится ROP-цепочка. Если нужно вызвать какую-то конкретную функцию, но она в коде не встречается, делается другой маневр. Вычисляем начало нужной DLL и парсим ее. Для этого хорошо бы иметь код на JavaScript, который умеет разбирать PE-формат и таблицу импорта в частности. Вот для таких целей и пригодится pe.js.
Ну или в качестве инфектора ЕХЕ-файлов на чистом JavaScript. Вот такой пример: alive-green.blogspot.ru/2014/03/js-javascript.html

cycript


www.cycript.org

cycript – инструмент от хорошо известного Jay Freeman (saurik). Он позволяет в рантайме просматривать и модифицировать приложение на Mac OS X или iOS. Все это происходит при взаимодействии через консоль (запуск скриптов также присутствует) на гибридном языке с синтаксисом Objective-C++ и JavaScript.
Есть также возможность взаимодействовать с Substrate – это очень удобно при реализации перехвата функции, ее логировании, модифицировании параметров или результата. Часто применяется при изучении работы программы или ее фаззинге.

Вот пример работы с cycript на iOS, где идет подключение к приложению и просмотр значений в объекте определенного класса.



Или, наверное, самая популярная функция cycript – вывод всех имен функций определенного класса с адресом их реализации:

function printMethods(className) {
   var count = new new Type("I");
   var methods = class_copyMethodList(objc_getClass(className), count);
   var methodsArray = [];
   for(var i = 0; i < *count; i++) {
     var method = methods[i];
     methodsArray.push({selector:method_getName(method), implementation:method_getImplementation(method)});
   }
   free(methods);
   free(count);
   return methodsArray;
}

По использованию данной библиотеки можно найти много мануалов в Интернете и даже упоминаний использования на Хабре.
На данном инструменте, например, построен фреймворк под названием iNalyzer, который часто используется при blackbox-тестировании iOS-приложений.

Frida RE


www.frida.re



Frida позволяет инъектить JavaScript-код в приложения на платформах Windows, Linux, Mac, Android и iOS. Что касается архитектур, – естественно, x86/x64/ARM/AArch64. Инструмент позволяет выполнять собственные скрипты на JS внутри приложения: перехватывать функции, создавать вокруг них обертки, подменять входные/выходные параметры или просто вызывать определенную функцию из исследуемого приложения, и это далеко не все. Таким образом, один и тот же код может почти без изменений использоваться на всех перечисленных ОС. Что касается Android, для нее есть поддержка работы с VM Dalvik, и можно работать не только с native-функциями, но и с написанными на Java. То же самое можно сказать и про Objective-C-код для OS X и iOS.
Ядро Frida написано на С, и для своей работы оно инъектит в целевой процесс движок V8 от Google, который выполняет наш JS-код с полным доступом ко всей памяти процесса и организует двунаправленный канал взаимодействия с приложением.
В Frida есть такие классные функции, как send, resv, post_message, позволяющие общаться с нашим JS-кодом, который уже выполняется внутри целевого приложения, и тем самым интерактивно изменять поведение кода внутри. Например, мы написали JS-код, который ищет определенную строку в памяти, и проинжектили его в мобильное приложение. После мы можем сначала поискать, остался ли логин в памяти после авторизации, а затем и пароль или какую-либо другую строку, просто отсылая ее нашему JS-скрипту. Ну и, естественно, получать ответ, нашлась нужная строка или нет.

Вот так, например, выглядит код встроенной функции enumerate_modules(), отвечающей за перечисление загруженных в процесс библиотек, в python binding:



Или вот код для логирования работы функции с прототипом int func(int val, char* str):

script = process.session.create_script("""
Intercrptor.attach(ptr("%s"), {
    onEnter: function(args){
        send({info:'onEnter', val:args[0].toInt32(), str:Memory.readUtf8String(args[1])});
    },
    onLeave: function(retval){
        send({info:'onLeave', retval: retval.toInt32()});
    }
});
""" % addr

Фреймворк был впервые представлен на конференции Hackito Ergo Sum 2013 и сейчас хорошо поддерживается, обновляется. Уже есть поддержка iOS 8.1 и ARM64-архитектуры. И это, наверное, самый интересный проект в данном обзоре.

Pinocchio


github.com/pablosole/pet

Проект, который появился еще раньше, чем Frida, и реализовал идею инжекта движка V8 в исследуемую программу. Представлен на конференции EkoParty 2012, но, в отличие от Frida, так и не получил развития и поддержки от сообщества. Но я считаю, что о нем стоит упомянуть, так как исходный код опубликован и любой желающий может сам продолжить развитие проекта, если ему он понравится.
Pinocchio позволяет реализовать все возможности PIN на JavaScript и основывается на движке V8. О том, что такое DBI (Dynamic Binary Instrumentation) и фреймворк PIN, я уже писал. Сам PIN не стоит на месте и развивается. Что умеет Pinocchio, можно посмотреть здесь.

Пример кода для обработки событий при загрузке нового модуля и создании нового потока в программе:

function newimage(img) {
log(img.name + “ – “ + img.loadOffset.hex());
}

function newthread(threadId, ctx, flags) {
log(“New Thread “ + current.thread.tid);
 log(“Thread Stack:” + ctx.get(REG_ESP).hex());
}

events.attach(“loadimage”, newimage);
events.attach(“startthread”, newthread);

Данный инструмент сейчас поддерживает лишь Windows и IA32.
Более подробная презентация об инструменте (на испанском): www.ekoparty.org//archive/2012/Pin%20para%20Todos%20y%20Todas.pdf

IDA_JScript


github.com/dzzie/RE_Plugins/tree/master/IDA_JScript



Если речь идет о реверсинге, то куда же без IDA Pro. Скрипты для нее с той или иной степенью удобства можно писать на огромном количестве языков: C/C++, IDC, Python (IDAPython), Ruby (idarub), Perl, Java (idajava), Ocaml (idaocaml). Некоторые биндинги, конечно, далеко не в актуальном состоянии.
И JavaScript не исключение: IDA_JScript.
Я, конечно, сомневаюсь, что этим много кто активно пользуется, но сам факт наличия красноречив. Можно использовать, но и поддерживать/актуализировать тоже придется.

Вот так выглядит код для получения всех имен, заданных пользователем, в заданном диапазоне:

s = 0x09A47A8
e = 0x09A5ACE

if(s.length==0 || e.length == 0){
    throw "invalid inputs"
}

s = parseInt(s);
e = parseInt(e);

ret = '';
com = 'comments:\r\n';

while(s < e)
{
    n = ida.getname(s)
    c = ida.getcomment(s);
    
    if(n && n.length > 0){
        ret += "MakeName(0X" + h(s) + ",\"" + n + "\");\r\n"
    }
    
    if(c && c.length > 0){
        com += "0X" + h(s) + "\t= " + c + "\r\n";
    }
    
    s = ida.nextea(s);
    if(s==-1) break;
} 

ret = ret + "\r\n\r\n" + com 
t(ret)
fso.setclipboard(ret);
alert("Names and comments for range extracted");


bNarly


github.com/d0c-s4vage/bnarly



Для того чтобы понимать, что привело к падению браузера или как та или иная страница влияет на внутренние структуры браузера, нужно смотреть/следить, что вытворяет JavaScript. Такое по сей день по плечу только отладчику. И процесс в отладчике выглядит достаточно муторным и трудоемким.
У товарища с nickname d0c_s4vage появилась идея инструментировать работу в WinDbg через JS, то есть выполнять команды WinDbg из JS. В итоге он создал проект bNarly.
bNarly (browser Narly) – это инструмент для исследования и эксплуатации браузеров. bNarly является своеобразным мостом между отладчиком WinDbg и JavaScript.
Написан данный инструмент с использованием библиотеки jQuery.
Где может на практике пригодиться эта тулза? Первое, что приходит на ум: при анализе креша, эксплуатации use-after-free или корректировке heap-spray.

Основные функции:
  • Дамп памяти
  • Трассировка free/alloc
  • Выполнение JavaScript-кода
Из полезных вещей есть продуманная система вычленения кода, отвечающего за графический интерфейс.
Алгоритм работы:
  • Открываем браузер
  • Открываем WinDbg и аттачимся к нужной вкладке
  • Ставим брейкпоинт в WinDbg на нужную функцию
  • В окне bNarly пишем и исполняем нужный код
  • WinDbg за всем следит, и потом bNarly отображает свою информацию
На текущий момент поддерживает:
  • IE 8, 9, 10, 11
  • Firefox >= 20


SchemDBG


github.com/hexgolems/schem



В последнее время в мире reverse engineering идет активная работа в направлении визуализации исследуемых данных, отображения процесса выполнения программы, в общем, всего, что связанно с удобством восприятия при исследовании программы.
Одним из наиболее часто используемых инструментов при RE является отладчик. И то, как он отображает процесс работы программы, очень важно. Сейчас отладчиков предостаточно, все отличаются, в том числе и UI, настроить его не всегда возможно, а у кого-то он либо страдает, либо вообще отсутствует.
Проект SchemDBG старается полностью разнести отладчик и отображение так, чтобы было возможно подключить любой отладчик, просто поддержав несколько основных операций.
SchemDBG ставит перед собой задачу отображать/предоставлять как можно больше информации в любой точке отлаживаемой программы. На текущий момент в качестве бэкенда поддерживаются GDB и PIN. Каждый из них – для 32- и 64-битных бинарных файлов, запущенных на машине с Ubuntu в качестве хостовой машины.
Отладчики управляются с помощью обертки, написанной на Ruby, а веб-фронтенд написан на CoffeeScript. Фронтенд корректно работает под Chromium (поддержки других браузеров не планируется). При этом много клиентов могут присоединяться к одному контроллеру (отладчику), который предоставляет просмотр в нескольких экранах (можно с разной настройкой).
Проект разрабатывался в рамках Google Summer of Code 2013.

Tessel


tessel.io

Ну а для различных игр с железом со знанием JS отлично подойдет эта плата. Получается в итоге такая Arduino для JS-любителей))



Подробно данную железку уже рассматривали здесь.

Для меня использование веб-технологий для визуализации данных, полученных в процессе RE, сейчас видится наиболее перспективным и полезным. Так, во внутренних разработках был написан плагин для IDA Pro, который выполняет функции WebSocket-сервера и помогает взаимодействовать с браузером. А уже в браузере с помощью библиотеки D3.js происходит визуализация как статичной информации, так и полученной в процессе выполнения исследуемой программы. Естественно, взаимодействие между IDA Pro и браузером интерактивно. Подобное взаимодействие можно посмотреть в проекте QIRA от George Hotz.

Можно смело сказать, что расстояние между веб-технологиями и задачами RE постепенно сокращается…
Tags:
Hubs:
+36
Comments 4
Comments Comments 4

Articles

Information

Website
dsec.ru
Registered
Founded
Employees
51–100 employees
Location
Россия