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



    Если вы посмотрите описания вакансий на позицию 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 постепенно сокращается…
    Метки:
    • +36
    • 20,5k
    • 4
    Digital Security 291,17
    Безопасность как искусство
    Поделиться публикацией
    Похожие публикации
    Комментарии 4
    • +2
      коротко и на тему, спасибо)
      • 0
        Frida RE

        И это, наверное, самый интересный проект в данном обзоре.


        mmBBQ круче, даром что более общего назначения. Ну и да, там прекрасный LuaJIT с его нечеловечески прекрасным FFI.
        • +2
          Я бы ещё добавил немного информации про Duktape, javascript-движок для интеграции в C/C++ проекты. Он же используется в упомянутом выше radare.
          • 0
            Я же пока что пилю свою версию прошивки для ESP8266, идея с JS оказывается не нова. Но разница в цене ощутима ;)

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

            Самое читаемое