Всем известно, что находясь внутри браузера, нельзя извлечь достаточное количество информации о его пользователе с помощью простого JavaScript. Служебная информация, вроде имени браузерного движка, операционной системы и их версий хоть и дает общее представление о пользователе (и об аудитории в целом), но все же не является всеобъемлющей.

Для комплексного анализа пользователя используется User-ID в Universal Analytics, но с помощью независимых программных компонентов, запущенных и находящихся где-то в памяти компьютера рядом с браузером, тоже можно собирать данные о пользователе. Полученная непосредственно из памяти браузера информация позволит осуществить анализ как отдельного пользователя, так и всей аудитории. Здесь будет рассмотрено семейство браузеров на движке Webkit и на конкретном примере браузера Google Chrome.

image

Браузер как хранилище интересной информации


Ежедневно миллионы людей доверяют своему веб-браузеру самую сокровенную информацию: личные и банковские данные, списки избранных сайтов. Большая часть действительно «вкусной» информации (в первую очередь, для злоумышленников) скрывается как самим браузером (менеджеры паролей с шифрованием), так и веб-ресурсами, которыми люди пользуются с помощью браузера (безопасно написанный и отлаженный код, SMS-оповещения/подтверждения и т.д). Но помимо этого остаются открытыми и легкодоступными данные, вроде исходного кода страниц. Ведь именно там и находится большинство того материала, на основе которого и можно произвести комплексный анализ пользователей. И материал этот отнюдь не одного лишь технического характера.

Сами по себе браузеры (особенно на базе Chromium) построены таким образом, чтобы о пользователях «утекало» как можно меньше информации во внешний мир. Т.е разработчики всячески пытаются обезопасить людей от всевозможных, пусть даже и несущественных утечек. Google Chrome, к примеру, создает для каждой отдельной вкладки свою «песочницу» в виде отдельного процесса. О деталях можно узнать, перейдя по локальной ссылке: chrome://memory Логично предположить, что каждая такая отдельная вкладка-процесс хранит исходный код собственной страницы.

Как узнать то, что знает браузер?


Процесс браузера ничем не отличается от других процессов операционной системы, а потому и он точно так же хранит все свои данные в оперативной памяти и для него свойственны все те же принципы секторной памяти. Программные компоненты, будучи запущенными в пределах ОС, находятся на одном программном уровне с браузером. Это дает возможность прочитать память браузера, снять её дамп.

Для демонстрации был создан небольшой тестовый проект на C#, позволяющий собирать сорцы исходного кода из памяти браузера. Исходный код проекта можно посмотреть в репозитории BitBucket. Утилита для непосредственного использования — здесь.

image

Теперь стоит понять, от чего же зависит качество сбора информации из исходных кодов открытых страниц браузера, располагающихся в памяти. Chromium — это OpenSource-проект, так что достаточно немного покопаться в его исходном коде, чтобы прояснить многие базовые аспекты.

Например, то, как устроена страница веб-документа. В классе Document, являющимся частью движка WebKit, есть вот такой код(С++):

...
// "body element" as defined by HTML5 (https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2).
// That is, the first body or frameset child of the document element.
HTMLElement* body() const;

// "HTML body element" as defined by CSSOM View spec (http://dev.w3.org/csswg/cssom-view/#the-html-body-element).
// That is, the first body child of the document element.
HTMLBodyElement* firstBodyElement() const;
...
HTMLHeadElement* head() const;
...

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

Сочетая эту информацию со знаниями о том, как операционная система выделяет память для нового программного объекта, получается, что находиться в памяти HTML код страницы может в совершенно раздробленном виде.

Сканирование памяти и вычленение разведданных


Предположим, один из пользователей открыл у себя в браузере новую вкладку (вот такую). Что в этом простом случае, казалось бы, можно извлечь?

Например, то, что искал пользователь в поисковой системе, и что еще не было стерто браузером из памяти:

  <div class="suggest2content suggest2contentthemelarge" style=
    "min-width:693px;">
        <div class="suggest2group">
            <div class="suggest2title">
                <span class="suggest2a11y">Группа подсказок:</span>
            </div>

            <ul class="suggest2items">
                <li class="suggest2-item suggest2-itemtypetext i-bem" data-bem=
                "{"suggest2-item":{}}"><span class=
                "suggest2-itemtext"><!-- Вот, что он искал -->
                 <b>какой фильм посмотреть</b></span></li>

                <li style="list-style: none">...</li>
            </ul>
        </div>
    </div>

Можно узнать и некоторые персональные данные. Например, почтовый ящик конкретного пользователя:

<div class="...">
        <a href="https://passport.yandex.ru/passport?mode=passport" tabindex=
        "0"><span class="usericon"></span> <span class="username">
        <!-- Тут "именной" почтовый ящик яндекса -->
         <span class="userfirst-letter">n</span>astya.ivanova</span>
        <span class="notice noticemoreno i-bem noticejsinited" data-bem=
        "{"notice":{}}"></span></a>

        <div class="popupcontent">
            <div class=
            "b-menu-vert dropdown-menumenu dropdown-menumenuthemeffffff">
                <ul class="b-menu-vertlayout">
                    <li style="list-style: none">...</li>

                    <li class="b-menu-vertlayout-unit">
                        <div class=
                        "b-menu-vertitem b-menu-vertitemthemegray multi-authaccount">
                        <span class=
                        "link multi-authaccount-link user userblankyes useraccountyes"
                            tabindex="0"></span>

                            <div class="usericon">
                                <span class=
                                "link multi-authaccount-link user userblankyes useraccountyes"
                                tabindex="0"></span>
                            </div><span class=
                            "link multi-authaccount-link user userblankyes useraccountyes"
                            tabindex="0"><span class="username"><span class=
                            "userfirst-letter">n</span>astya.ivanova</span></span>
                        </div>
                    </li>

                    <li style="list-style: none">...</li>
                </ul>
            </div>
        </div>
    </div>

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

