روز سه شنبه ۱۹ مرداد، شبکه پالی نتورک مورد حمله هکرها قرار گرفت و بیش از ۶۰۰ میلیون دلار رمزارز از این شبکه به سرقت رفت. پالی نتورک شبکهای است که امکان انتقال رمزارزها بین بلاکچینهای مختلف را فراهم میکند. ۶۰۰ میلیون دلار دزدیده شده در این هک، در فاصله خیلی کوتاهی توسط هکر بازگردانده شد.
در این مقاله قصد داریم به طور دقیق و با جزئیات به این مسئله بپردازیم که هک شبکه پالی نتورک چطور انجام شد و هکرها چگونه موفق شدند این شبکه را هک کنند. با ما همراه باشید.
بعد از هک پالی نتورک چه اتفاقی افتاد؟
داراییهای به سرقت رفته که شامل رمزارزها و استیبل کوینها بودند، روی سه بلاکچین اتریوم، بایننس اسمارت چین و پالیگان بودند. ساختار استیبل کوینها بهگونهای است که سازندگان آنها میتوانند در مواقع ضروری، دارایی بعضی اکانتها را فریز کنند. بلافاصله بعد از این دزدی، تتر از این قابلیت استفاده کرد و ۳۳ میلیون دلار از USDTهای دزدیده شده توسط هکر را فریز کرد. پس از این اقدام، یکی از کاربران شبکه اتریوم این مسئله را به اطلاع هکر رساند و هکر برای قدردانی، حدود ۴۳ هزار دلار (۱۳.۳۷ اتر) اتر برای او ارسال کرد.
پالی نتورک اطلاعات اکانتهایی را که حاوی داراییهای دزدیده شده بودند، منتشر کرد و از ماینرها و صرافیها درخواست کرد تا رمزارزهایی که از این آدرسها میآیند را در لیست سیاه خود قرار دهند. علاوه بر این، وبسایت Elliptic اکانتهای هکر را به لیست خود اضافه کرد تا کاربران بتوانند تراکنشهای این آدرسها را رصد کنند.
صبح روز چهارشنبه، هکر شروع به انتشار پیامهایی کرد که نشان میدادند او قصد بازگرداندن داراییها را دارد! هکر با ارسال تراکنشی به خودش در شبکه اتریوم (از اکانتی که حاوی مقداری از داراییهای دزدیده شده بود) پیامی فرستاد و گفت: حاضرم دارایی ها را بازگرداندم!
به نظر میرسید هکر میخواهد داراییهای دزدیده شده را بازگرداند. این تصمیم میتوانست دو دلیل داشته باشد: یا هکر از اول تصمیم به بازگرداندن داراییها داشته، یا توجه زیادی که در سراسر جامعه کریپتو به کار او جلب شده بود، باعث شد از اینکه بتواند این داراییها را خرج کند ناامید شود و از ترس فاش شدن هویتش و اینکه دستگیر شود، تصمیم بگیرد مبالغ سرقتی را برگرداند.
پالی نتورک به این پیام هکر پاسخ داد و از او خواست داراییها را به آدرسهای اعلامی ارسال کند:
پس از گذشت چند ساعت، هکر شروع کرد به ارسال داراییهای دزدیدهشده به آدرسهایی که پالی نتورک اعلام کرده بود. میتوانید اطلاعات مربوط به بازگشت داراییها در هر شبکه را از طریق این لینکها ببینید:
هکر پالی نتورک در مرحله اول، ۲۵۸ میلیون دلار از داراییها را بازگرداند و سپس، ۲۳۵ میلیون دلار دیگر را به یک آدرس اتریوم فرستاد. هکر این آدرس با با عنوان یک «اکانت چندامضایی اشتراکی» توصیف کرده است. پالی نتورک هم بعدا گفت که به طور مشترک با هکر (که از او با عنوان آقای کلاه سفید / Mr. White Hat یاد میکند) به داراییها دسترسی دارد.
از آنجایی که کلید خصوصی این اکانت به طور مشترک در اختیار هکر و پالی نتورک است، هکر همچنان اگر میخواست میتوانست از دسترسی پالی نتورک به این داراییها جلوگیری کند. او در پیامی گفته بود «وقتی همه آماده باشند، کلید نهایی را رو میکنم»
هکر پالی نتورک در اقدامی جالب، طی پروسه بازگرداندن داراییها شروع به ارسال پیامهایی کرد که حاوی پرسش و پاسخ با خودش بودند. در ادامه میتوانید این پیامها را ببینید.
بخش اول:
بخش دوم:
بخش سوم:
بخش چهارم:
از پرسش و پاسخی که هکر با خودش به راه انداخته، میتوان این برداشت را کرد که او از همان ابتدا تصمیم داشته داراییها را بازگرداند و هدفش از هک پالی نتورک «سرگرمی» و جلوگیری از آسیب زدن افراد «داخلی» به شبکه بوده است. هکر ادعا کرده که او پیشنهاد ۵۰۰ هزار دلاری برای بازگرداندن داراییها را رد کرده است.
با این وجود، او از مردم درخواست کرده بود در ازای کار درستی که انجام داده، به او پول اهدا کنند:
تا زمان نگارش این مقاله، حدود ۵۳۰۰ دلار به اکانت هکر واریز شده است.
اما هک پالی نتورک دقیقا چطور انجام شد؟
حالا که در جریان کلیت هک پالی نتورک قرار گرفتیم، خوب است نگاهی جزئیتر به این ماجرا بیندازیم و ببینیم دقیقا چه اتفاقی در قراردادهای این شبکه افتاد و هکر با استفاده از کدام نقطه ضعفهای شبکه موفق به هک کردن پالی نتورک شد.
شبکه پالی قرارداد خاصی به نام EthCrossChainManager دارد که امکان گرفتن دیتا از بلاکچینهای دیگر را دارد. این عملکرد برای پروژههای کراسچین (بین زنجیرهای)، عملکردی نرمال و عادی است. در قرارداد پالی نتورک، فانکشنی به نام verifyHeaderAndExecuteTx وجود دارد که برای بیرون کشیدن تراکنشهای کراسچین به کار میرود. این فانکشن، با چک کردن امضاها، درستی بلاک هدر را تایید میکند و بعد، با یک اثبات مرکل، چک میکند که تراکنش داخل بلاک قرار گرفته یا نه. میتوانید کد مربوط به این فانکشن را اینجا ببینید. کار نهایی که این فانکشن انجام میدهد، صدا زدن executeCrossChainTx_ برای تارگت کردن قرارداد است. اینجا دقیقا همانجایی است که نقص بحرانی مورد نظر ما قرار میگیرد. شبکه پالی چک میکند که تارگت مورد نظر یک قرارداد است، اما فراموش کرده کاربران را از صدا زدن یک تارگت خیلی مهم، یعنی قرارداد EthCrossChainData منع کند.
دلیل اهمیت این تارگت چیست؟ این تارگت لیستی از کلیدهای عمومی را نگهداری میکند که دیتای مربوط به بلاکچینهای دیگر را تصدیق میکند. اگر کسی بتواند این لیست را تغییر دهد، دیگر نیازی به هک کردن کلیدهای خصوصی نخواهد داشت. فقط کافیست کلیدهای عمومی را طوری کنار هم قرار دهد تا با کلیدهای خصوصی خودش تطبیق پیدا کنند. میتوانید لیست مورد نظر را اینجا ببیند.
در نتیجه، یک نفر متوجه شده که میتواند یک پیام کراسچین را به طور مستقیم به قرارداد EthCrossChainData ارسال کند. این کار چه نفعی برای او دارد؟ از آنجایی که مالکیت قرارداد EthCrossChainData در اختیار قرارداد EthCrossChainManager است، با ارسال این پیام کراسچین، کاربر میتواند با حقه قرار داد EthCrossChainManager را وادار به صدا زدن قرارداد EthCrossChainData کند، بدون اینکه onlyOwner این فرآیند را بررسی کند. (onlyOwner درستی دسترسی صاحب کانترکت و فانکشنهایی که او صدا میزند را چک میکند) حالا فقط کافیست کاربر مهارت کافی برای به دست آوردن دیتای درست را داشته باشد تا بتواند با استفاده از این فانکشن، کلیدهای عمومی را تغییر دهد. این فانکشن را میتوانید اینجا ببینید.
توضیح برای کاربران غیرفنی: فرض کنید شما برای کامپیوتر خود یک پسورد تعیین کردهاید. کامپیوتر شما برای اینکه به شما دسترسی بدهد، فقط نیاز به این پسورد دارد و برایش اهمیتی ندارد چه کسی این پسورد را وارد کرده است. اگر کسی کامپیوتر و پسورد شما را داشته باشد، میتواند به اطلاعات آن نیز دسترسی داشته باشد.
تنها چالشی که باقی میماند این است که کاربر بفهمد چطور EthCrossChainManager را وادار به صدا زدن فانکشن درست کند. اینجا کمی مهارت زبان برنامهنویسی سالیدیتی به کمک کاربر میآید تا او بتواند فانکشن درست را انتخاب کند.
اولین چهار بایت دیتای ورودی تراکنش، Signature Hash یا Sighash نام دارد. Sighash دیتای کوچکی است که به قرارداد سالیدیتی میگوید شما قصد انجام چه کاری را دارید. Sighash یک فانکشن با گرفتن چهار بایت اول هش “()” محاسبه میشود. برای مثال، Sighash فانکشن انتقال ERC20، اولین چهار بایت هش “transfer(address,uint256)” است.
قرارداد پالی نتورک امکان صدا زدن هر قراردادی را داشت. با این وجود، تنها فانکشن قراردادی را صدا میزد که با این Sighash مطابقت داشته باشد:
فانکشن “method” در اینجا ورودی کاربر بود. تنها کاری که مهاجم باید برای صدا زدن فانکشن درست انجام میداد این بود که یک Value برای “method” پیدا کند، که وقتی این Value با بقیه Valueها ترکیب و هش شد، حاوی همان چهار بایت اولیهای میشد که Sighash فانکشن هدف ما داشت. با کمی سر و کله زدن، شما میتوانید ورودی لازم برای ایجاد Sighash صحیح را پیدا کنید. نیازی نیست توابع پیچیده هش را پیدا کنید و فقط کافیست چهار بایت اول را چک کنید. درنهایت، آیا این تئوری درست است؟
Sighash تارگت واقعی این است:
>http://ethers.utils.id(‘putCurEpochConPubKeyBytes(bytes)’).slice(0, 10) ‘0x41973cd9’
و Sighash که مهاجم ساخته بود این است:
> http://ethers.utils.id(‘f1121318093(bytes,bytes,uint64)’).slice(0, 10) ‘0x41973cd9’
همانطور که میبینید، هیچ نیازی به در خطر افتادن کلید خصوصی وجود ندارد. فقط کافیست مهارت ساختن دیتای درست را داشته باشید و بعد، کار تمام است! قرارداد خودش را هک میکند!
یکی از بزرگترین درسهای طراحی که میتوان از این ماجرا گرفت این است: اگر قراردادهای کراسچین شبیه به این میسازید، مطمئن شوید که نمیتوان از آنها برای صدا زدن قراردادهای خاص استفاده کرد. اگر قرارداد شما به شدت نیازمند این است که امتیازهای خاصی شبیه به این داشته باشد، مطمئن شوید که کاربران نمیتوانند از پیامهای کراسچین برای صدا زدن آن قردادهای خاص استفاده کنند. اینجا میتوانید فانکشن مورد نظر برای هدف قرار دادن یک پیام کراسچین را ببینید. هیچ چیز نمیتواند مانع شما برای ارسال پیام به قرارداد EthCrossChainData شود.
تنها چیزی که میتواند این تئوری را ۱۰۰ درصد تایید کند، این است که پیام اولیه از یک بلاکچین دیگر ارسال شده باشد. و اینکه به نظر میرسد پیام اولیه از بلاکچین Ontology ارسال شده باشد، مهر تاییدی بر این فرضیه است.
جمعبندی هک پالی نتورک به زبان ساده
در پالی نتورک دو کانترکت به نامهای EthCrossChainManager و EthCrossChainData وجود دارد. کانترکت منیجر، به نوعی صاحب کانترکت دیتاست و میتواند در آن تغییرات ایجاد کند. کانترکت دیتا حاوی لیست آدرسهای بلاکچینهای دیگر است که از آنها تراکنش ارسال شده. کانترکت دیتا این لیست را برای صحتسنجی تراکنشها نگهداری میکند. از طرف دیگر، کانترکت منیجر این تراکنشها را چک میکند تا از درستی انجام آنها اطمینان حاصل کند. وقتی کانترکت منیجر اتفاق افتادن تراکنشها را تایید میکند، کانترکت مربوط به آنها را اجرا میکند. منیجر تمام کانترکتها، از جمله کانترکت دیتا را اجرا میکند. باگ داستان همینجاست.
هکر با ارسال تراکنشی، کانترکت دیتا را صدا میزند و موفق به اصلاح کردن لیست آدرسهای این کانترکت میشود. هکر با انجام این کار، موفق میشود کلیدهای عمومی داخل لیست را با کلیدهای خصوصی مورد نظر خودش تطبیق دهد و به این ترتیب، موفق به انتقال داراییها میشود.
منبع: