Как снять в̶и̶т̶а̶л̶и̶н̶у̶ ̶д̶л̶я̶ ̶д̶у̶г̶л̶а̶с̶а̶ fingerprint и нахуя он вообще нужен
Для многих не секрет, что при входе на форум, бас ласково и нежно снимает с вас фингер. Я решил разобраться, как именно он это делает спиздить код себе и раскрыть все его грязные секретики.
Не люблю долгие вступления, начнем сразу с практики, с форума, это вроде как основной источник фингеров для бас.
И так, первое что можно увидеть - отправку фингера на сервер баса.
Запрос улетает с фикс хэдерами.
Точку входа нашел через "Инициатор"
Ответ пишет в фп. Чё это за фп, на деле хуй поймешь
Раз эта шифрованная хуйня с сервера не base64, то и хуй с ним..
Начнем сначала
При входе на сайт он тянет js код на снятие фингера. Что примечательно, тут другой субдомен, не такой как у платного сборщика, да и код на самом деле чуть другой.
Обычный код вызова запуска сбора фингера
<script src="//customfingerprints.bablosoft.com/clientsafe.js"></script>
<script>document.addEventListener("DOMContentLoaded", function(){ProcessFingerprint(false, "88005553535")})</script>
В момент стягивания фингера на форуме отображается уведомление "новый софт для работы с отпечатками", иронично, что юзер который это видит (а точнее его отпечаток) и станет основой для оного софта)
После вызова процесса сбора фингера, улетает запрос (функция receiveMessage), который и присылает код для активации сбора.
Тоесть он прост чекает тайминг в локалсторедж, давно ли был сбор. Кстати, для юзеров кастом сервера это вроде как становится проблемой, ведь если юзер зашел, а потом перезагрузил страницу (прерывая тем самым сбор), метка ставится и второй (на деле первый полноценный) раз сбор уже не начинается.
И так, если всё заебок, то улетает запрос и прилетает ответ, что активирует сбор. Не видел ни где раньше юз postMessage. Пример XSS.
Также получаем набор, для которого над заготовить канвасы и готовим их.
Кастуем магию промисов и собираем всю хуйню для фингера в 1 jsonчег.
Кстати, в регере маил ру я занимался вот такими извращениями с регулярками, чтобы спиздить sec хэдеры.
Оказывается их можно прост дернуть из useragentdata
Дальше сборщик прост шлет фингер на сервер баса, кстати в том числе с теми самыми канвасами. Более того, он потом еще раз зачем-то считает те же самые канвасы и уже через сокет отправляет.
А че делать с этим говном, я так и не придумал
Подготовка окончена
Так как ProcessFingerprint чекал какие-то настройки, а ProcessFingerprintInternal выполнял сразу то что нужно, я прописал именно его.
Тем более, на форуме ProcessFingerprint как раз выглядел как ProcessFingerprintInternal
2) сразу запись фингера в поле
3) сразу поставил тянуть фингер
Акей, фингер собирается, теперь почекаем и сравним с фингером с сервера баса и посмотрим шо таки собирают.
Слева мой сборщик, справа бас отпечаток с сервера.
Тоесть вот эта вся ебень из дефолт инфы браузера, которую насобирал бас сборщик фингера и есть отпечаток. У каждого браузера эта хуйня своя и часть параметров уник. Более того, оно еще и инфу помимо браузера палит.
И по отдельности эт все херня, ни кому не всрался какой-то вася с большим экраном, а вот всё вместе это уник отпечаток и можно вычислить конкретного чела.
1) Где lang, ua, orientation, headers, connection?
2) Что за алгоритм шифрования у строк: audio, battery, canvas, webgl, rectangles?
Начнем по порядку.
Когда мы меняем чет в дефолт функционале браузера присваивая свои значения, то вместо старых привязок (натив кода) он будет теперь ссылаться на новый (наш js) код, что можно спалить.
Вот, если чекать патченую инфу, то у её дефолтных функций значения станут хуйней, поэтому эти функции мы тож патчим. Да, патчим только то что обычно чекают)
Все эти данные хранятся в dat, он кстати сразу с манкипатчем идёт.
Выглядит как то что надо, но судя по доке отличается от Accept-Language порядком q, так что скорее всего оно из запроса тянется на сервере. Особенно, учитывая демо линку https://fingerprints.bablosoft.com/lang
Тем не менее, так как Accept-Language: ru-RU,ru;q=0.9, список языков тот же, что и вертает window.navigator.languages
, думаю там прост парс языков и числа по убыванию от 0.9, до 0.5 тоже прокатит.
А headers наверное просто кастомный, в сборе фингера я его не увидел.
А вот хуй знает. Просчитанные канвасы декодятся как хекс, а та инфа, которая в бас фингере в строках audio, battery, canvas, webgl, rectangles не декодится (возможно это просто хэш).
function EncodeHex(str){var hex = '';for(var i=0;i<str.length;i++) {var add = str.charCodeAt(i).toString(16);if(add.length == 1){hex += '0';}if(add.length == 0){hex += '00';}hex += add;}return hex}
function DecodeHex(a) {var e = new Uint8Array(a.match(/.{1,2}/g).map((a=>parseInt(a, 16))));return (new TextDecoder).decode(e)}
Но наверное эт не сильно важно, в итоге каждый сайт сам решает на каких данных и чем считать хэш. Тут например md5.
На субдомене баса по фингерам можно почекать как они работают (F12)
- canvas (canvas) https://fingerprints.bablosoft.com/canvas
- webgl (canvas) https://fingerprints.bablosoft.com/webgl
- audio https://fingerprints.bablosoft.com/audio
- battery https://fingerprints.bablosoft.com/battery
- lang https://fingerprints.bablosoft.com/lang
- headersorder https://fingerprints.bablosoft.com/headersorder
PS: Добавил в сборщик рассчитанные канвасы
Думаю, рассчитанные канвасы бас может подменять запатчив toDataURL. Например, чекаем итоговую картинку по базе и меняем на нужную, если такая есть.
В любом случае, код для расчета имеется, а если не пойдет, всегда можно спиздить с желаемого сурса.
Кстати, в старых версиях, вроде 23.2.2, был еще параметр payload, в котором хранился манкипатч для фингера. Подозреваю, что он просто применял этот код и так пытался зачистить следы патча своими значениями.
В engine.js модуля FingerprintSwitcher можно увидеть, как он передает патч после установки фингера
Кстати, забавный Древний кек по палеву баса
Смысол
А собственно, на этом и строится весь фрод по отпечаткам.
Тоесть сайт собирает с юзеров такими же методами данные и шлет себе в нейронку, которая пытается найти корреляции бот не бот.
Но на самом деле, все разрабы ленивые жёпки и юзают прост готовые решения
Вот, например, презентация от яндекса с объяснением принципа работы их либы https://youtu.be/xl1fwCza9C8, которую многие юзают как основу фрода. Закинул дохуя фингеров, пусть оно само там разбирается бот или не бот.
Маил ру, как не трудно заметить, так и поступил https://youtu.be/by9vFMOqnfc
Пример, как это использовано в антифроде банка https://link.medium.com/lpnzTBOcm8
А для сбора фингеров можно взять за основу примеры из открытых либ типо fingerprintjs и creepjs
Вот и получается, отреверсил сурсы вафки, капчи или чего еще, понял, что ей нужно, подсунул или поставил сбор. Ниже пару примеров.
Бас пытается запихать в фингер все популярные защиты, а не под конкретный сурс, что по итогу раздувает файлы фингера.
Хотя, как сказал великий древнегреческий философ
Вот мы и разобрались, что такое фингеры, как их снять и при чем тут манкипатч
И вот тут возникает вполне резонный вопрос: А как бас чекает фингеры ботов?
Учитывая выше сказанное, я решил ещё раз внимательно почекать сурсы сборщика фингера. Каких-то защит на клиенте я не нашел (мож эт я конечно плохо искал), что наводит на мысли об отсутствии там оных. Ну нет и нет.
Наверное, у баса на серверной стороне много всяких защит и собранные плохие фингеры ни куда не попадут
Судя по форуму, у баса столь хорошего антибота пока нету, но какой-то таки есть.
На самом деле, вопрос довольно сложный и интересный, ведь чтобы ботами наебать антифрод против ботов, нужно самому написать антифрод против ботов, чтобы не собирать отпечатки ботов, чтобы на них потом делать ботов и их не палили другие антиботы. И это очень забавно. А потому не мудрено, что в базе баса наверняка овердохуя бот фингеров например челов с басом.
Чтобы обойти фрод отпечатков, у баса самого фрод отпечатков должен быть как минимум не хуже, чем у тех кого нужно наебать. Либо, придется идти по стопам великого философа, что выглядит самым разумным на текущий момент.
Экзотика
Метод брута авториза в соцках выглядит грубым, но при грамотном использовании мог бы стать очень полезным) Например чекать у юзера авториз в гугле.
POC: https://browserleaks.com/social#protection
Source: https://github.com/RobinLinus/socialmedia-leak
Если я правильно помню, за эффективность этот метод признали незаконным, а еще он вроде как помогал следить за юзерами tor (но это не точно)
Source: https://github.com/jonasstrehle/supercookie
JA3 и другие отпечатки запросекаф
На самом деле, за последние пару лет этот метод перестал уже быть экзотикой и стал классикой, юзается всем топ бигтехом, а тем более вафками (waf)
POC: https://tls.peet.ws/api/all
Source: https://github.com/FoxIO-LLC/ja4
- C++ https://github.com/lwthiker/curl-impersonate самая норм либа
- NodeJS https://github.com/apify/got-scraping
- Python https://github.com/yifeikong/curl_cffi основанный на https://github.com/lwthiker/curl-impersonate
- GO https://github.com/Danny-Dasilva/CycleTLS более юзерфрендли
- GO https://github.com/wangluozhe/requests не тестил, но выглядит более надёжно, особенно учитывая количество и скорость обнов, а также перечинь методов детекта запросов, которые либа обходит
Мнение
БОльшая часть антифрода на сайтах до сих пор, на самом деле, строится чисто на трасте прокси, а иногда и рег данных (например мыло), все остальное скорее бонусы, но не исключено, что где-то важен онли фингер или он влияет сильнее.
В любом случае, хорошие прокси нивелируют хуевый отпечаток браузера, а наоборот это не работает. Тем более, что методов детекта хуева туча и просто 1 фингером баса все это не предусмотреть.
*Разумеется, я тут не учитываю методы детекта юза прокси, коих не мало, начиная от http3 через quick, заканчивая пингом у websocket через браузер. Даже для снятие фингера с запросов появилось много новых методов (китайская репа)
Эта статья скорее для того, чтобы понимать, что палится, где искать, и как это всё на самом деле работает.
Лучше всего, имхо, таки собрать 1 фингер айфона под фрод конкретного сайта, чем дохуя из базы баса.
Ответы на вопросы:
- Чё за методы детекта прокси?
Quic https://cloudflare-quic.com/ обсуждение на форуме
Latency Test (пинг между http и websocket) и всякая всячина1 https://proxy.incolumitas.com/proxy_detect.html обсуждение на форуме
Всякая всячина2 https://networktest.twilio.com/ обсуждение на форуме
Фингер портов localhost через websocket обсуждение на форуме
TTL обсуждение на форуме
- Ещё раз, как блять работает фингер?
Говоря простыми словами, в браузере уже есть прописанные свойства и они указаны в переменных. Мы можем скриптом спиздить у какого-нибудь юзера их из браузера и просто присвоить им новые значения в своём.
А вот это уже интересно. Браузер, эт программа с кучей всяких либ и js. Чтобы в браузере можно было рисовать картинки существует api canvas. Очень удобным оказалось, что рисование 1 и той же картинки в канвасе, на разных экранах, разном железе, в итоге приведет к разным картинкам. Тоесть смысол был в том, чтоб на каждом ведре картинка не была хуйней, но появилась вот такая фича. Для рисования доступно разное апи, для 2д, для 3д, что приводит к еще нескольким фингерам (2d, webgl, webgl2). А благодаря WEBGL_debug_renderer_info можно просто так взять и узнать видеокарту в 3 строки кода. В доке баса неплохое объяснение.
- Как мне снять свой фингер под бас?
Найти чела/купить самому с кастом сервером и фингер ключом. Зайти на его сайт и попросить потом скинуть фингер.
Так как audio, battery, canvas, webgl, rectangles не декодится, можно попробовать снять моим скриптом поменять все кроме этих значений в каком-нибудь фингере, но це чревато баном на сайте, тк я не ебу че бас там пошифровал.