Часто полезную информацию получается извлечь благодаря механизму так называемого «межсайтового сопряжения». Например, когда определенные веб-ресурсы поддерживают авторизацию через аккаунт Google+, Facebook и т.д. В таком случае уже удастся получить наиболее приближённые к конкретному пользователю аналитические данные.

Предположим у целевого пользователя есть google-аккаунт и этот пользователь прокоментировал определенную сущность на сайте, который сопряжен с его аккаунтом Google. В таком случае бОльшая часть информации о google-пользователе будет инкапсулирована внутри исходного кода веб-страницы. Вот примерная часть дампа, которую можно будет вычленить из большинства страниц, интегрированных с Google:

<div class="SR">
        <h3 class="zi"><!-- Имя и ссылка на профиль -->
         <a class="ob tv Ub Hf" href="./113137362950198752663">Nastya
        Ivanova</a></h3>прокомментировал видео на YouTube
    </div><span class="uG Ve"><span class="d-s Vt Hm dk Q9" tabindex="0" title=
    "Кто видит">Доступно всем в Интернете</span>  -  <span class=
    "uv PL"><a class="o-U-s FI Rg" href=
    "113137362950198752663/posts/T8xcx2jKjGP" rel="noreferrer" style=
    "display:none" target="blank">2014-04-05</a></span></span>
    undefinedundefinedundefined

    <div class="Al pf">
        undefined

        <div class="Xx xJ">
            <div class="Ig At dn">
                <div class="Bt Pm">
                    <div class="tG QF">
                         
                    </div><!-- Комментарий пользователя -->

                    <div class="Ct">
                        Dear not russian speakers! For full understanding the
                        Soviet Anthem you should hear and understand it on
                        russian language. Interpretation is not so bad but
                        meaning is distorted here and there. And thats because
                        English is not so rich language as Russian I think ;)
                    </div>
                </div>
            </div>
        </div>
    </div>

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

Что в итоге?


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

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

Конспект


  • Исходный код проекта, который собирает информацию о пользователе можно посмотреть тут.
  • Аналог подобного процесса — использование User-ID в Google Analytics.
  • Самые точные данные о пользователе можно получить благодаря межсайтовому сопряжению (аккаунты соц. сетей).

Комментарии (9)


  1. Sap_ru
    20.07.2015 15:38
    +2

    А каким таким образом получить из JS доступ к «сырой» памяти процесса? Этот момент волшебным образом опущен.
    Вы говорить, что есть «chrome://memory», а потом сразу начинаете рассуждать над тем, что находится в ОЗУ.


  1. Sap_ru
    20.07.2015 15:41
    +3

    Вник немного. Вы рассказываете о JS и браузерах, а потом предлагаете запустить программу на C# ?! Если есть возможность произвольные программы запускать, то очевидно, что это дыра — берёт список уязвимостей ОС и творим чудеса.


    1. Asen
      20.07.2015 15:56
      -1

      Ну, программа на C# лишь демонстрирует «присутствие» на одном программном уровне с браузером.
      Конечно же гипотетический запуск непосредственно из браузера был бы уязвимостью и очень серьёзной.
      В прошлом было исправлено немало таких уязвимостей, корнями уходившими, как правило, в модули-расширения вроде Flash и Java.


  1. BeLove
    20.07.2015 15:48
    -1

    А какие аналитические компании ведут себя подобным образом? Предлагают поставить свой агент, дампят память, анализируют её (парсинг на примере статьи) и отсылают её в «центр»? :)


  1. ateraefectus
    20.07.2015 15:59
    +3

    Вы бы ещё рассказали о том, что если ходить по порносайтам, в один прекрасный день можно словить винлокер. Смысл в который раз пережевывать настолько очевидные вещи?


  1. aGRa
    20.07.2015 18:33
    +1

    Очень сомневаюсь, что подобные программы будут работать без администраторских прав.


  1. anatolikus
    21.07.2015 01:42
    +1

    Думаю, куда интереснее и реальнее возможность сбора так называемых «отпечатков браузера» и идентификации пользователя по ним.
    Уникальность своего отпечатка можно проверить здесь: panopticlick.eff.org


    1. PsyHaSTe
      23.07.2015 16:25

      А можно поподробнее, что с этой инфой делать? А то у всех моих знакомых стоит FF, и выдается результат 22.43 бита информации. Как-то подозрительно совпадает.


      1. anatolikus
        24.07.2015 01:45
        -1

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

        Тут более интересна информация об уникальности отпечатка. Только что проверил и мой результат не очень оптимистичен: «Your browser fingerprint appears to be unique among the 5,637,227 tested so far.»

        А что с этим делать… Да пока ничего. По крайней мере, я не знаю. Если есть что скрывать, то желательно маскироваться под большинство по всем пунктам в табличке результатов. Печаль в том, что даже если отключить JS в браузере, то тебя можно будет узнавать по: «ага, вот опять пришел тот чувак, с отключенными скриптами».