Print This Post Google Chrome и Secure Preferences

Суббота, 25. Апрель 2015
Раздел: C/C++, Perl, Windows, автор:

chrome_art

На нашем форуме и не только, с некоторой периодичностью люди интересуются алгоритмом генерации "защитного кода" в файле Secure Preferences для браузера Google Chrome.
Зачем он браузеру? Этот код используется для проверки целостности настроек расширений и некоторых других параметров, проще говоря - HMAC. Зачем он людям? Вероятно, это необходимый этап для тихой установки расширений или изменения настроек браузера. Давайте разберемся, где и как происходит генерация этих HMAC'ов.

Для начала заглянем в исходный код проекта Chromium. Беглый поиск по слову hash вывел меня на файл pref_hash_calculator.cc. И, что характерно, именно здесь все и происходит. Процитирую код основных методов, которые отвечают за генерацию:

Авторское форматирование было задвинуто подальше, так как у меня личная неприязнь к такому стилю. Код выглядит довольно простым, осталось понять, что вообще подается на вход. Чтобы не скачивать весь исходный код Chromium и не собирать его, поступим следующим образом: поставим официальный Chrome, скачаем один лишь файл pref_hash_calculator.cc и укажем в Visual Studio путь к отладочным символам для Google Chrome:

Все готово к исследованию. Запускаем браузер, атачимся к процессу, ждем, пока прогрузятся отладочные символы (можно в настройках указать загрузку символов только для модуля chrome.dll, этого будет достаточно), открываем файл pref_hash_calculator.cc в MSVC и ставим брейкпоинт на методе Calculate. Теперь нам необходимо совершить какое-нибудь действие, которое приведет к вычислению хэша, например, установить произвольное расширение из Chrome Web Store. Устанавливаем и попадем на наш брейкопинт.

breakpoint1

Мы видим значения seed_ (перевел в hex для удобства):

И device_id:

Причем seed_ - постоянная величина (но, скорее всего, может меняться от версии к версии), а device_id - уникальный идентификатор компьютера. Откуда берется seed_? Не вдаваясь в подробности поиска, скажу, что он содержится в файле resources.pak, который находится в директории с браузером. Формат содержимого файла известный и давно описан, например, тут. Давайте попробуем самостоятельно извлечь seed_ из resources.pak. Для этого я напишу простенький скрипт на Perl:

Делаем тестовый прогон и узнаем, что seed_ содержится в ресурсе с ID 609, который скорее всего тоже меняется.

script

Теперь нам необходимо получить device_id. Откуда его берет Chrome? Не буду вас утомлять отладчиком, просто скажу, что нас интересует функция GetMachineId из файла machine_id.cc. Приведу ее исходный код на всякий случай:

Этот код является частью сторонней библиотеки RLZ. Я не стал особо копаться в логике вызовов, а просто выдрал код, немного подредактировал и сделал из него отдельный файл, который можно смело собирать и тестировать под Windows (генерация device_id отличается в зависимости от ОС). Ссылка на проект для Microsoft Visual Studio 2013 в конце статьи.
Итак, у нас есть seed_, device_id, осталось обратить свое внимание на два оставшихся аргумента, которые передаются в GetMessage - это path и value. Зайдем сразу внутрь функции GetMessage и посмотрим, что она формирует.

breakpoint2

Мы видим, что path содержит путь к настройкам расширения в Secure Preferences:

А value (value_as_string) - настройки расширения в JSON:

Подытожим логику вычисления:

В качестве hmac используется HMAC SHA256, это видно по коду. Приведу пример простого скрипта, который парсит расширения из файла Secure Preferences и вычисляет hmac для каждого из них, а также super_mac. Алгоритм вычисления прост:

super_mac используется для проверки целостности некоторых настроек браузера и массива пар ид_расширения - hmac. Наконец-таки скрипт:

Запустим скрипт, указав в качестве аргументов device_id, seed и путь к файлу Secure Preferences:

script2

Как мы видим, скрипт успешно отработал и корректно вычислил HMAC'и.

Скрипты из статьи и проект для MSVC 2013, вычисляющий device_id: скачать

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 28 к “Google Chrome и Secure Preferences”


  1. vasya_voin :

    Подскажи как они тут допёрли что менять и где
    https://rdot.org/forum/showthread.php?t=2875
    Там же исходники xull.dll не получить.
    На перл хочется написать такой скрипт для новой версии фф

    [Ответить]

    Kaimi:

    Почему не получить? FireFox внезапно стал браузером с закрытым исходным кодом?

    [Ответить]


  2. vasya_voin :

    Я скачал исходники, там нет этой библиотеки

    [Ответить]

    Kaimi:

    Т.е. нет пути типа: toolkit/library/moz.build?
    И в файле moz.build ни единого упоминания слова xul?

    [Ответить]


  3. cfk :

    A lil bit offtop, but who wants use Chrome, Opera(nu) & Vivaldi, etc with WebRTC, that cannot be disabled.

    vasya_voin: Otherwise - u can always filter FF quotes, and other stuff with "Privoxy", check rdot forum topic for this.

    [Ответить]


  4. zeitgeist :

    А как на счёт других полей?
    Что они кодируют для startup url, например?

    [Ответить]

    Kaimi:

    А как на счет самому проделать подобные действия с отладчиком и посмотреть?

    [Ответить]

    zeitgeist:

    @Kaimi,
    да не вопрос, просто компиляция ещё часов 10 возьмёт.
    А вообще спасибо за статью.

    [Ответить]

    Kaimi:

    Зачем компилировать? Я же писал, что достаточно отладочные символы подключить и интересующие одиночные файлы скачать


  5. zeitgeist :

    Сейчас увидел, спасибо.

    [Ответить]


  6. Andrew :

    Кстати, для Яндекс-браузера device_id не нужен. Сообщение формируется extension_path + extensio_setting. А в качестве key можно передать 0x00

    [Ответить]


  7. DevilJeka :

    Privet Kaimi, iskal infu nas4iot faila Secure Preferences i natknulsia na tvoi sait(o4eni interesnii kstati, molodez), doljen skazati cho ti edinstvenii isto4nik takoi poleznoi informazii (poleznoi dlia griaznih del pravda :D).
    Ia doljen sdelati installer kotorii v konze dobavliaet stranizu nashei kompanii v startup_pages v chrome. Vsio kak po maslu no na samom glavnom:

    c:\Users\operatore 3\AppData\Local\Google\Chrome\User Data\Default>hmac.pl 837552B31736B91B48643763FE6E1F494FC1D936AE09173C3D E748F336D85EA5F9DCDF25D8F347A65B4CDF667600F02DF6724A2AF18A212D26B788A25086910CF3A90313696871F3DC05823730C91DF8BA5C4FD9C884B505A8
    "Secure Preferences"

    values on reference is experimental at C:\Users\operatore 3\AppData\Local\Google\Chrome\User Data\Default\hmac.pl line 91.
    Can't use an undefined value as a HASH reference at C:\Users\operatore 3\AppData\Local\Google\Chrome\User Data\Default\hmac.pl line 36.

    K sojalenii ia v Perle ne 4eshu, i ia eshio doljen perevesti eto vsio na C#... Smojesh proveriti po4emu tvoi script u menia ne rabotaet (Ia kru4u ego na Perl 5.22.0 Strawberry)? a esli esti jelanie i vremia to podmodifizirovati ego 4tob kak parametri polu4al: "device_id, seed, key, value" e vidoval hmac dlia "value" i novii super-mac (vsio na stdout). Potom ia ego sobiru v exe, sunu v installer i budu parsiti ego stdout kogda nado.

    Ogromnoe spasibo za takuiu infu, i sait krasava :)

    Privet iz Italii

    [Ответить]

    DevilJeka:

    Izvini, script rabotaet otli4no, prosto ia emu podoval osobii file "Secure preferences", neznaiu po4emu no na moiom pk tam nahoditsia tolko super-mac i vesit 105byte, daje s novoi ustanovkoi, a na drugih pk 30-50kb i oni rabotaiut na tvoiom scripte.

    [Ответить]


  8. DevilJeka :

    Izviniaiusi, po4ital script paru raz i vsio ponial, Perl menia pugal a v konze konzov vsio o4eni prosto, u menia on ne rabotal potomu4to ia imel levii "Secure Preferences" file, tam tolko super-mac nohoditsia, a ostalnie mac v "Preferences".

    [Ответить]


  9. xenohunter :

    Иллюстрация напомнила о комиксе Fisheye Placebo. Красивый комикс. Рекомендую.

    [Ответить]


  10. Alde :

    Скрипт, запущенный в версиях Perl под Windows (ActivePerl 5.20.? x64, Strawberry 5.22.0 x32) каждый раз возвращают разные MAC для расширений: как собственно посчитанные, так и ref (

    SuperMac всегда считается верно

    [Ответить]

    Kaimi:

    Не наблюдаю такой проблемы с Strawberry Perl 5.22 x64.
    Правда выдает warning на строку if(scalar values $ref->{$key} == 0) , но считает корректно.

    Другое дело список расширений каждый раз в произвольном порядке выдается, но это ни на что не влияет.

    [Ответить]

    Alde:

    > Другое дело список расширений каждый раз в произвольном порядке выдается, но это ни на что не влияет.
    Ааа, точно, в произвольном порядке.

    Спасибо.

    [Ответить]


  11. Геннадий :

    Здравствуйте.
    Я получил $seed с помощью скрипта и $device_id с помощью проекта rlz_id. Вместо аргументов командной строки в скрипте вычисления hmac указал:
    my $sec_pref_file = 'C:\\Users\\...\\Default\\Secure Preferences';
    my $seed = 'e748f33...505a8';
    my $device_id = '6A7411E...290539F';
    При запуске получаю такие ошибки:
    values on reference is experimental at startpage.pl line 90.
    Global symbol "$device_id" requires explicit package name (did you forget to declare "my $device_id"?) at startpage.pl line 48.
    Global symbol "$key" ... line 50.
    Global symbol "$device_id" ... line 66.
    Global symbol "$key" ... line 68.

    Строки кода:
    48 while(my $ref = shift @queue)
    50 next unless ref $ref eq ref {};
    66 {
    68 delete $ref->{$key} ;

    Среда:
    Window 10 x64
    perl v5.22.1 built for MSWin32-x86-multi-thread-64int
    Binary build 2201 [299574] provided by ActiveState http://www.ActiveState.com
    Built Dec 24 2015 12:36:28

    Подобные ошибки perl выдает если переменные не инициализированы в режиме strict, однако они инициализированы! не понимаю в чем причина.
    В perl я новичок, установил только ради Вашего скрипта

    Помогите устранить указанные ошибки компиляции, пожалуйста :)

    [Ответить]

    Kaimi:

    pastebin.com, по фрагментам я не угадаю, что не так

    [Ответить]


  12. Геннадий :

    спасибо. заработало. я запускал и редактировал разные файлы :(
    Существует ли один скрипт, выполняющий все этапы вычисления hmac включая определение входных параметров?

    [Ответить]

    Kaimi:

    У меня такого нет

    [Ответить]


  13. Pabloz :

    Kaimi, большое спасибо за пост, очень познавательно. Есть вопрос..я в MSVC 2012 Ultimate указал путь к серверу с отладочными символами и при подключении к процессу chrome.exe, идет их подгрузка, но когда я открываю файл pref_hash_calculator.cc и ставлю бряк, появляется мессага о том, что символы для данного элемента не подгружены и остановки не будет?.

    [Ответить]

    Kaimi:

    Может символы не подгрузились (можно посмотреть в логе студии), также не вижу pref_hash_calculator в исходниках по старому пути (видимо куда-то перенесли), может не к тому процессу хрома подключился, может еще что-то...

    [Ответить]

    Pepe:

    How to calculate HMAC "startup_urls":?

    key = seed_
    message = device_id + '[ "http://www.google.es/"]'
    HMAC (message, key)

    This method does not work for me.
    Greetings.

    [Ответить]

    Kaimi:

    Install Visual Studio, attach debugger to the Chrome process, change startup url, observe how is it being hashed.


  14. Геннадий :

    я нашел исходники здесь https://chromium.googlesource.com/chromium/chromium/+/trunk/chrome/browser/prefs, увидел зависимости и решил использовать стороннюю библиотеку. из того что нашел понравилось это http://create.stephan-brumme.com/hash-library/.

    [Ответить]


  15. pabloz :

    Спасибо, разобрался. Да, действительно, файл теперь лежит в другом месте: https://chromium.googlesource.com/chromium/src.git/+/master/components/user_prefs/tracked/pref_hash_calculator.cc

    [Ответить]


Оставьте ваш комментарий