فرار از سندباکس V8 با زنجیر کردن سه باگ
خلاصهٔ کاملتر
نویسنده که فعلاً کار تماموقت نداره، تصمیم گرفته مدلسازی مدرن exploit مرورگر رو یاد بگیره و برای همین سراغ v8CTF گوگل رفته؛ یه چالش دائمی که توش گوگل یه نسخهٔ ثابت کروم رو اجرا میکنه و تو باید کاری کنی که مرورگر محتوای یه فایل فلگ رو چاپ کنه. به گفتهٔ خودش، هدف مشخص و یه خط پایان مسخره انتخاب کرده و تا رسیدن بهش ادامه داده. نکتهٔ مهم اینه که هدف، دقیقاً همون بیلد کروم برای تست روی لینوکس بوده، چون تو exploit مرورگر کوچیکترین تفاوت نسخه همهچی رو خراب میکنه.
زنجیرهٔ نهایی از سه CVE عمومی استفاده کرد. باگ اول (CVE-2026-15903) یه اشتباه تو کامپایلر بهینهساز TurboFan بود که اجازه میداد تابع charCodeAt بیرون از رشتهٔ موردنظر بخونه و بهعنوان یه اوراکل آدرس کار کنه. باگ دوم (CVE-2026-15776) یه اشتباه تو RegExp و مقدار lastIndex بود که باعث میشد بعد از جمعآوری زباله، یه اشارهگر به حافظهای بمونه که قبلاً بازیافت شده. باگ سوم یه ناهماهنگی بین JSPI و جدول JS Dispatch بود که بعداً برای عبور از خود سندباکس به کار اومد.
نویسنده توضیح میده که این باگها مکمل هم بودن: باگ اول میدونست شیء کجاست ولی نمیتونست بنویسه، باگ دوم میتونست شیء رو جایگزین کنه ولی به اطلاعات چیدمان حافظه نیاز داشت. با ترکیبشون تونست یه آرایهٔ جعلی بسازه و به خوندن و نوشتن دلخواه داخل «قفس» ۴ گیگابایتی V8 برسه. ولی این هنوز پایان کار نبود، چون سندباکس V8 اشارهگرهای مهم نیتیو رو عمداً بیرون از این قفس نگه میداره.
برای عبور از این مرز، اول با دستکاری طول یه رشتهٔ خارجی، آدرس پایهٔ باینری کروم رو لو داد و ASLR رو دور زد. بعد با سوءاستفاده از ناهماهنگی JSPI سر تعداد آرگومانهای استک، استک نیتیو رو منحرف کرد و کنترل جریان اجرا رو گرفت. در آخر بهجای shellcode، از کدهایی که همین الان تو باینری کروم هستن استفاده کرد (یه زنجیرهٔ ROP ساده برای باز کردن، خوندن و چاپ فایل) تا فلگ رو بخونه، چون حفاظت W^X هنوز فعال بود و اجازهٔ اجرای کد تازه رو نمیداد.
نکتهٔ جالب اینه که گرفتن فلگ و بردن چالش دو چیز کاملاً جدا بودن. نویسنده تأکید میکنه که این یه فرار از سندباکس V8 بوده، نه فرار از سندباکس کل پروسهٔ کروم که تو این چالش غیرفعال شده بود. جایزهٔ ۱۰ هزار دلاری شرطهای سختی داره: نرخ موفقیت حداقل ۸۰ درصد، میانگین زمان اجرای زیر ۵ دقیقه و اینکه اولین ثبتکننده برای اون باگ باشی. چون زنجیرهش n-day بود و اعداد قابلیت اطمینانش خوب نبود، جایزهای نگرفت. اون همچنین شفاف میگه که تو مسیر از چند LLM کمک گرفته، ولی هیچ پرامپتی نبوده که بگه «V8 رو pwn کن» و یه exploit آماده تحویل بده.
نکات کلیدی:
- هدف دقیقاً بیلد Chrome for Testing نسخهٔ ۱۵۰.۰.۷۸۷۱.۴۶ روی لینوکس با V8 نسخهٔ ۱۵.۰.۲۴۵.۱۳ بود
- سه CVE عمومی: CVE-2026-15903 (اوراکل آدرس)، CVE-2026-15776 (آرایهٔ جعلی و خوندن/نوشتن)، و ناهماهنگی JSPI و JS Dispatch Table
- خوندن و نوشتن دلخواه فقط داخل قفس ۴ گیگابایتی V8 به دست اومد؛ فرار از قفس به باگ سوم نیاز داشت
- بهجای shellcode از زنجیرهٔ ROP روی کد موجود کروم استفاده شد چون W^X فعال بود
- این یه فرار از سندباکس V8 بود، نه سندباکس پروسهٔ کروم که تو چالش غیرفعال شده بود




