در تاریخ ۲۰ اوت ۲۰۲۶، توسعهدهنده مت کالاهان (وبلاگ laserphile) تجزیه و تحلیل یک باگ عجیب را منتشر کرد: هدفونهای بلوتوثی او با multipoint از کامپیوتر به تلفن سوئیچ نمیشدند. هر بار که تب AliExpress باز میشد. او حدس نزد - او APIهای مرورگر را ابزارسازی کرد و دید که درون صفحه چه اتفاقی میافتد. مشخص شد که دو اسکریپت مبهم از استک ضد تقلب Alibaba از طریق صدایی که هیچکس نمیشنید، زمینه صوتی را بالا میبرد و اثر انگشت دستگاه را ثبت میکند.
این یک تصویر ایدهآل از آن چیزی است که تقریباً هیچکس قبل از تنظیم پروفایلها یا راهاندازی پارسر انجام نمیدهد: به استک شناسایی سایت نگاه نمیکند و آن را حدس میزند. در زیر - یک روش عملی برای ثبت نقشه شناسایی یک سایت خاص با دستان خود، در یک ساعت، بدون معکوسسازی obfuscation و بدون خدمات پولی.
چرا باید نقشه شناسایی را ثبت کنیم
چرخه معمولی به این شکل است: حسابها مسدود میشوند - تنظیمات مرورگر ضد شناسایی را به طور تصادفی تغییر میدهیم - پروکسیها را تغییر میدهیم - دوباره مسدود میشوند. بین «مسدود شدن» و «تنظیمات» هیچ دادهای وجود ندارد: مشخص نیست که سایت دقیقاً چه چیزی را میخواند و در کدام لایه آن را شناسایی میکند.
نقشه شناسایی این شکاف را پر میکند. این یک لیست است: کدام فروشنده حفاظت وجود دارد، کدام اسکریپتها آن را پیادهسازی میکنند، کدام APIها را لمس میکنند و نتیجه کجا میرود. سپس مشخص میشود که واقعاً نقطه ضعف کجاست - در IP، در اثر انگشت شبکه یا در لایه سختافزاری مرورگر. این برای سه گروه مخاطب به یک اندازه مفید است:
- چند حسابی - درک اینکه بر اساس کدام سیگنال پروفایلها به هم چسبیده میشوند. IP آنها متفاوت است، اما استک صوتی، رندرکننده WebGL و hardwareConcurrency اغلب برای کل فارم یکسان هستند.
- خزیدن - درک اینکه آیا اساساً باید مرورگر را بالا ببریم یا این کار با یک کلاینت HTTP با اثر انگشت TLS صحیح انجام میشود.
- حریم خصوصی - دیدن اینکه دقیقاً فروشگاه یا سرویس چه چیزی درباره دستگاه شما جمعآوری میکند به جز کوکیها.
مرحله ۱. شناسایی فروشنده حفاظت از طریق شبکه
اولین کاری که انجام میدهید این است که DevTools را در تب Network باز کنید، صفحه را بارگذاری کنید و هدرها و کوکیهای اولین سند را مشاهده کنید. نشانههای شناسایی شناخته شده و پایدار هستند:
CF-RAYدر هدرهای پاسخ و کوکیcf_clearance- Cloudflare.- کوکی
_abckو اسکریپت با تابعbmak- Akamai Bot Manager. - متغیرها و کوکیها با پیشوند
_px- PerimeterX (HUMAN). - کوکی
datadomeو یک JS جداگانه از دامنه فروشنده - DataDome. - کد خالی
429بدون بدنه پاسخ - امضای مشخص Kasada.
اگر با دست تنبل هستید، ابزارهای شناسایی باز مانند microlinkhq/is-antibot (بیش از ۳۰ ارائهدهنده) و افزونههای شناسایی مرورگر برای بیش از ۲۶ فروشنده وجود دارد. آنها یک پاسخ سریع اولیه ارائه میدهند، اما به سوال اصلی پاسخ نمیدهند - دقیقاً چه چیزی در مرورگر شما اندازهگیری میشود. برای این باید به جلو بروید.
مرحله ۲. استخراج لیست اسکریپتهای مشکوک
Network را بر اساس نوع JS فیلتر کنید و همه چیزهایی را که از دامنه اصلی بارگذاری نمیشوند یا در دایرکتوریهای خدماتی قرار دارند، یادداشت کنید. در مورد AliExpress، این دو فایل با مسیرهای خدماتی واضح بودند:
assets.aliexpress-media.com/g/AWSC/uab/1.140.0/collina.jsassets.aliexpress-media.com/g/AWSC/fireyejs/1.231.67/fireyejs.js
نشانههای اسکریپت ضد تقلب: کد obfuscated، نسخه در مسیر، زیر دامنه جداگانه برای استاتیک، عدم وجود هرگونه ارتباط با بخش بصری صفحه. نیازی به باز کردن و خواندن obfuscation نیست - در مرحله بعدی اسکریپت خودش درباره خودش صحبت خواهد کرد.
مرحله ۳. ابزارسازی fingerprint-API
این هسته روش است و دقیقاً همان کاری است که کالاهان انجام داد: او سازنده AudioContext و AudioNode.prototype.connect() را دور زد و سپس دو زمینه صوتی زنده را در صفحه دید که هیچ عنصر رسانهای و هیچ فراخوانی play() وجود نداشت.
منطق ساده است: شما متد مورد نظر خود را با پوشش خودتان جایگزین میکنید که فراخوانی را با استک ثبت میکند و کنترل را به اصل منتقل میکند. استک فراخوانی نشان میدهد که کدام اسکریپت دقیقاً API را فراخوانی کرده است. قرار دادن چنین اسنیپتی راحتترین کار از طریق DevTools Sources → Snippets یا از طریق افزونهای است که کد را در document-start اجرا میکند - مهم است که قبل از بارگذاری اسکریپت ضد تقلب انجام شود.
حداقل مجموعهای از تلهها که اکثر سیگنالها را پوشش میدهد:
HTMLCanvasElement.prototype.toDataURLوgetImageData- اثر انگشت کانواس.WebGLRenderingContext.prototype.getParameter- مدل کارت گرافیک و درایور، دقت شیدرها.AudioContext/OfflineAudioContextوAudioNode.prototype.connect- اثر انگشت صوتی.- گترهای
navigator.hardwareConcurrency،navigator.deviceMemory،navigator.plugins،navigator.webdriver. RTCPeerConnection- WebRTC و آدرسهای محلی.screen.width/height،devicePixelRatio،Intl.DateTimeFormat().resolvedOptions()- صفحه و منطقه زمانی.navigator.mediaDevices.enumerateDevices- لیست دستگاههای صوتی و ویدیویی.
در پایان، شما لیستی خواهید داشت: کدام یک از این APIها واقعاً فراخوانی شدهاند، چند بار و توسط چه کسی. در مورد مورد تجزیه و تحلیل شده، اسکریپتهای Alibaba کانواس و toDataURL، رندرکننده WebGL و دقت شیدرها، صدا از طریق نوسانساز و آنالایزر، اندازههای صفحه و devicePixelRatio، hardwareConcurrency و deviceMemory، پلاگینها، پشتیبانی از کدکها، WebRTC، زمانهای عملکرد، الگوهای حرکت ماوس و لمسها، حسگرهای حرکت دستگاه و ویژگیهای نشانگر اتوماسیون را لمس کردند.
صوتی که گراف انجام میداد
مفید است که بفهمید اندازهگیری چگونه به نظر میرسد تا آن را در مکانهای دیگر شناسایی کنید. گراف به این شکل بود: نوسانساز دندانهدار → AnalyserNode → ScriptProcessorNode، که نتیجه تحلیل را میخواند → GainNode با تقویت صفر → destination. صدایی وجود ندارد، بلندی اهمیتی ندارد - آن به سادگی وجود ندارد. اما اتصال به destination، به گفته نویسنده، باعث میشود مرورگر به طور فعال گراف را پردازش کند، اگرچه بلندی نهایی برابر با صفر است. این دقیقاً مسیر صوتی زنده بود که مسیر بلوتوث را باز نگه میداشت و سوئیچ multipoint هدفونها را خراب میکرد.
تفاوتها در پردازش این سیگنال به پردازنده، سختافزار صوتی، سیستمعامل، مرورگر و درایورها بستگی دارد - از این رو یک شناسه پایدار که تغییر IP و پاکسازی کوکیها را تحمل میکند. تجزیه و تحلیل دقیق این لایه و تنظیم پروفایلها برای آن - در مقالهای درباره حفاظت در برابر Audio Context Fingerprinting.
مرحله ۴. ضبط ارسال نتیجه
جمعآوری بدون ارسال بیمعنا است، بنابراین مرحله بعدی - پیدا کردن اینکه اثر انگشت جمعآوری شده به کجا میرود. Network را بر اساس XHR/Fetch فیلتر کنید و به طور جداگانه درخواستهای نوع ping را مشاهده کنید - اینها توسط navigator.sendBeacon تولید میشوند، که اسکریپتهای تلمتری آن را دوست دارند، زیرا او از صفحه خارج میشود.
تقریباً همیشه مفید است که fetch، XMLHttpRequest.prototype.send و navigator.sendBeacon را به طور اضافی بپوشانید - در این صورت شما بدنه درخواست را قبل از اینکه برود، خواهید دید. آماده باشید که محتوا سریالیزه و رمزگذاری شده باشد: در مورد AliExpress، دادهها قبل از ارسال به تلمتری Alibaba رمزگذاری شدند. اما حتی به این شکل شما دو واقعیت را دریافت میکنید: آدرس گیرنده و زمان ارسال نسبت به اقدامات شما.
اگر سایت نه تنها در مرورگر، بلکه از طریق برنامه موبایل یا کلاینت جداگانه کار میکند، همان سوال در سطح ترافیک حل میشود، نه DOM - روشهای ضبط و تجزیه در تجزیه و تحلیل بازرسی ترافیک از طریق mitmproxy توصیف شده است.
مرحله ۵. مقایسه نقشه با پروفایل خود
اکنون شما لیستی از سیگنالهایی دارید که سایت واقعاً میخواند. باقیمانده این است که بررسی کنید پروفایل کاری شما چه چیزی را بر اساس این سیگنالها ارائه میدهد. ترتیب به این شکل است: مقادیر را در مرورگر عادی ثبت کنید، سپس در هر پروفایل ضد شناسایی و مقایسه کنید.
دو چیز به طور همزمان مهم است: مقادیر باید بین پروفایلها متفاوت باشند و درون یک پروفایل بین جلسات پایدار باشند. پروفایلی که اثر انگشت آن در هر بار اجرا تغییر میکند، برای ضد تقلب به اندازه کافی مشکوک به نظر میرسد، مانند ده پروفایل با اثر انگشت یکسان.
به طور جداگانه بررسی کنید که آیا جایگزینی واقعاً در لایه مورد نظر وجود دارد. در اینجا پراکندگی بین مرورگرها قابل توجه است: Firefox از نسخه ۱۱۸ خروجی ثابت WebAudio را ارائه میدهد و بر اساس دادههای تجزیه و تحلیل ۹۹.۲۴٪ کاربران به سه مقدار کاهش مییابند؛ Brave دادههای تصادفی را اضافه میکند و از ۲۲ اوت ۲۰۲۶ به طور خاص این اسکریپتهای AliExpress را مسدود میکند و یادآوری میکند که حفاظت در برابر اثر انگشت صوتی به طور پیشفرض بیش از شش سال است که در آن وجود دارد؛ Safari خطاهایی را به بافرهای صوتی اضافه میکند؛ Chrome هیچ حفاظتی ندارد.
چالشها
- اسکریپت قبلاً کار کرده است. مسدود کردن فایل اثر انگشت صوتی ایجاد شده را از بین نمیبرد - نویسنده به وضوح اشاره میکند که تبهای باز باید بسته شوند. این همچنین شامل ابزارسازی شما میشود: اگر پوشش بعد از اسکریپت قرار گیرد، شما هیچ چیزی نخواهید دید.
- مسدود کردن عملکرد را خراب میکند. استک ضد تقلب اغلب برای چیزهای قانونی - احراز هویت، پرداخت، حفاظت ضد ربات از سوءاستفاده واقعی پاسخ میدهد. ثبت نقشه شناسایی و حذف اسکریپتها دو کار متفاوت است؛ دومی سایت را خراب میکند.
- نسخه شناسایی یکی نیست. استک ممکن است بر اساس جغرافیا، نوع دستگاه و گروه A/B متفاوت باشد. ثبت نقشه از آن IP و آن دستگاه که واقعاً با آن کار میکنید، منطقی است، در غیر این صورت شما یک پیکربندی دیگر را توصیف میکنید.
- خود ابزارسازی شناسایی میشود. متدهای بومی بازتعریف شده
toStringصحیح را از دست میدهند و دیباگر متصل ردپاهایی را باقی میگذارد. برای شناسایی این موضوع بحرانی نیست، اما پروفایل شناسایی را با پروفایل عملیاتی اشتباه نگیرید - تکنیکهای پنهانسازی اتوماسیون در راهنمای پنهانسازی مرورگر headless توضیح داده شده است.
چه پروکسی برای نتیجه نیاز است
نتیجه عملی اصلی از چنین نقشهای تقریباً همیشه یکی است: IP فقط لایه اول است و قبل از سایر لایهها بررسی میشود. اگر استک ضد تقلب در مرحله درخواست آدرس هاستینگ را ببیند، به گراف صوتی و کانواس نمیرسد - شما یک چالش یا خروجی خالی دریافت میکنید و در حال تعمیر چیز نادرست هستید.
بنابراین منطق انتخاب به این شکل است. برای سایتهایی با استک جدی (Akamai، DataDome، PerimeterX، توسعههای داخلی سطح Alibaba) پایهای پروکسیهای مسکونی هستند - آدرسهای ارائهدهندگان واقعی که در اولین فیلتر قطع نمیشوند. برای برنامههای موبایل و سایتهایی که مخاطبان اصلی آنها با گوشیهای هوشمند هستند، پروکسیهای موبایل به پروفایل طبیعی نزدیکتر هستند: CGNAT اپراتور آدرس را به طور ذاتی بین چندین کاربر زنده تقسیم میکند.
و برعکس نیز درست است: اگر نقشه نشان داد که سایت فقط به هدرها و کوکیها محدود میشود و اثر انگشت JS سنگین وجود ندارد، - فارم مرورگری اضافی است، این کار با یک کلاینت HTTP معمولی و آدرسهای دیتاسنتر حل میشود.
نتیجهگیری
مورد هدفونها به خودی خود به خاطر اثر انگشت صوتی ارزشمند نیست - این موضوع سالهاست که شناخته شده است. روش ارزشمند است: فردی به حدسها اعتماد نکرد و دو روش API مرورگر را دور زد و در یک شب لیست کاملی از آنچه که از او برداشت میشود و آدرسی که به آن میرود، دریافت کرد. همان تکنیک یک ساعت در هر سایتی که با آن کار میکنید طول میکشد و ماهها تلاش برای تنظیمات تصادفی را جایگزین میکند. نقشه شناسایی را قبل از تعمیر مسدود شدنها ثبت کنید - در غیر این صورت خطر دارید که بودجه را برای پروکسیها صرف کنید در جایی که مشکل در یک رندرکننده WebGL یکسان در تمام پروفایلها بود.
```