تصور کنید تنها با یک دستور ریاضی ساده، تمام masquerade یا نقاب مرورگر شما کنار برود و وبسایتها بفهمند دقیقاً از چه سیستمعاملی استفاده میکنید. اگر فکر میکنید تغییر User-Agent کافی است تا هویت شما پنهان بماند، باید بدانید که سختافزار و سیستمعامل شما در لایههای عمیقتر، حقیقت را لو میدهند.
بسیاری از سیگنالهای مرورگر را میتوان جعل کرد، اما نحوهی پردازش اعداد ممیز شناور (Floating-point) در CPU و سیستمعامل تقریباً غیرقابل تغییر است. به گزارش Scrapfly، یک فراخوانی ساده از تابع Math.tanh(0.8) اکنون میتواند سیستمعامل شما را برای هر وبسایتی که بازدید میکنید، افشا کند.
اثرانگشتگذاری (Fingerprinting) پیش از این بر آثار بصری مانند رندرینگ Canvas یا فونتهای نصبشده متکی بود. اما اکنون یک سیگنال خاموشتر در بیتهای انتهایی تقریبهای عددی ظاهر شده است. این «نشت ریاضی» به سیستمهای ضدبات اجازه میدهد تا بین لینوکس، مک و ویندوز با دقت بسیار بالا تمایز قائل شوند.
اکثر توابع ریاضی در موتور V8 (موتور جاوااسکریپت گوگل) در تمام پلتفرمها یکسان هستند. اما از نسخه کروم ۱۴۸ به بعد، گوگل نسخه داخلی tanh را با std::tanh جایگزین کرد. این تابع مستقیماً از کتابخانه ریاضی سیستمعامل میزبان (libm) استفاده میکند. به همین دلیل، خروجی تابع اکنون به این بستگی دارد که شما از glibc در لینوکس، libsystem_m در مک یا UCRT در ویندوز استفاده کنید.
همانطور که در بررسیهای پیشین ما دربارهی امنیت لایههای زیرین مرورگر اشاره کردیم، هرگونه وابستگی مستقیم به کتابخانههای سیستمعامل میتواند منجر به افشای هویت کاربر شود.
کالبدشکافی نشت داده
این تفاوت به این دلیل رخ میدهد که استاندارد IEEE 7544 برای اعداد با دقت مضاعف، الزام نمیکند که توابعی مثل سینوس یا تانژانت هایپربولیک دقیقاً «بهدرستی گرد» شوند. گرد کردن دقیق هزینه محاسباتی بالایی دارد. در نتیجه، هر سازنده سیستمعامل کتابخانه (libm) مخصوص خود را ارائه میدهد که برای سرعت بیشتر، دقت را در آخرین بیت (ULP) فدا میکند.
این منجر به سه مجموعه بیت متفاوت میشود:
- لینوکس: glibc
- مک: Apple libsystem_m
- ویندوز: UCRT
بهعنوان مثال، اجرای Math.tanh(0.8) نتایج متفاوتی دارد:
- لینوکس: 0.6640367702678491
- مک: 0.664036770267849
- ویندوز: 0.6640367702678489
بر اساس مستندات فنی، در کروم ۱۵۰ این تفاوتها بسته به ورودی تغییر میکنند. برای مثال در ورودی 0.5 هر سه سیستم یک جواب میدهند (که این ورودی برای شناسایی بیفایده است)، اما در ورودی 0.8 هر سه تفاوت دارند و یک امضای اختصاصی برای هر سیستمعامل میسازند.
از آنجا که این تفاوتها راهمند (Deterministic) هستند، شناسگر نیاز به محاسبات پیچیده ندارد. او فقط یک جدول جستوجو دارد: اگر مرورگر ادعا کند مک است اما خروجی ریاضی لینوکس را برگرداند، یعنی هویت خود را جعل کرده است.
بازه زمانی افشا
این نشت موضوع جدیدی است. تا قبل از کروم ۱۴۸، موتور V8 از یک نسخه داخلی به نام fdlibm استفاده میکرد و خروجی در تمام سیستمعاملها یکسان بود. اما با کامیت c1486295ae5 و جایگزینی آن با std::tanh در نسخه V8 14.8.57، این حفره ایجاد شد. بنابراین نسخههای ۱۴۷ و قدیمیتر این سیگنال را ندارند، اما نسخههای ۱۴۸، ۱۴۹ و ۱۵۰ این افشاگر هستند.
چرا جعل این اثرانگشت تقریباً غیرممکن است؟
Scrapfly چهار تله حیاتی را شناس کرده که پاک کردن این اثرانگشت را سخت میکند:
- نشت نامتقارن: در جاوااسکریپت فقط
Math.tanhنشت میکند. توابعی مثلMath.expیاMath.powهمچنان از کتابخانه داخلی استفاده میکنند و یکسان هستند. اگر یک بات سعی کند همه را جعل کند، تناقضی ایجاد میکند که خودش یک سیگنال شناسایی است. - تفاوت در CSS: توابع مثلثاتی CSS (مثل
sinیاcos) کد مشترکی با شیءMathدر جاوااسکریپت ندارند. این توابع مستقیماً از libm سیستمعامل استفاده میکنند، بنابراین تمام هفت تابع مثلثاتی CSS نشت میکنند. - کتابخانههای دوگانه اپل: مک از دو کتابخانه متفاوت استفاده میکند.
libsystem_mبرای محاسبات تکمقیاسی و چارچوب Accelerate برای محاسبات برداری. این دو در بسیاری از ورودیها با هم اختلاف دارند. انتخاب کتابخانه اشتباه برای جعل، بدتر از آن است که اصلاً جعل نکنید. - تفاوتهای معماری: پردازندههای ARM و x86 عملیات FMA و انتشار علامت NaN را متفاوت مدیریت میکنند. کدی که روی کاغذ درست است، ممکن است در زمان کامپایل روی سختافارهای مختلف تغییر کند.
نقشه نشت دادهها
در موتور Blink، مسیرها به این صورت است:
- توابع Math در جاوااسکریپت: اکثر آنها ایمن هستند، فقط
Math.tanhنشت میکند. - توابع
calc()در CSS: تمام توابع مثلثاتی نشت میکنند. - Web Audio: در مک از Accelerate برای مراحل برداری (نشت معماری) و از libsystem_m برای فشردهساز (نشت سیستمعامل) استفاده میکند.
- WASM: چون توابع ریاضی را همراه خود میآورد، در سطح سیستمعامل ایمن است و فقط تفاوت ARM-versus-x86 را نشان میدهد.
راهکار مهندسی برای دور زدن
برای بستن این شکاف، Scrapfly فرآیند «بازتولید دقیق الگوریتم» را توصیف میکند. هدف این است که دقیقاً شبیه سیستمعاملی باشیم که ادعا میکنیم. این کار شامل استخراج ضرایب MinMaxScaler و جداول نمایی از libm هدف و تبدیل آنها به کد C قابل حمل است.
برای ویندوز، آنها فایل ucrtbase.dll را در زمان اجرا در حافظه بارگذاری میکنند. از آنجا که UCRT ویندوز x86-64 است، میتوان آن را مستقیماً روی سرور لینوکس اجرا کرد. این کار نیازمند مدیریت دقیق حافظه (Shadow Space) برای جلوگیری از تخریب ساختار فریم در Clang است.
یک نکته فنی دیگر این است که توابع UCRT در ابتدا یک فلگ CPU-dispatch را میخوانند تا مسیر کند یا سریع (FMA/AVX2) را انتخاب کنند. Scrapfly آدرس این فلگ را استخراج کرده و آن را به اجبار روی مسیر FMA قرار میدهد تا خروجی دقیقاً مشابه یک دستگاه ویندوزی مدرن شود.
سیستم اعتبارسنجی
هیچ کدی بدون اثبات منتشر نمیشود. تیم آنها ۸۷۱,۰۰۰ ورودی را در هر انتشار تست میکند. آنها از دو مرجع استفاده میکنند: یک دستگاه مک واقعی برای شناسایی اختلاف کتابخانهها و یک مرورگر کروم واقعی روی مک از طریق پروتکل دیباگینگ.
حتی عملکرد (Performance) هم یک سیگنال است. نسخههای اولیه آنها ۲.۵ تا ۶ برابر کندتر بودند. یک حلقه زمانبندی ساده میتوانست بفهمد که این مرورگر واقعی نیست. با انتقال به FMA سختافزاری، سرعت آنها حتی از glibc بیشتر شد و بیتها کاملاً منطبق شدند.
این تحول، مرز جدیدی در بازی موش و گربه بین وباسکرپرها و سیستمهای حفاظتی است. وقتی ریاضیات زیربنایی سیستمعامل به یک بیومتریک تبدیل شود، هزینه نامرئی ماندن برای اپراتورهای بات بهشدت افزایش مییابد.
گام بعدی شما
- برای تست مرورگر خود، کنسول توسعهدهنده (F12) را باز کرده و دستور
Math.tanh(0.8)را اجرا کنید تا ببینید چه هویتی را پخش میکنید. - اگر مدیر سیستم هستید، بررسی کنید آیا ابزارهای ضدبات شما از این سیگنالهای ریاضی برای شناسایی ترافیک جعلی استفاده میکنند یا خیر.
- برای توسعهدهندگانی که با WASM کار میکنند، این یک فرصت برای پیادهسازی توابع ریاضی مستقل از پلتفرم است.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تفاوتهای پردازش در تراشههای ARM و x86 مراجعه کنید.




گفتگو