- PVSM.RU - https://www.pvsm.ru -

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

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

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

Если веб-порталами с:

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

Node Capstone

Совсем недавно на свет появился фреймворк для дизассемблирования – Capstone [12]. Проект сразу получил поддержку сообщества и огромную популярность. Это и понятно: он прост в использовании и сразу поддерживает большое количество архитектур: 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 [13]
А это пример кода, в котором происходит дизассемблирование 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%st%st%s",
        insn.address.toString(16), insn.mnemonic, insn.op_str,
        JSON.stringify(insn.detail)
    );
});

cs.close();

pe.js

github.com/mihailik/pe.js [14]

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

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

cycript

www.cycript.org/ [16]

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

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

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

Или, наверное, самая популярная функция 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 [18], который часто используется при blackbox-тестировании iOS-приложений.

Frida RE

www.frida.re/ [19]

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

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:

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

Или вот код для логирования работы функции с прототипом 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 [20]

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

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

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 [23]

IDA_JScript

github.com/dzzie/RE_Plugins/tree/master/IDA_JScript [24]

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

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

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

s = 0x09A47A8
e = 0x09A5ACE

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

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

ret = '';
com = 'comments:rn';

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

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

bNarly

github.com/d0c-s4vage/bnarly [31]

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

Для того чтобы понимать, что привело к падению браузера или как та или иная страница влияет на внутренние структуры браузера, нужно смотреть/следить, что вытворяет JavaScript. Такое по сей день по плечу только отладчику. И процесс в отладчике выглядит достаточно муторным и трудоемким.
У товарища с nickname d0c_s4vage [32] появилась идея [33] инструментировать работу в 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 [34]

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

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

Tessel

tessel.io/ [35]

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

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

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

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

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

Автор: d1g1

Источник [39]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/86071

Ссылки в тексте:

[1] HEX-редакторами: http://hexed.it/

[2] ассемблерами: https://defuse.ca/online-x86-assembler.htm

[3] Cenigma: http://www.cenigma.org

[4] ODA: http://www.onlinedisassembler.com/odaweb/

[5] Radare2 Cloud: http://cloud.rada.re/enyo/

[6] Retargetable Decompiler: http://decompiler.fit.vutbr.cz/decompilation/

[7] эмуляторами: http://www.cambus.net/emulators-written-in-javascript/

[8] виртуализаторами: https://github.com/copy/v86

[9] и т. д.: https://github.com/espruino

[10] Surku: https://github.com/attekett/Surku

[11] Nduja: https://sites.google.com/site/tentacoloviola/fuzzing-with-dom-level-2-and-3

[12] Capstone: http://www.capstone-engine.org/

[13] github.com/parasyte/node-capstone: https://github.com/parasyte/node-capstone

[14] github.com/mihailik/pe.js: https://github.com/mihailik/pe.js

[15] alive-green.blogspot.ru/2014/03/js-javascript.html: http://alive-green.blogspot.ru/2014/03/js-javascript.html

[16] www.cycript.org/: http://www.cycript.org/

[17] Substrate: http://www.cydiasubstrate.com

[18] iNalyzer: https://appsec-labs.com/iNalyzer

[19] www.frida.re/: http://www.frida.re/

[20] github.com/pablosole/pet: https://github.com/pablosole/pet

[21] писал: http://habrahabr.ru/company/dsec/blog/142575/

[22] здесь: https://github.com/pablosole/pet/blob/master/API.txt

[23] www.ekoparty.org//archive/2012/Pin%20para%20Todos%20y%20Todas.pdf: http://www.ekoparty.org//archive/2012/Pin%20para%20Todos%20y%20Todas.pdf

[24] github.com/dzzie/RE_Plugins/tree/master/IDA_JScript: https://github.com/dzzie/RE_Plugins/tree/master/IDA_JScript

[25] IDC: https://www.hex-rays.com/products/ida/support/tutorials/idc/index.shtml

[26] IDAPython: https://www.hex-rays.com/products/ida/support/idapython_docs/

[27] idarub: http://www.the-interweb.com/bdump/ida/rublib/index.htm

[28] Perl: http://sourceforge.net/p/cyrplw/code/50/tree/perl/

[29] idajava: https://github.com/cblichmann/idajava

[30] idaocaml: https://code.google.com/p/idaocaml/

[31] github.com/d0c-s4vage/bnarly: https://github.com/d0c-s4vage/bnarly

[32] d0c_s4vage: https://twitter.com/d0c_s4vage

[33] идея: http://d0cs4vage.blogspot.ru/2013/06/windbg-tricks-javascript-windbg.html

[34] github.com/hexgolems/schem: https://github.com/hexgolems/schem

[35] tessel.io/: https://tessel.io/

[36] здесь: http://habrahabr.ru/post/190146/

[37] D3.js: http://d3js.org/

[38] QIRA: https://github.com/BinaryAnalysisPlatform/qira

[39] Источник: http://habrahabr.ru/post/253309/