آسیب پذیری مهمی در شبکه پالیگان یافت شده بود که منجر به سرقت ۹.۲ میلیارد توکن متیک میشد.
به گزارش میهن بلاکچین و به نقل از ایمیونفای، هکر کلاه سفید به اسم لئون اسپیس واکر (Spacewalker) در تاریخ ۳ دسامبر (۱۲ آذر) آسیب پذیری بسیار مهمی را در پالیگان گزارش داد. این آسیبپذیری شامل عدم امکان بررسی موجودی در عملکرد انتقال قرارداد MRC20 پالیگان است و به حملهکننده امکان داده است تا تمام ۹,۲۷۶,۵۸۴,۳۳۲ توکن متیک را از این قرارداد سرقت کند. پس از گزارش لئون اسپیس واکر، پالیگان بلافاصله دست به کار شد تا این باگ را اصلاح کند. ایمیونفای (Immunefi) در بازرسی فعالیت بلاک چین به پالیگان کمک کرد، اصلاح این باگ را تایید و انجام هاردفورک را توصیه کرد.
اگرچه پالیگان به توسعه و پیادهسازی اصلاح این باگ پرداخت، اما هکر دوم (که به اسم هکر کلاه سفید ۲ به آن اشاره میکنیم) در تاریخ ۴ دسامبر (۱۳ آذر)، به آسیب پذیری مشابهی اشاره کرد و آن را گزارش داد. پالیگان تصمیم گرفت فقط این بار استثنا قائل شود و به هکر کلاه سفید ۲، ۵۰۰,۰۰۰ توکن متیک پاداش داد.
به علاوه، یکی از هکرهای کلاه مشکی (یا گروهی از هکرها) توانستند با استفاده از همین آسیب پذیری پالیگان و قبل از اصلاح باگ، ۸۰۱,۶۰۱ توکن متیک سرقت کنند. تیم پالیگان در تاریخ ۵ دسامبر (۱۴ آذر)، اصلاح این باگ را ثبت کرد.
پالیگان جایزه ۲.۲ میلیون دلاری به لئون اسپیس واکر و جایزه ۵۰۰,۰۰۰ توکن متیک به هکر کلاه سفید ۲ پرداخت کرد که با احتساب قیمت کنونی توکن متیک، معادل با ۱,۲۶۲,۷۱۱ دلار میشود. جایزه ۲.۲ میلیون دلاری بیشترین مقداری است که پالیگان برای شناسایی آسیبپذیریها ارائه داده است. این موضوع، اهمیت جایزههای بزرگ شناسایی باگ در دیفای را نشان میدهد.
در این حوزه و با توجه به آینده دیفای، این آخرین مورد شناسایی آسیب پذیریهای شدید و مهم نخواهد بود. با افزایش سرمایه موجود در حوزه دیفای، پروژههای بیشتری دارای باگهای مهم در کد خود خواهند بود و این موضوع، اجتنابناپذیر است. تنها تفاوتی که وجود دارد این است که آیا پروژههای آینده، اقدامات امنیتی جامع اتخاذ میکنند و نهایت تلاش خود را به کار خواهند گرفت که از کدهای پروژه خود محافظت کنند یا خیر. مهمترین روش برای محافظت از کدها، طرحهای شناسایی باگ همراه با جایزههای کلان است.
در ادامه به بررسی جزییات فنی این آسیبپذیری میپردازیم.
تحلیل و بررسی آسیب پذیری پالیگان
توکن متیک (MATIC) توکن اصلی اکوسیستم پالیگان است. نقشی که متیک برای شبکه پالیگان دارد همانند نقش اتر برای شبکه اتریوم است. تفاوت اصلی بین اتر و متیک در نحوه ساخت متیک است. توکن متیک در اکوسیستم پالیگان برای چندین عملکرد نظیر رایگیری در خصوص پروپوزالهای بهبود پالیگان (PIP)، مشارکت در امنیت شبکه از طریق سهامگذاری (staking) و پرداخت کارمزد گس استفاده میشود.
جالبترین نکته درباره توکن متیک، استاندارد آن است. متیک، توکن بومی پرداخت کارمزد گس در شبکه پالیگان است، اما قرارداد اجرا شده در پالیگان نیز محسوب میشود. این قرارداد، قرارداد MRC20 است. استاندارد MRC20 عمدتا برای انتقال بدون کارمزد توکن متیک استفاده میشود که در خصوص اتر، این امر غیرممکن است. هنگام ارسال اتر، تراکنشی انجام میدهید که کیف پول باید آن را امضا کند.
انتقال بدون کارمزد گس متیک توسط تابع ()transferWithSig انجام میشود. کاربری که توکن در اختیار دارد، مجموعهای از پارامترها نظیر اپراتور، مقدار، نانس و تاریخ انقضا را امضا میکند. اپراتور بعدا میتواند این امضا را به قرارداد MRC20 انتقال دهد تا از جانب دارنده توکن، انتقال را انجام دهد. این انتقال برای دارنده توکن کارمزد گس به همراه ندارد زیرا اپراتور، کارمزد گس را پرداخت میکند.
ما ابتدا بررسی میکنیم که هش امضا (که در قرارداد به آن dataHash گفته میشود) قبلا استفاده نشده باشد. این موضوع از حملههای اجرای مجدد (replay attack) جلوگیری میکند. پس از بررسی هش، با استفاده از ecrecovery، آدرس دارنده توکن را به دست میآوریم و آن را به تابع ()transferFrom_ منتقل میکنیم.
قراردادهای هوشمند بر بستر اتریوم از طریق ecrecover، به الگوریتم داخلی بررسی امضای ECDSA دسترسی دارند. این تابع داخلی به شما امکان میدهد تا صحت امضا را از اطلاعات هششده بررسی کنید و کلید عمومی امضاکننده را برگردانید. ecrecovery یک تابع رپر (wrapper) بر بستر ecrecover استاندارد است که به شما امکان میدهد مجموعهای از امضاها را انتقال دهید.
اما باگ و آسیب پذیری مورد نظر در توکن متیک پلتفرم پالیگان میتوانست به حملهکننده امکان دهد تا تعداد دلخواهی توکن از قرارداد MRC20 صادر کند. این موضوع بدان معنا است که تمام تقریبا ۹.۲ میلیارد توکن متیک میتوانست سرقت شوند.
مسأله اصلی این است که تابع transferFrom_ تابع transfer_ را مستقیما فراخوانی میکرد بدون آنکه بررسی کند آیا from (آدرس مبدا) موجودی کافی دارد یا خیر. همچنین به دلیل عدم بررسی این موضوع که آیا ecrecovery آدرس صفر را برمیگرداند یا خیر، میتوانیم تابع ()transferWithSig را بدون امضای معتبر فراخوانی کنیم.
این تابع، موجودی آدرسهای from (مبدا) و to (مقصد) را گرفته و با تابع ()transfer_ انتقال میدهد که مشکل مشابهی دارد. این تابع بررسی نمیکند که آیا ارسالکننده، موجودی کافی دارد یا خیر.
این موضوع میتواند به شرایطی منجر شود که طی آن، هر فردی میتواند چنین تراکنشی ایجاد کرده و تعداد دلخواهی توکن از قرارداد جنسیس صادر کند. اما چگونه این اقدام انجام میشود؟
در ادامه، مراحل این اقدام را قدم به قدم توضیح میدهیم:
۱- یک رشته (string) بایت به طول دلخواه به غیر از ۶۵ ایجاد کنید. به دلیل بررسی در ecrecovery، اگر مجموعه امضا طول ۶۵ نداشته باشند، به آدرس صفر (مبدا) برمیگردند. این موضوع بدان معنا است که برای ادامه حمله به امضای معتبر نیازی نداریم.
۲- مقدار amount انتقال داده شده به تابع میتواند هر مقداری باشد، اما میتوانیم از کل موجودی قرارداد MRC20 استفاده کنیم.
۳- آدرس to آدرس حملهکننده خواهد بود.
۴- پس از بازیابی آدرس from از امضای نامعتبر (این آدرس صفر است زیرا ما امضای نامعتبر انتقال دادهایم)، تابع ()transferFrom_ فراخوانی میشود.
۵- از آنجایی که موجودی آدرسهای from و to بررسی نمیشود، قرارداد تابع ()transfer_ را فراخوانی میکند.
۶- تابع ()transfer_ فقط بررسی میکند که خود دریافتکننده، قرارداد MRC20 نباشد و مقداری از قرارداد MRC20 به حملهکننده انتقال میدهد.
۷- از سود تمام توکنهای متیک لذت ببرید.
اصلاح آسیب پذیری پالیگان
پالیگان تابع transferWithSig