1 место Анонимность в каждый ZennoPoster. От Useragent'a до шрифтов. Часть 1.

Discussion in 'Седьмой конкурс статей' started by ibred, May 22, 2017.

  1. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Всех приветствую!
    Долгое время отсутствовал на данном форуме, да и в интернете в целом.
    В моей жизни щелкнул тумблер «Nightmare», сейчас уже потихоньку всё налаживается, - разобрался в правилах игры :-)

    Вот даже статью размещаю с опозданием, но nuaru в курсе, так что предлагаю выдохнуть.

    anonymous-computer.jpg

    Сегодня я раскрою одну насущную тему – анонимность.

    Вопрос анонимизации я считаю невероятно актуальным в нашем Zenno-сообществе, исходя из количества постов (вопросов) появляющихся с регулярной периодичностью, касающихся эмуляции\генерации параметров браузера и\или профиля и кричащими заголовками «Меня палят!!! Что делать, как обойти???»

    Надеюсь, что с появлением этой статьи, отпадёт большинство вопросов на заданную тему, качество работы улучшится, а кошелёк станет толще.

    Как говорила моя учительница по русскому языку со школьных времён: «Понеслась душа в рай!»

    Анонимность. От теории к практике.
    Расскажу всё, что знаю, только не бейте.
    Мы не хакеры, поэтому нам скрывать нечего, наоборот нам необходимо предоставить сервисам и сайтам, как можно больше информации о нас чтобы нас ни в чём не заподозрили, но, естественно, с эмулированной.

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

    # Методы идентификации пользователей #
    Информация о браузере

    — Useragent и свойства навигатора
    — Разрешение экрана, глубина и видимая область
    — Набор плагинов
    — Другое
    Хранилища
    — Кэш (ETag)
    — Web storage
    — IndexedDB
    — Куки (Web cookies, LSO Cookies, Evercookies).
    — HSTS Super cookies (HTTP Strict Transport Security)
    — История посещений (History API)
    Связь и местоположение
    — IP адрес (Прокси)
    — DNS (Domain Name System)
    — WebRTC
    — Геолокация
    — Таймзона
    Отпечатки
    — WebGL
    — Fingerprint Canvas
    — Browser Fingerprint
    — AudioContext Fingerprint
    — Системные шрифты (Fonts Fingerprint)



    mozilla-firefox-10-32x32.png Браузер
    Useragent. Это строка, используемая клиентскими приложениями (в нашем случае браузер) в качестве своего имени. В её состав входит несколько компонентов.

    Свежие UA популярных браузеров.
    • Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
    • Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 OPR/42.0.2393.94
    • Mozilla/5.0 (Windows NT 6.3; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
    Раз ZennoPoster работает с Firefox – его и рассмотрим.
    Но совсем скоро появится возможность играться и с браузером Chrome.

    Mozilla / 5.0 ([Platform]; rv: [GeckoVersion]) Gecko / [GeckoTrail] Firefox / [FirefoxVersion]
    • Mozilla/5.0 — Основной токен, указывающий версию совместимости и является общим практически для каждого браузера на сегодняшний день.
    • [Platform] – Описывает родную платформу, на которой работает браузер. Например: Windows, Mac, Linux или Android. Обратите внимание, что эта строка может состоять из нескольких маркеров, разделённых «;».
    • rv:[GeckoVersion] — Указывает версию выпуска Gecko. В последних версиях браузера GeckoVersion такая же, как FirefoxVersion.
    • Gecko / [GeckoTrail] — Указывает на то, что браузер основан на Gecko. На десктопах [GeckoTrail] является константой «20100101»
    • Firefox / [FirefoxVersion] – Заявляет, что используется браузер Firefox определённой версии.
    Так же при взаимодействии через обозреватель необходимо заполнять и доп. свойства навигатора: buildID, appVersion, appName, appCodeName, language(s), platform, oscpu, product, productsub.

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

    Решение:
    Code (csharp):
    1. // Выбираем случайную версию Firefox
    2. string version = Macros.TextProcessing.Spintax("{38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53}");
    3.  
    4. //Формируем набор buildID нашего Firefox (у каждой версии свой) [Идея хранения позаимствована у doc'a, за что ему большая благодарность!]
    5. Dictionary <string, string> buildIDSet = new Dictionary <string, string>();
    6. buildIDSet.Add("53", "20170413192749");
    7. buildIDSet.Add("52", "20170316213829");
    8. buildIDSet.Add("51", "20170125094131");
    9. buildIDSet.Add("50", "20161104212021");
    10. buildIDSet.Add("49", "20161019084923");
    11. buildIDSet.Add("48", "20160817112116");
    12. buildIDSet.Add("47", "20160623154057");
    13. buildIDSet.Add("46", "20160502172042");
    14. buildIDSet.Add("45", "20160905130425");
    15. buildIDSet.Add("44", "20160210153822");
    16. buildIDSet.Add("43", "20160105164030");
    17. buildIDSet.Add("42", "20151029151421");
    18. buildIDSet.Add("41", "20151014143721");
    19. buildIDSet.Add("40", "20150812163655");
    20. buildIDSet.Add("39", "20150618135210");
    21. buildIDSet.Add("38", "20150513174244");
    22.  
    23. instance.ShowNavigatorField(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.BuildId);
    24. // Устанавливаем BuildID
    25. instance.SetHeader(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.BuildId, buildIDSet[version]);
    26.  
    27. // Формируем набор версий операционной системы Windows
    28. // 6.0 Windows Vista
    29. // 6.1 Windows 7
    30. // 6.2 Windows 8
    31. // 6.3 Windows 8.1
    32. // 10.0 Windows 10
    33. string winOC = Macros.TextProcessing.Spintax("{6.0|6.1|6.2|6.3|10.0}");
    34. string platform = Macros.TextProcessing.Spintax("{Win32|Win64}");
    35.  
    36. // Определяем "битность" самого приложения
    37. string platformApp = string.Empty;
    38. if(platform=="Win32"){
    39.     platformApp = Macros.TextProcessing.Spintax("{; WOW64|}");
    40. } else {
    41.     platformApp = "; Win64; x64";
    42. }
    43. // Устанавливаем Useragent
    44. project.Profile.UserAgent = string.Format("Mozilla/5.0 (Windows NT {0}{1}; rv:{2}.0) Gecko/20100101 Firefox/{2}.0", winOC, platformApp, version);
    45. project.Profile.UserAgentAppVersion = "5.0 (Windows)";
    46. project.Profile.UserAgentAppName = "Netscape";
    47. project.Profile.UserAgentAppCodeName = "Mozilla";
    48. project.Profile.UserAgentProduct = "Gecko";
    49. project.Profile.UserAgentProductSub = "20100101";
    50.  
    51. // OC
    52. project.Profile.UserAgentOsCpu = string.Format("Windows NT {0}{1}", winOC, platformApp);
    53. project.Profile.UserAgentPlatform = platform;
    54.  
    55. Random r = new Random();
    56. // Формируем набор возможных вариантов Accept-Language
    57. // Здесь присутствует как русский язык, так и иностранный.
    58. // Если необходимо, чтобы выборка была по какому-то определенному признаку - закоментируйте или удалите не нужные строки.
    59. string[] acceptLanguageSet = {
    60.     "ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4",
    61.     "en-US,en;q=0.5",
    62.     "en-US,en;q=0.8,es;q=0.6",
    63.     "en-US,en;q=0.8,nl;q=0.6,el;q=0.4,de;q=0.2",
    64.     "ru-RU,ru;q=0.9,en;q=0.8",
    65.     "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"
    66. };
    67. // Устанавливаем Accept-Language
    68. string acceptLanguage = acceptLanguageSet[r.Next(0, acceptLanguageSet.Length)].ToString();
    69. project.Profile.AcceptLanguage = acceptLanguage;
    70. // Устанавливаем настройки языка
    71. project.Profile.UserAgentBrowserLanguage = acceptLanguage.Substring(0, acceptLanguage.IndexOf(','));
    72. project.Profile.UserAgentLanguage = acceptLanguage.Substring(0, acceptLanguage.IndexOf(','));
    Разрешение экрана, битность и видимая область.
    Легко определяется с помощью JavaScript и CSS (Media Queries) и так же легко эмулируется.
    Code (csharp):
    1. Random r = new Random();
    2.  
    3. // Формируем набор популярных десктопных разрешений [Идея хранения позаимствована у doc'a, за что ему большая благодарность!]
    4. int [,] resolutionSet = {
    5.     {2880, 1800},
    6.     {2560, 1600},
    7.     {2560, 1440},
    8.     {1920, 1200},
    9.     {1920, 1080},
    10.     {1680, 1050},
    11.     {1600, 1200},
    12.     {1600, 900},
    13.     {1440, 900},
    14.     {1366, 768},
    15.     {1360, 768},
    16.     {1280, 1024},
    17.     {1280, 800},
    18.     {1280, 768},
    19.     {1152, 864},
    20.     {1080, 1920},
    21.     {1024, 768}
    22. };
    23. // Получаем рандомное разрешение и устанавливаем
    24. int resolution = r.Next(resolutionSet.Length/2);
    25. project.Profile.ScreenSizeWidth = resolutionSet[resolution, 0];
    26. project.Profile.ScreenSizeHeight = resolutionSet[resolution, 1];
    27. // Видимая область
    28. project.Profile.AvailScreenWidth = project.Profile.ScreenSizeWidth-17;
    29. project.Profile.AvailScreenHeight = project.Profile.ScreenSizeHeight-40;
    30. // Глубина цвета монитора (Color Depth)
    31. // [Чуть позже будет обновление механизма установки этого параметра]
    32. instance.SetScreenPreference("screen_color_depth", 24);
    33.  
    34.  
    Набор плагинов
    Владелец ресурса так же может получить доступ к списку Ваших плагинов, предустановленных в браузере, которые, кстати, говоря, являются частью fingerprint'a о котором речь чуть позже (в разделе отпечатки).

    Решение 1: Скрыть все плагины.
    Code (csharp):
    1. // Получаем список плагинов
    2. var PluginList = instance.GetPlugins().ToList();
    3. // По очерёдно в цикле скрываем все плагины
    4. for (int i=0; i < PluginList.Count; i++){
    5.    instance.HidePlugin(PluginList[i]);
    6. }
    Решение 1.1: Скрыть все плагины так же можно, полностью отключив Flash.
    Code (csharp):
    1. // Аналоги на кубиках находятся в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UsePlugins = false; // Отключает Flash, Java, Silverlight
    Решение 2: Подменить\эмулировать плагины.
    Code (csharp):
    1. // -----------------------------
    2. //---------- Шаблон ------------
    3. // -----------------------------
    4.  
    5. // Создаём плагин
    6. var template = new ZennoLab.CommandCenter.PluginItem("Название плагина", "библиотека.dll", "Описание", "Версия");
    7. // Включаем
    8. instance.ShowPlugin(template);
    9.  
    10. // В шаблоне отсутствует mime-тип. О нём я напишу чуть позже.
    11. // Как только информация обновится, сообщу об этом в топике.
    12.  
    13. // -----------------------------
    14. //---------- Пример ------------
    15. // -----------------------------
    16. // Создаём плагин
    17. var plugin_acestream = new ZennoLab.CommandCenter.PluginItem("Ace Stream P2P", "npace_plugin.dll", "ACE Stream Plug-in Version 2.2.7, Copyright (c) 2012-2017 Innovative Digital Technologies", "2.2.7.0");
    18. // Включаем
    19. instance.ShowPlugin(plugin_acestream);
    Другое
    Hardware Concurrency. Соответствует количеству ядер процессора.
    Code (csharp):
    1. // Формируем набор возможных вариантов
    2. string cpu = Macros.TextProcessing.Spintax("{2|4|6|8}");
    3.  
    4. instance.ShowNavigatorField(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.HardwareConcurrency);
    5. // Устанавливаем рандомное кол-во ядер процессора
    6. instance.SetHeader(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.HardwareConcurrency, cpu);
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Do Not Track – это HTTP-заголовок, который позволяет пользователю обходить отслеживание его действий третьими лицами. Активировав в браузере DNT, вы сможете оповестить их о своем нежелании быть отслеженным. Если третья сторона поддерживает DNT систему, то она не станет следить за вами или помещать в браузер куки для получения данных о вас.

    Недостаток системы заключается в том, что это добровольная технология, основанная на системе доверия и принятия. Если сторонняя компания поддерживает её, то она не будет отслеживать действия пользователя, установившего данную опцию. В противном случае ваши действия будут отслеживаться.
    Code (csharp):
    1. instance.ShowNavigatorField(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.DoNotTrack);
    2. instance.SetHeader(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.DoNotTrack, "1"); // Включает Do Not Track
    3.  
    4. // 0 - Выключает, 1 - Включает, null - "Мне всё равно"
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Touchscreen Type (Touchscreen Support) - Поддерживает ли Ваше устройство сенсорный экран.
    Если на сайте (где мы будем работать) есть такая проверка, как правило тестируется 2 сценария:
    1. Определяется максимальное кол-во одновременных сенсорных контактов
    2. Вызов события ontouchstart и TouchEvent на странице

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

    Второе указывается (включается) явно через about:config. Чтобы активировать сенсорные события, необходимо включить dom.w3c_touch_events.enabled, установив значение 1. Где 0 - Выключено, 1 - Включено, 2 - Автоматическое определение.

    Code (csharp):
    1. instance.SetBrowserPreference("dom.w3c_touch_events.enabled", 1); // Включаем сенсорные события
    2. instance.ShowNavigatorField(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.MaxTouchPoints);
    3. instance.SetHeader(ZennoLab.InterfacesLibrary.Enums.Browser.NavigatorField.MaxTouchPoints, "5"); // Устанавливаем 5 (например) максимальных одновременных касаний.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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

    С помощью JS владелец сайта может узнать, используется у Вас в браузере подобный механизм или же нет.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. // Вам необходимо выбрать что-то одно и выполнить код.
    3. instance.UseAdds = false; // Режим показа рекламы запрещён
    4. instance.UseAdds = true; // Режим показа рекламы разрешён
    5.  
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    devicePixelRatio - Соотношение пикселя к устройству или как ещё говорят: отношение физического пикселя к виртуальному. И может меняться в зависимости от масштаба браузера.

    Значение по-умолчанию определяется устройством.
    Например, Apple iPhone 7 и MacBook Pro имеют Pixel Ratio по-умолчанию равной 2. А старенький Nexus One и таблет Amazon Kindle Fire HD 7 имеют значение 1.5. Дисплеи обычной четкости выдают 1.

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

    Code (csharp):
    1. Tab tab = instance.ActiveTab;
    2. tab.PageScale = 150; // Устанавливаем Pixel Ratio в 150%
    3.  
    4. // Всё, значение установлено. Если Вы захотите его получить:
    5. return tab.PageScale; // Вернет значение 150. JavaScript на стороне сервера будет определять, как 1.5


    database-key-icone-4972-32.png Хранилища
    Кэш
    Кэш браузера может служить не только для ускорения загрузки страниц, за счёт хранения временных файлов, но и для идентификации пользователей. Отличный тому пример ETag.

    ETag (Entity Tag) — это уникальный идентификатор, присвоенный веб-сервером на определенную версию ресурса. Если содержание ресурса для этого адреса меняется на новое, назначается и новый ETag. Использование в таком ключе ETags аналогично использованию отпечатков пальцев.

    Подробнее:
    https://ru.wikipedia.org/wiki/HTTP_ETag

    Решение: Очистить кеш.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.ClearCache(); // Очищаем кэш
    Web storage (localStorage и sessionStorage, Global Storage, Database Storage via SQLite)

    Если упростить, то веб-хранилища можно рассматривать как усовершенствованные куки. Ключевые отличия заключается в следующем:
    Размер хранимой информации. Веб-хранилища могут хранить в себе в ~1000 раз больше информации, чем куки, например.
    Интерфейс. Веб-хранилище попадает исключительно под компетенцию сценариев (скриптов) на стороне клиента. Данные интернет-хранилища не передаются на сервер при каждом запросе HTTP, и веб-сервер не может напрямую записать в интернет-хранилище.
    Две области хранения. Всё, что попадает в локальное хранилище и сохраняются после закрытия браузера. А то, что было добавлено в сессионное хранилище - удалется при закрытии окна.

    Решение #1: Очистить куки. Данные из хранилищ удаляются вместе с ними.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.ClearCookie(); // Очищаем куки
    Решение #2: Блокировать работу хранилищ.
    Code (csharp):
    1. instance.SetBrowserPreference("dom.storage.enabled", false);
    Тестирование: http://javascript.ru/files/id/persistence.html

    IndexedDB
    Это объектная база данных, которая намного мощнее, эффективнее и надежней, чем Web Storage.
    Если Вы не разработчик, а обычный пользователь, лучше полюбуйтесь этим енотом:
    enot.jpg
    Для нас - ценителей анонимности, это лишь хранилище пользовательских данных. К сожалению, очистить его штатными средствами ZennoPoster не предоставляется возможным на данный момент.

    Решение: Запретить использование IndexedDB в конфиге браузера.
    Code (csharp):
    1. instance.SetBrowserPreference("dom.indexedDB.enabled", false);
    Тестирование: http://demo.techbrij.com/1042/HTML5-IndexedDB-demo.php


    Куки (Web cookies, LSO Cookies, Evercookies)
    Web cookies (http cookies)
    - уникальные текстовые данные, отправленные веб-сервером пользователю с последующим сохранением на его компьютере. На практике обычно применяется для хранения данных о пользователе: аутентификации, персональные предпочтения и настройки, сеансы и ведения статистики.

    Поэтому не забывайте их чистить при работе с несколькими аккаунтами:
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.ClearCookie(); // Очищаем куки
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    LSO Cookies (Flash cookies) - Полное название Local Shared Objects. Подход во многом аналогичен обычным «печеньям», но имеет ключевые отличия: данный тип cookie является общим для всех браузеров на компьютере (в отличие от классической cookie, которая привязана к браузеру) и способен хранить в несколько раз больше информации.

    Решение #1: Несмотря на глобальность распространения, очищается обычным способом:
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.ClearCookie(); // Очищаем куки
    Решение #2: Отключить Flash.
    Code (csharp):
    1. // Аналоги на кубиках находятся в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UsePlugins = false; // Отключает Flash, Java, Silverlight
    Решение #3: Запретить сайтам хранить информацию на компьютере через менеджер настроек Flash Player. Для этого потребуется зайти в "Панель управления" -> "Система и безопасность" - > Flash Player (если такого у Вас нет, тогда просто в поиске панели управления напишите "Flash").
    2017-05-20_14-15-23.png

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Evercookies
    Данная технология использует все существующие хранилища, а также массу всевозможных хитростей, помогающих «промаркировать» компьютер пользователя. Ключевой особенностью данного механизма является автоматическое восстановление кук, если они не были удалены хотя бы в одном из хранилищ.

    Простая очистка куков и кэша не поможет т.к. они цепляются за историю посещения и в конечном итоге восстанавливаются.

    Решение: Перед очисткой необходимо закрыть все вкладки браузера.
    Code (csharp):
    1. instance.CloseAllTabs(); // Закрываем все вкладки браузера
    2. instance.ClearCache(); // Очищаем кэш
    3. instance.ClearCookie(); // Очищаем куки
    Тестирование: http://samy.pl/evercookie/


    HSTS Super cookies (HTTP Strict Transport Security) - Данный механизм защищает соединения между браузером и сервером, принудительно активируя обращение к сайтам через HTTPS протокол, и препятствует атакам, связанным с понижением уровня защиты (downgrade attack).
    Для каждого домена прописывается флаг вида (true/false), но в бинарном виде и хранится в браузере долгое время.

    Эту технологию именуют так же HSTS Super Cookies т.к. она использует эти данные для определения пользователя. При этом прочитать данные HSTS можно с любого домена в отличии от Web cookie, которые доступны только тому доменному имени, который их установил.
    Иронии в том, что данная функция призвана обеспечивать безопасность в сети интернет.

    В FireFox'e эти данные хранятся в корне директории профиля браузера, в файле SiteSecurityServiceState.txt:
    По этим "цифровым отпечаткам" Вас могут идентифицировать после смены IP, очистки или отключении кук, выключенных плагинах и даже в режиме инкогнито. По умолчанию эта функция включена и не имеет никаких настроек для её блокировки.

    Решение: Очищаем и блокируем запись HSTS Super Cookie о доменах.
    Code (csharp):
    1. // Оповещения
    2. bool msgType = false; // true - выводить оповщения в лог ZP, false - не выводить.
    3. // Считываем глобальные настройки ZennoPoster, чтобы получить путь к "Trash" папке, где будет храниться всё то, что нам нужно
    4. string globalSettings = File.ReadAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"ZennoLab\ZennoPoster\5\Settings\globalsettings.settings"));
    5. globalSettings = Regex.Match(globalSettings, @"(?<=clnName>CacheCookiePath</[^<]+>(\s+)?<clnType>[^<]+</[^<]+>(\s+)?<clnValue>)[^<]+").Value;
    6. // Получаем путь к Trash папке
    7. // Формируем путь директории,где будем искать данные HSTS в профилях
    8. string dirBaseProfile = (globalSettings==@"\Trash")?string.Format(@"{0}\Trash\Profiles\", System.IO.Directory.GetParent("ZennoPoster").ToString()):string.Format(@"{0}\", globalSettings);
    9. //Кладём все найденные папки в список
    10. List<string> lst = new List<string>();
    11. // Ищем папки в профилях, созданные base.exe
    12. lst = System.IO.Directory.GetDirectories(dirBaseProfile).ToList();
    13. if (Global.Variables.IsProjectMaker) lst.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"ZennoLab\ZennoPoster\5\ProjectMaker\Browser\Debug")); // для PM
    14. project.SendInfoToLog(string.Format("Найдено папок в профилях {0}", lst.Count), msgType);
    15. string pathBase = string.Empty;
    16. // Чистим файлы в цикле для всех баз (base.exe)
    17. while (lst.Count>0) {
    18.   pathBase = string.Format(@"{0}\SiteSecurityServiceState.txt", lst[0]);
    19.   lst.RemoveAt(0);
    20.   FileInfo file = new FileInfo(pathBase);
    21.   if (file.Exists)
    22.   {
    23.   if (File.GetAttributes(pathBase).ToString()=="ReadOnly") {
    24.   project.SendInfoToLog(string.Format("Уже был заблокирован {0}", pathBase), msgType);
    25.   continue;
    26.   } else {project.SendInfoToLog(string.Format("Почищен и заблокирован {0}", pathBase), msgType);}
    27.   }
    28.   File.WriteAllText(pathBase, string.Empty);
    29.   File.SetAttributes(pathBase, FileAttributes.ReadOnly);
    30. }
    31. instance.Reload();


    Тестирование: http://www.radicalresearch.co.uk/lab/hstssupercookies



    История посещений (History API)
    Веб-сайт может получить с помощью JavaScript данные о Вашей истории посещений. А свойство "History.length" возвращает количество элементов в истории сессии, включая загруженую страницу.

    Внимание: это не общая история всех посещений Вашего браузера, а история перемещения в рамках сайта.

    Подробно: https://developer.mozilla.org/ru/docs/Web/API/History/length

    Когда и где это применять?
    1. Там где важна рандомность посещений каких-либо конкретных страниц, чтобы Ваши действия не были однотипными.
    2. Там где важно совершить определенное кол-во переходов перед совершением ключевого действия.

    Решение #1: Эмуляция посещений конкретных страниц.
    По мимо того, что мы достигаем цели оставаться анонимнымы и не привлекать лишнего внимания, данный метод несет в себе ещё и оптимизанную часть т.к. используя это решение теперь нет нужды переходить по случайным страницам* сайта и ждать их загрузки, тратя ресурсы, достаточно просто выполнить код.

    * Работает только там, где используется контроль посещений через History API. Как это определить? Чуть позже будет инструкция.

    Code (csharp):
    1. // Данное решение родилось в 7 часу вечера 23 мая.
    2. // Код появится в ближайшее время, ориентировочно завтра.
    Решение #2: Накрутить количество посещённых страниц.
    2017-05-22_15-47-49.png
    Code (JavaScript):
    1. // Данный код добавляет в History одну страницу.
    2. // В свойствах страницы (название, маркер и ссылка) указывается белеберда т.к. нам важен только факт накрутки объема истории.
    3. var text = "";
    4. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    5.  
    6. for( var i=0; i < 9; i++ )
    7.    text += possible.charAt(Math.floor(Math.random() * possible.length));
    8.  
    9. var stateObj = { marker: "id" };
    10. history.pushState(stateObj, text, text+".html");


    web-shield-32.png Связь и местоположение
    IP адрес (Прокси) - это промежуточное звено между машиной клиента и и другим интернет-сервером. То, что позволяет нам скрывать свой настоящий IP-адрес. Это если максимально сжато и вкратце.

    В разрезе обеспечения анонимности прокси бывают:
    HTTP(S) Proxy. Такие прокси-серверы пропускают через себя только HTTP-траффик, по умолчанию добавляя в передаваемый траффик данные о применении прокси;
    SOCKS'ы. В отличие от HTTP-прокси-серверов работают с высокоуровневыми протоколами: HTTP, FTP, РОРЗ и др., а не только по HTTP. Так же SOCKS передаёт всю информацию, ничего не добавляя от себя.

    При общении с другим сервером (при посещении сайта, например), клиентом (то есть нами) отсылается ряд переменных в заголовке запроса.
    REMOTE_ADDR - IP адрес клиента
    HTTP_VIA - В идеале должна быть пустой, если нам нужна анонимность. Если прокси не в состоянии обеспечить анонимность, скорее всего здесь будет его IP.
    HTTP_X_FORWARDED_FOR - Если она не пустая - это удар по Вашей анонимности. В противном случае здесь будет Ваш реальный IP.


    Рассмотрим ряд заголовков, которые могут заявить серверу случайно или намерено, что используется прокси-сервер.
    HTTP_VIA
    HTTP_X_FORWARDED_FOR
    HTTP_FORWARDED_FOR
    HTTP_X_FORWARDED
    HTTP_FORWARDED
    HTTP_CLIENT_IP
    HTTP_FORWARDED_FOR_IP
    VIA
    X_FORWARDED_FOR
    FORWARDED_FOR
    X_FORWARDED
    FORWARDED
    CLIENT_IP
    FORWARDED_FOR_IP
    HTTP_PROXY_CONNECTION

    Чтобы быть инкогнито, все эти заговки должны быть пустыми, но если в них что-то прописано, убедитесь хотя бы, что это не Ваш реальный IP адрес.
    Собственно, уровень анонимности определяется тем, сколько переменных из списка выше скрывают свои значения от сервера.

    Если с соксами всё понятно, они априори анонимны.
    То HTTP(S) Proxy могут спалить наш реальный адрес (не всегда). Они имеют следующую градацию:

    Прозрачные (Transparent). Они не скрывают Ваш реальный адрес, но они впринципе и не предназначены анонимного серфинга. Это всё равно, что выйти на улицу в трусах поверх штанов и думать, что никто не заметит.
    Анонимные (Anonymous). Сообщают, что используется прокси, но не выдают Ваш истинный IP адрес.
    Искажающие (Distorting). Так же не скрывают, что мы сидим за прокси и наш IP адрес не выдают, но в заголовки пишут случайные адреса. В общем, как повезёт.
    Элитные прокси (High anonymous / Elite). Самые достойные из набора HTTT(S) проксей. Скрывают факт использования прокси, так и наш настоящий IP адрес.

    Итак-с, движемся дальше.
    Так же стоит обезопаститься и проверить наличие наших проксей в спам-базах, например: https://www.spamhaus.org/
    А так же на принадлежности к сети TOR: https://check.torproject.org/cgi-bin/TorBulkExitList.py

    Хорошо - если отсутствует, и не очень если... ну, Вы поняли.

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

    Всё зависит от ситуации. Если Вам просто необходимо совершить разовые операции или накрутить простенькое голосование, или получить доступ к сайту - обычных прозрачных или простых анонимных Вам хватит с головой.
    Всё остальное надуманное и перерасход средств, если Вы собираетесь их приобретать.

    Тестирование: http://www.iprivacytools.com/proxy-checker-anonymity-test/

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DNS (Domain Name System) — Система для получения информации о доменах. Чаще всего используется для получения IP-адреса по имени хоста.
    Пример: При обращении к домену google.com происходит вычисление (резолвинг) IP 173.194.70.101 по этому имени.

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

    А что если зайти сразу по IP адресу (173.194.70.101)?
    И тут возможна утечка из-за запросов активных элементов на странцие сайта.

    Решение: Изменить DNS сервера в настройках сетевого подключения.
    Публичный Google DNS: https://developers.google.com/speed/public-dns/
    DNSCrypt - Поддерживает шифрование DNS запросов, а не передает их в открытом виде, которые можно перехватить, но работает этот сервис только через собственное программное обеспечение, так что налету, просто настроив DNS-серверы на сетевой карте, начать работу не получится.
    Инструкции по установке и настройке приведены на их сайте, прямо на главной странице: https://dnscrypt.org

    Тестирование: - https://www.dnsleaktest.com/
    (Нажмите на кнопку Extended)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    WebRTC (Web real-time communication) - Проект с открытым исходным кодом, предназначенный для организации передачи потоковых данных между браузерами или другими поддерживающими его приложениями по технологии точка-точка (P2P). Он входит в состав популярных браузеров Google Chrome, Mozilla и Opera.

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

    Это снижает эффективность работы через прокси или VPN.

    Решение #1: Подмена локального IP.
    Code (csharp):
    1. string proxy = "127.0.0.1"; // Укажите здесь желаемый адрес, который Вы хотите подсунуть WebRTC вместо реального (локального).
    2. instance.WebRTCWorkMode = ZennoLab.InterfacesLibrary.Enums.Browser.WebRTCMode.Emulate;
    3. instance.SetWebRTCAdresses(proxy);
    Решение #2: Выключить WebRTC.
    Code (csharp):
    1. instance.SetBrowserPreference("media.peerconnection.enabled", false);
    Тестирование: https://diafygi.github.io/webrtc-ips/ и https://browserleaks.com/webrtc

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Таймзона - зная наш IP адрес, любой интернет ресурс может получить базовую информацию о нас: страну и город, а это ещё как минимум часовой пояс. Время делится на 2 типа:
    • Локальное
    • Системное
    Если Вы работаете без прокси, можете пропустить этот подраздел, так как в этом случае нечего опасаться. В обратном случае держитесь крепче, ведь сервер вот-вот уже анализирует Ваш IP и фиксирует, что Вы сейчас во всю отрываетесь на Багамах.

    Пока сервер сдерживает свои 01001010101001 (чувства), передаёт эстафету фронтэнду, в частности JavaScript и его уже интересует Ваше системное (реальное время). Всего несколько милисекунд пройдет до момента, когда машина начнёт злорадствовать, ведь она выяснила, что на самом деле Вы - %любой плохой город%

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

    Чтобы этого избежать, необходимо подменить данные, если работа через прокси принципиальна.

    Решение #1: Подмена системного времени
    Code (csharp):
    1. instance.TimezoneWorkMode = ZennoLab.InterfacesLibrary.Enums.Browser.TimezoneMode.Emulate;
    2. instance.SetTimezone(-4,0); // Устанавливаем часовой пояс UTC -04:00)
    Решение #1.1: Автоматизированная подмена системного времени на основе Вашего IP (Прокси)
    Простая установка прокси с включенной опцией "Эмулировать часовой пояс".
    Code (csharp):
    1. string proxy = project.Variables["proxy"].Value; // В переменной proxy должен лежать прокси согласно формату protocol://ip:port или protocol://login:[email protected]:port
    2. instance.SetProxy(proxy,false,false,true); // Установка прокси с эмуляцией таймзоны на основе IP

    Получаем таймзону встроенным в ZP методом GetTimezone() с последующей эмуляцией через instance.SetTimezone()

    Code (csharp):
    1. int hours, minutes;
    2. string proxy = project.Variables["ip"].Value; // В переменной ip должен лежать только IP адрес (без протокола, порта, логина и пароля)
    3. ZennoPoster.IpTools.GetTimezone(proxy, out hours, out minutes); // Получаем таймзону прокси встроенным методом ZP
    4.  
    5. instance.TimezoneWorkMode = ZennoLab.InterfacesLibrary.Enums.Browser.TimezoneMode.Emulate; // Включаем эмуляцию
    6. instance.SetTimezone(hours,0); // Устанавливаем таймзону

    Получаем таймзону от стороннего сервиса (на примере бесплатного api.sypexgeo.net) с последующей эмуляцией через instance.SetTimezone()

    Шаг 1. Добавить директивы using: Добавить действие -> Свой код -> Директивы using и общий код.
    Code (csharp):
    1. using System.Web;
    Шаг 2. Добавить действие -> Свой код -> Ссылки из GAC.
    • Жмём "Добавить" далее ищем System.Web.dll последней версии и подходящей разрядности для Вашей ОС. Кликаем "ОК".
    • Жмём "Добавить" далее ищем System.Web.Extensions.dll последней версии и подходящей разрядности для Вашей ОС. Кликаем "ОК".
    Code (csharp):
    1. string response = String.Empty;
    2. try {
    3.    string proxy = instance.GetProxy(); // или можно подставить переменную шаблона project.Variables["proxy"].Value
    4.    response = ZennoPoster.HttpGet(
    5.        @"http://api.sypexgeo.net/", // URL
    6.        proxy, // Прокси
    7.        "UTF-8", // Кодировка
    8.        ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly // Получаем только тело
    9.      );
    10. } catch (Exception ex) {
    11.    return "Не загрузилось";
    12. }
    13. try {
    14.    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    15.    dynamic usr = serializer.DeserializeObject(response);
    16.  
    17.    instance.TimezoneWorkMode = ZennoLab.InterfacesLibrary.Enums.Browser.TimezoneMode.Emulate;
    18.    instance.SetTimezone(usr["region"]["utc"],0);
    19. } catch {return "Не удалось получить таймзону от sypexgeo";}

    Решение #2: Отключить JavaScript. Тогда никто не сможет получить Ваше системное время, но сам отключения - это уже негативный сигнал для алгоритмов деанонимизации.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UseJavaScripts = false; // Отключает JS
    Тестирование: https://whoer.net/ru
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Геолокация - Ваше точное месторасположение. То есть ресурсу будет доступен не только город, но и Ваши координаты, но это только с Вашего разрешения.

    То есть мы можем запретить определять наше местоположение, что по умолчанию вроде как и установлено. Либо подменить эти данные.

    Решение #1: Запретить определять местоположение.
    Необходимо создать кубик: Добавить действие -> Браузер -> Настройки.
    2017-05-22_02-09-20.png
    Решение #2: Подмена данных о геопозиции.
    Необходимо создать кубик: Добавить действие -> Браузер -> Настройки.
    И заполнить форму.
    2017-05-22_02-11-26.png


    fingerprint.png Отпечатки
    WebGL - это программная библиотека для языка программирования JavaScript, позволяющая создавать на JS интерактивную 3D-графику, функционирующую в широком спектре совместимых с ней веб-браузеров. WebGL - это контекст элемента canvas HTML, который обеспечивает API 3D графики без использования плагинов и выполняется на графическом процессоре компьютера.

    Как происходит идентификация? 3D графика очень платформозависима, версия драйверов, версия видеокарты, стандарт OpenGL в системе, версия шейдерного языка, — все это будет влиять на то, как внутри будет прорисовано это изображение. И после того, как оно будет преобразовано в байтовый массив - он будет уникальным.

    Решение #1: Точечное. Отключить WebGL для браузера.
    Code (csharp):
    1. instance.SetBrowserPreference("webgl.disabled", true);
    2. //instance.SetBrowserPreference("webgl.enable-webgl2", false); // WebGL 2.0 не поддерживается текущей версией движка Mozilla Firefox, используемой в ZennoPoster 5.11.1.0
    3. instance.SetBrowserPreference("webgl.disable-extensions", true);
    4. instance.SetBrowserPreference("webgl.min_capability_mode", true);

    Решение #2: Радикальное. Отключить JavaScript.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UseJavaScripts = false; // Отключает JS
    Тестирование: https://browserleaks.com/webgl

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Fingerprint Canvas - Метод идентификации заключается в том, что на скрытом Сanvas холсте рисуется определённый текст с определенными наложенными на него эффектами, которые задаются в JS скрипте на стороне сервера к которому Вы обращаетесь. После этого, как и в случае с WebGL полученный результат преобразуется в байтовый массив.

    Как я уже писал ранее (в контексте того же WebGL), всё, что связанно с графикой, очень платформозависимо и на разных машинах будет отличный друг от друга результат, не смотря на то, что задание было одно и тоже.

    Решение #1: Эмуляция с помощью штатных средств ZennoPoster.
    Необходимо создать кубик: Добавить действие -> Браузер -> Настройки.
    Далее выбрать опцию, как на скриншоте.
    2017-05-22_00-21-50.png

    Решение #2: Блокируем Canvas Fingerint.
    Необходимо создать кубик: Добавить действие -> Браузер -> Настройки.
    Далее выбрать опцию, как на скриншоте.
    2017-05-22_00-22-28.png

    Тестирование: https://browserleaks.com/canvas

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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

    То есть его уникальность зависит от настройки параметров, которые описаны в статье выше. Меняете их - меняется и отпечаток.

    Тестирование: https://hidester.com/browser-fingerprint/
    (Вам нужна строка Your browser fingerprint: *********************************)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    AudioContext Fingerprint - Основывается на проверке аудио подсистемы вашего браузера, посылая низкочастотные звуки при помощи AudioContext API.

    Данный способ снятия «звукового отпечатка» чрезвычайно эффективен в идентификации пользователей. Поговоривают, что этот способ использует и Google.

    Что можно сделать в такой ситуации?
    • Изменить битрейт.
    • Количество колонок.
    • Установить новое устройство в качестве воспроизведения.
    Решение #1: Играться с настройками звука.
    Минус на текущий момент заключается в том, что количество доступных вариаций в рамках данной машины ограничено, но это лучше чем ничего. В данный момент изучаю вопрос более детально, чтобы жонглировать этим механизмом глобально.

    Открываем панель управления воспроизведением звука.
    Переходим в "Свойства".
    2017-05-22_02-53-10.png

    И меняем там выше перечисленные параметры на свой лад.
    Что ж, чтобы Вас убедить, что это работает, держите 2 звуковых отпечатка для сравнения. Для примера изменялся только битрейт.

    24бит, 48000 Гц (Студийная запись)
    2017-05-22_02-57-07.jpg

    24бит, 44100 Гц (Студийная запись)
    2017-05-22_02-58-00.png

    Решение #2: Радикальное. Отключить JavaScript.
    Code (csharp):
    1. // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UseJavaScripts = false; // Отключает JS
    Тестирование: https://audiofingerprint.openwpm.com/

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Системные шрифты (Fonts Fingerprint)
    Когда баны розданы, а идеи кончились, все дороги начинают вести к системным шрифтам.
    С помощью Flash и\или JavaScript веб-сайт может получить список шрифтов, установленных в системе. У всех пользователей этот набор разный, что и повышает шанс деанонимизации.

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

    Решение #1: Для защиты от снятия отпечатка шрифтов, необходимо отключить Adobe Flash и\или JavaScript.
    Code (csharp):
    1. // Аналоги на кубиках находятся в "Добавить действие" -> "Браузер" -> "Настройки"
    2. instance.UsePlugins = false; // Отключает Flash, Java, Silverlight
    3. instance.UseJavaScripts = false; // Отключает JS
    Решение #2: Манипулировать списком, добавляя новые и удаляя старые.

    Шаг 1. Добавить директивы using: Добавить действие -> Свой код -> Директивы using и общий код.
    Code (csharp):
    1. using System.Runtime.InteropServices;
    2. using Microsoft.Win32;
    3. using System.Drawing.Text;
    Шаг 2. Открыть вкладку "Общий код" и после строки:
    Code (csharp):
    1. public static object SyncObject = new object();
    Добавить ниже:
    Code (csharp):
    1. public class Fonts {
    2.    [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    3.    private static extern int AddFontResource(string lpszFilename);
    4.  
    5.    [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    6.    private static extern int RemoveFontResource(string lpszFilename);
    7.  
    8.    public static void SetupFont(IZennoPosterProjectModel project, string fontName, string fontpath) {
    9.      lock(SyncObject) {
    10.        try {
    11.          // Создаём полный путь, где будет размещён наш шрифт
    12.          var fontDestination = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), fontName);
    13.          // Чекаем существование шрифта
    14.          project.SendInfoToLog(fontDestination);
    15.          if (!File.Exists(fontDestination)) {
    16.            project.SendInfoToLog(string.Format("Уставливаем шрифт {0}", fontName));
    17.            // Копируем шрифт в папку Fonts
    18.            System.IO.File.Copy(Path.Combine(fontpath, fontName), fontDestination);
    19.            // Получаем имя шрифта
    20.            PrivateFontCollection fontCol = new PrivateFontCollection();
    21.            fontCol.AddFontFile(fontDestination);
    22.            var actualFontName = fontCol.Families[0].Name;
    23.            // Устанавливаем шрифт
    24.            AddFontResource(fontDestination);
    25.            project.SendInfoToLog(string.Format("Установлен шрифт {0}", actualFontName));
    26.            // Добавляем шрифт в реестр
    27.            RegistryKey AddFont = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", true);
    28.            AddFont.SetValue(actualFontName, fontName, RegistryValueKind.String);
    29.            AddFont.Close();
    30.            project.SendInfoToLog(string.Format("Шрифт {0} ({1}) успешно установлен и добавлен в реестр", actualFontName, fontName));
    31.          } else {project.SendWarningToLog(string.Format("Шрифт {0} уже установлен в системе", fontName));}
    32.        } catch (Exception ex) {project.SendErrorToLog(ex.Message);}
    33.      } // - End - lock(SyncObject)
    34.    } // - End - public static void SetupFont
    35.    public static void DeleteFont(IZennoPosterProjectModel project, string fontName) {
    36.      lock(SyncObject) {
    37.        try {
    38.          // Путь до шрифта, который необходимо удалить
    39.          var fontDestination = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), fontName);
    40.          // Чекаем его существование
    41.          if (File.Exists(fontDestination)) {
    42.            PrivateFontCollection fontCol = new PrivateFontCollection();
    43.            fontCol.AddFontFile(fontDestination);
    44.            var actualFontName = fontCol.Families[0].Name;
    45.            // Удаляем шрифт
    46.             RemoveFontResource(fontDestination);
    47.            lock(SyncObject) {File.Delete(fontDestination);}
    48.            // Удаляем шрифт из реестра
    49.            RegistryKey RemoveFont = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", true);
    50.            RemoveFont.DeleteValue(actualFontName.ToString());
    51.            RemoveFont.Close();
    52.            project.SendInfoToLog(string.Format("Шрифт {0} ({1}) успешно удалён", actualFontName, fontName));
    53.          }
    54.        } catch (Exception ex) {project.SendErrorToLog(ex.Message);}
    55.      } // - End - lock(SyncObject)
    56.    } // - End - public static void DeleteFont
    57. } // - End - public class Fonts
    Шаг 3. Использовать код вызова установки и удаления в C# кубиках.
    Установка:
    Code (csharp):
    1. string nameFont = project.Variables["name_font"].Value; // Название файла шрифта (например, myfont.ttf)
    2. CommonCode.Fonts.SetupFont(project, nameFont, @"C:\Fonts\"); // Установка шрифта. 3-й аргумент это директория, в которой он находится.
    Удаление:
    Code (csharp):
    1. string nameFont = project.Variables["name_font"].Value; // Название файла шрифта (например, myfont.ttf)
    2. CommonCode.Fonts.DeleteFont(project, nameFont); // Удаление шрифта


    Тестирование: https://panopticlick.eff.org/results и https://browserleaks.com/fonts

    aiWHzqI.png Что ещё необходимо сделать:
    • Добавить генерацию mime-типов для плагинов. [Раздел "Набор плагинов"]
    • Сделать готовый список плагинов для массового использования
    • Обновить Решение #1 для раздела ["История посещений (History API)"]
    • Добавить больше информации по разделу ["Разрешение экрана, глубина, видимая область"]
    • Найти решение для эмуляции WebGL отпечатка
    • Автоматизировать смену Audio Context Fingerprint
    • Сделать шаблон с 1-им и 4-мя кубиками (разбитым по разделам) для удобства использования в своих проектах.
    • Эмуляция геолокации (случайных координат) в зависимости от страны прокси-сервера.
    • Автоматизированная эмуляция таймзоны в зависимости от страны прокси-сервера.
     
    Last edited: May 31, 2017
    qweeeraz, che100, indus and 134 others like this.
  2. Astraport

    Astraport Client

    Joined:
    May 1, 2015
    Messages:
    2,390
    Likes Received:
    1,515
    И вторая часть будет скоро?
     
  3. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Сделал такой префикс так как уверен, что это не вся информация по данной теме, но старался описать всё максимально подробно, но без воды, исходя из опыта.
    Как только накопится доп. информация по анонимизации, опубликую её в разделе "Внеконкурные статьи" или на 8 конкурсе, если будет такая возможность.
     
    Belwin and Знайка like this.
  4. amyboose

    amyboose Client

    Joined:
    Apr 21, 2016
    Messages:
    1,949
    Likes Received:
    783
    Если бы со шрифтами все было так легко. Например, я хочу сразу в 100 потоков работать и мне нужно, чтобы шрифт оставался постоянным на странице, но в другом потоке был другим. Придется каждый раз лочить загрузку страницы, чтобы подгрузить нужный шрифт и потом его выгрузить. Тут надо искать решение через js
     
    Alelsey1611 and Lord_Alfred like this.
  5. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Писал этот материал очень долго, так как все нужно было не только структурировать и интересно подать, но и проверить.
    Старался ориентироваться на всю аудиторию, поэтому некоторые моменты могут быть разжёваны, например, как "Что такое DNS", но особо не затягивал. Не забывайте, что у всех разный опыт в той или иной сфере, да и навыки в целом.
    Оценивайте мой, да и любой труд трезво, и максимально объективно насколько это возможно.

    Надеюсь, что всем понравится.

    Это лучше чем ничего, да и я все-таки склонен считать, что отпечаток шрифтов имеет небольшой вес в решении вопроса о блокировке или ещё чего-то страшного со стороны сайта.
    Flash может извлечь все шрифты, но его можно отключить, а за отключенный флееш плеер ещё никто не наказывал, а JS может получить только ограниченное кол-во шрифтов, так как скрипт проходится по готовому списку и просто сверяет.
     
    Last edited: May 22, 2017
    Wzor likes this.
  6. Kare

    Kare Client

    Joined:
    Dec 23, 2014
    Messages:
    478
    Likes Received:
    241
    Спасибо, эту информацию нужно добавить в зенновики :-)
    Поправьте, одинаковые значения instance.UseAdds:
     
  7. sergiksergik

    sergiksergik Client

    Joined:
    Dec 6, 2011
    Messages:
    595
    Likes Received:
    110
    Поправь
    С помощью JS владелец сайта может узнать, используется у Вас в браузере подобный механизм или же нет.
    Код (csharp):
    // Аналог на кубике находится в "Добавить действие" -> "Браузер" -> "Настройки"
    instance.UseAdds = false; // Режим показа рекламы запрещён
    instance.UseAdds = false; // Режим показа рекламы разрешён
    // Вам необходимо выбрать что-то одно и выполнить код.
     
  8. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Спасибо, исправил!
    Ночью дописывал, сказалось видимо :bm:
     
    Kare likes this.
  9. Astraport

    Astraport Client

    Joined:
    May 1, 2015
    Messages:
    2,390
    Likes Received:
    1,515
    Было бы хорошо, если бы все методы анонимизации были поданы табличкой: метод|вес. Т. е. сразу весь комплекс внедрить не всегда удобно и разумно, а вот что-то важное сделать нужно в первую очередь.
     
  10. Valiksim

    Valiksim Client

    Joined:
    Apr 14, 2012
    Messages:
    1,296
    Likes Received:
    285
    Фраза не совсем понятная. "Меньше" и "насыщеннее" - противоречие, кажется?

    За статью СПАСИБО! Шикарный подарок
     
  11. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Это будет очень субъективно.
    Да и сами ресурсы по разному расценивают полученную информацию от пользователей - кто-то очень щепетильно относится к разнице во времени (локального и системного), а другой и глазом не поведет, опустит этот момент.
    Но чтобы из-за шрифтов банили - я Вас умоляю. Не сейчас точно.
    У определенной части пользователей (если не львиной) не установлены никакие сторонние шрифты, так если ещё и флеш отключен, то будут определены только стандартные (те что предустановлены в системе). Получается, что у этой части юзеров будет один и тот же слепок фонтов.
    Опечатался и неправильно сформулировал. Переписал, благодарю за наблюдательность!
    И спасибо за спасибо :-)
     
    Dmffmd and Valiksim like this.
  12. Astraport

    Astraport Client

    Joined:
    May 1, 2015
    Messages:
    2,390
    Likes Received:
    1,515
    Мне кажется 90% банов в соц. сетях либо за жалобы, либо за нарушение лимитов, либо за использование заюзанных прокси.
    Вот скажите, если я поднял на своем VPS прокси-сервер и работаю через него, допустим FB может определить что я работаю именно через прокси, а не напрямую с локального компьютера или телефона через Wi-Fi?
    Сколько нормальных юзеров сидит через прокси? Единицы. И поэтому, само использование любых прокси, это уже большой минус в карму. Ещё немного и бан.
     
    Alelsey1611 and Rocketmedia like this.
  13. arhip1985

    arhip1985 Client

    Joined:
    Oct 31, 2011
    Messages:
    2,455
    Likes Received:
    515
    толково) меня порадовала статья
    вторая часть будет востребована.
     
    Valiksim likes this.
  14. Valiksim

    Valiksim Client

    Joined:
    Apr 14, 2012
    Messages:
    1,296
    Likes Received:
    285
    Это да!

    К этой статье ещё бы рекомендации общего плана, типа: "Как прожить и не работать", то есть, картину в целом описать, общим взглядом или взглядом сверху. Или, иными словами, сделать обобщение
     
  15. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    В статье есть ответы на Ваши вопросы :-)
    Если вкратце: если используется тип прокси HTTP Elite или Socks5, то определить, что Вы находитесь за прокси-сервером можно только через утечку (WebRTC, Flash и др.)
    Или аппаратно (через другое приложение, например, но не через браузер).

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

    Основываюсь только на своем опыте и информации по данному направлению в интернете.
    Возможно, я ошибаюсь.

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

    Спасибо :-)
    Не понял, что Вы имеете ввиду. Переформулируйте, пожалуйста.
     
    LaGir, White trash and SHoro like this.
  16. samsonnn

    samsonnn Client

    Joined:
    Jun 2, 2015
    Messages:
    843
    Likes Received:
    443
    отличная статья, мой голос - ваш)
     
    DenisK likes this.
  17. AZANIR

    AZANIR Client

    Joined:
    Jun 9, 2014
    Messages:
    243
    Likes Received:
    96
    Ух круто реально круто , с какой версии и далее данное решение работает отпишите пожалуйста.
     
    Kare likes this.
  18. stanar

    stanar Client

    Joined:
    Dec 19, 2015
    Messages:
    294
    Likes Received:
    149
    Отлично.
     
  19. Geograph

    Geograph Client

    Joined:
    Feb 16, 2014
    Messages:
    141
    Likes Received:
    67
    Отличная статья [​IMG]
    Не помешал бы еще в конце шаблон из одного кубика C#, реализующий сразу все техники :-)
     
  20. avtorco

    avtorco Client

    Joined:
    Jun 6, 2016
    Messages:
    13
    Likes Received:
    1
    Вот это здорово. Наконец кто-то комплексно и серьёзно взялся за наболевшую тему.
     
    Vik89 likes this.
  21. Danny

    Danny Client

    Joined:
    Sep 29, 2014
    Messages:
    683
    Likes Received:
    138
    Большое спасибо за действительно полезную статью!

    Раз здесь зашел разговор, то хотел бы уточнить, как для таймзон задать часовой пояс в виде переменной?
    Т.е. чтобы вместо "-4,0" была переменная. Пробовал стандартно как в C# (хотя в нем не шарю особо) - project.Variables["time"].Value; - но что-то не работает.


    И еще по поводу Dnscrypt:
    https://dnscrypt.org/#dnscrypt-proxy
    это будет общий днс для всех запущенных потоков?

    Заранее спасибо.
     
    Last edited: May 22, 2017
  22. Борат Сагдиев

    Борат Сагдиев Пользователь

    Joined:
    May 9, 2017
    Messages:
    61
    Likes Received:
    36
  23. arhip1985

    arhip1985 Client

    Joined:
    Oct 31, 2011
    Messages:
    2,455
    Likes Received:
    515
    и при чём??))
     
  24. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Спасибо!

    Сделаю чуть позже :-)

    Code (csharp):
    1. int time = Convert.ToInt32(project.Variables["time"].Value);
    2. instance.TimezoneWorkMode = ZennoLab.InterfacesLibrary.Enums.Browser.TimezoneMode.Emulate;
    3. instance.SetTimezone(time,0); // Устанавливаем часовой пояс UTC -04:00)
    Да, DNS устанавливается для текущего сетевого подключения.
     
    Danny likes this.
  25. doc

    doc Client

    Joined:
    Mar 30, 2012
    Messages:
    6,251
    Likes Received:
    2,881
    очень знакомый код по генерации юа и разрешения экрана)
     
  26. Porosenok

    Porosenok Client

    Joined:
    Sep 26, 2010
    Messages:
    1,047
    Likes Received:
    53
    Супер, особенно кусок кода для генерации юзерагентов порадовал. А я все по-простому делаю, из таблицы беру.
    Скажите, а там реальные юзерагенты генерируются?
     
  27. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Я понял о чём речь.
    До того, как столкнулся с твоим сниппетом, у меня тоже был похожий механизм генерации Useragent'a и разрешения, но мне понравилось, как ты хранишь списки билдов (Dictionary <string, string>) и разрешений экрана (int[,]) - позаимстовал.
    Надеюсь, не против? :-) (передал тебе привет в сниппетах)
    В остальном они просто похожи, там особо и не извратиться - большинство конструкций статичны и логичны.
    Да, по всем стандартам :-) Можете смело использовать.
     
    Roman* likes this.
  28. Lord_Alfred

    Lord_Alfred Client

    Joined:
    Oct 9, 2015
    Messages:
    2,428
    Likes Received:
    1,977
    Не хочу придираться, т.к. статья вроде бы достойная, но.. код сами писали?


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


    - 17 и 40 откуда взяли? На разных версиях Windows - эти значения различаются.


    - всегда 24, см.: https://developer.mozilla.org/en-US/docs/Web/API/Screen/colorDepth


    Также, при изменении размеров окна - следует выполнять instance.SetWindowSize(Width, Height)


    Чтобы корректно эмулировать плагины - нужно обязательно включить возможность их отображения + предварительно скрыть зенкой системные плагины.

    Не советую эмулировать отличное (большее) количество ядер в системе, т.к.:
    а) это возможно спалить
    б) крупные сайты (вроде fb, g, vk) могут использовать этот показатель, чтоб асинхронно запускать js-воркеры, поэтому могут возникнуть проблемы.


    - почему оно должно вернуть 1.5, если установили 150?..




    Решение не отображено в полной мере, здесь добавляется всего лишь 1 случайная страница, и то скорее всего некорректно.



    - (про шрифты) - я бы не стал использовать предложенный метод, т.к. он напрямую обращается к реестру и удаляет/добавляет оттуда шрифты. Это чревато тем, что можно получить Win98 из Win10 (имхо). Тут нужен жирный дисклеймер и более подробное объяснение как это всё запустить во многопотоке.




    Да, при желании - может. IP-адрес будет серверный и выдан конторе, которая занимается продажей серверов.
     
    Last edited: May 22, 2017
    Andrew Shell, Wzor, kagorec and 2 others like this.
  29. ibred

    ibred Administrator

    Joined:
    Apr 4, 2015
    Messages:
    1,835
    Likes Received:
    1,361
    Всё выбирается правильно. Разрешений в списке 17, но Length вёрнет 32, для этого и нужно деление на 2.

    Эти строки добавлены для примера. Не стояло цели сделать русскоязычный UA.
    UPD: В сниппет добавлен уточняющий комментарий.

    Измерил размер своей панели и проверил по whoer'y для достоверности.

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

    Размер окна не меняется, изменяется только масштаб.

    Не знал, что с этим есть проблемы технического характера. А почему нужно обязательно скрыть системные (виртуальные не дружат с реальными)?

    А) Это никак не спалит т.к. в сниппете установлен лимит 8. А это вполне нормальный показатель, у меня такой процессор в ПК стоит, который я покупал 4 года назад.
    Б) Предполагаю, что это влияет на нагрузку железа? Буду иметь ввиду.

    Вёрнет не сниппет, а JS скрипт, который будет получать информацию о Вас. Некорректно выразился, подправлю.
    UPD: В сниппет добавлен уточняющий комментарий.

    Давайте начнём с того, что это пример :-) Я думаю, что каждый в состоянии сам загнать JavaScript кубик в цикл.
    В данном примере важен факт количества, что касается корректности - добавляется все верно, но белеберда, вместо названий страниц случайный набор символов, но это не играет роли.
    UPD: В сниппет добавлен уточняющий комментарий.

    У меня не было никаких проблем с этим, хотя и тест был не продолжительным.
    Думаю, что лок решит проблему, чуть позже отредактирую пост.
     
    Last edited: May 22, 2017
    AlexGoodWeb and Valiksim like this.
  30. doc

    doc Client

    Joined:
    Mar 30, 2012
    Messages:
    6,251
    Likes Received:
    2,881
    @ibred, всё в порядке)

    в чём же неправильность?
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 1)