پروتکل اینورس فایننس (Inverse Finance) یک پروتکل وامدهی مبتنی بر شبکه اتریوم (Etereum) است. این پروتکل در ۱۶ ژوئن ۲۰۲۲ (۲۶ خرداد ۱۴۰۱) هک شد و داراییهای آن به سرقت رفت. ظاهرا ماجرای هک پروتکل اینورس فایننس ناشی از آسیبپذیری در یک اوراکل (Oracle) بود که برای رصد قیمت توکنها استفاده میشد. به همین دلیل میخواهیم با بازسازی حمله به فورک (Fork) میننت اتریوم ببینیم حمله دستکاری اوراکل در پروتکل Inverse Finance چطور اتفاق افتاده است. با میهن بلاکچین همراه باشید.
حمله دستکاری اوراکل چیست؟
به منظور درک بهتر از حمله دستکاری اوراکل (Oracle Manipulation Attack) میخواهیم کد حمله به پروتکل اینورس فایننس (inverse finance) را بازسازی کنیم. به این ترتیب میتوان تقریبا همان تراکنشی را که مهاجم در فورک شبکه اصلی اتریوم انجام داده است در این محیط انجام داد.
انگیزه اصلی از این کار کنجکاوی در مورد حملات اوراکل و بازسازی آنها در شبکه فورک هاردهت است. برای شما عجیب نیست که چطور چندین خط کد تنها در عرض یک دقیقه مقدار زیادی توکن را جابهجا و سرقت میکند؟ اما ماجرای حمله دستکاری اوراکل Inverse Finance چه بود؟
در ۱۶ ژوئن ۲۰۲۲ (۲۶ خرداد ۱۴۰۱) شخصی با استفاده از وام سریع (Flashloan) پروتکل وامدهی آوه (AAVE) در میننت اتریوم، اوراکل را فریب داد و قیمت توکن INV را در پروتکل وامدهی اینورس فایننس دستکاری کرد. در مجموع ارزش توکنهایی (۵۳.۲۴ واحد WBTC و ۹۹۹۷۶ واحد USDT) که این مهاجم بهدست آورد بیش از یک میلیون دلار بود. اطلاعات حمله به پروتکل وامدهی Inverse Finance به شرح زیر است:
🛑 جزییات تراکنش حمله
جزییات هش تراکنش اتریوم (Txhash) در سایت اتر اسکن:
0x958236266991bc3fe3b77feaacea120f172c0708ad01c7a715b255f218f9313c
🛑 نصب و راهاندازی
۱. پکیج منیجر yarn و محیط اجرایی Node.js را نصب کنید.
۲. با اجرای دستور git clone مخزن کد را شبیهسازی کنید.
https://github.com/yuichiroaoki/inverse-finance-exploit.git
🛑 راهاندازی سریع محیط حمله
اطلاعات بیشتر را در Harhdat Docs بخوانید.
۱. اجرای متغیرهای محیطی
برای انجام تراکنش در شبکه اصلی اتریوم به یک URL پروتکل فراخوانی تابع از راه دور در میننت آلکمی ( ALCHEMY_MAINNET_RPC_URL) نیاز دارید. میتوانید آن را به صورت رایگان از سایت Alchemy دریافت کنید.
سپس با استفاده از دستور زیر یک فایل .env را ایجاد کنید:
ALCHEMY_MAINNET_RPC_URL='<your-own-alchemy-mainnet-rpc-url>’
۲. Dependencyها را نصب کنید
دستور yarn install را اجرا کنید
۳. قراردادهای هوشمند را کامپایل کنید
دستور yarn compile را اجرا کنید
۴. حمله به فورک میننت اتریوم را شبیهسازی کنید
با اجرای دستور yarn attack اسکریپت scripts/attack.ts اجرا میشود.
خروجیهای مورد انتظار طبق موارد زیر است:
- $ yarn attack
- latest answer 979943357748941122174
- latest answer 2831510989152831182521
- Earned: 53.24504921 WBTC
- Earned: 99976.294967 USDC
- Transaction Fee: 0.08769064026344821 ETH
به این ترتیب تراکنشی مشابه با تراکنش مهاجم در فورک میننت اتریوم انجام شد.
چطور یک قرارداد حمله را بازتولید کنیم؟
برای بازسازی یک قرار داد حمله مراحل زیر را انجام دهید: یک شماره بلاک برای اجرای اسکریپتها و تستها تنظیم کنید
هنگام وقوع حمله ابتدا یک شماره بلاک تنظیم کنید. همانطور که در فایل hardhat.config.ts در تصویر بالا مشاهده میکنید چراغ مربوط به شماره بلاک روشن است. با استفاده از URL پروتکل فراخوانی تابع از راه دور (RPC) میننت آلکمی و شماره بلاک، تمام تستها و اسکریپتهای راهاندازی شده در فورک شبکه اتریوم اجرا میشوند. به عبارت دیگر همه وضعیتها از قبیل قیمت توکن، موجودی استخرها و سایر موارد، مشابه با وضعیت بلاکی است که در فایل hardhat.config.ts مشخص شده است.
به این ترتیب میتوان با استفاده از محیط هاردهت حمله را روی بلاکهای قبلی شبیهسازی کرد. از این رو در اینجا هم از یک بلاک قبل از بلاک مورد حمله (بلاک شماره ۱۴۹۷۲۴۱۹) استفاده شده است.
قراردادهایی را که مهاجم با آنها تعامل داشته است بررسی کنید
با استفاده از ابزار تجسم داده BlockSec میتوان قراردادهایی را که مهاجم با آنها تعامل داشته است و آرگومانهای فراخوان توابع خارجی را مشاهده کرد. این ابزار و اطلاعات حاصل از آن، به تنهایی برای بازسازی قرارداد مهاجم کافی است.
مهاجم Finance Inverse در طول تراکنش حمله با پروتکلهای زیادی از جمله استخر AAVE V2 برای دریافت وام سریع و استخر پروتکل Curve و سایر پروتکلها تعامل داشته است. برای بازسازی این حمله باید فراخوانی توابع برای این پروتکلها به همان شکل حمله انجام شود.
به منظور اجرای فراخوانی توابع خارجی به همان شکل حمله در زبان برنامهنویسی سالیدیتی (Solidity) به اطلاعات زیر نیاز است:
- آدرس قرارداد
- رابط قرارداد
- تابع و پارامترهای آن
سایت اتراسکن شامل چنین اطلاعاتی نیست، اما برای مهندسی معکوس یک دیکامپایلر بایتکد ماشینمجازی اتریوم (EVM) را ارائه میدهد. البته هنوز در مرحله آزمایشی قراردارد و درک آن کمی سخت است. برای بهدست آوردن اطلاعات مورد نیاز میتوان لاگ رویداد (گزارش سطح بالا) تراکنشها را نیز بررسی کرد اما به تنهایی کافی نیست.
به هر حال ابزار تمام این اطلاعات را شامل میشود. در این نرمافزار با کلیک روی نام یک قرارداد به صفحه اتراسکن همان قرارداد هدایت میشوید. از آنجایی که اکثر پروتکلها قراردادهای خود را در اتراسکن اعتبارسنجی و تایید میکنند، میتوان یک قرارداد رابط با اتراسکن ایجاد کرد.
قرارداد رابط ایجاد کنید
در مرحله بعد باید از تابع قرارداد مورد استفاده، یک رابط قرارداد ایجاد کنید. به طور مثال تابع latestAnswer قرارداد اوراکل inverse finance را بررسی میکنیم.
خط مربوط به تابع latestAnswer، استفاده از متد Static Call را نشان میدهد و این یعنی با یک تابع View مواجه هستیم.
همه توابع View در بخش Read Contract هستند و همه توابع فراخوانهای تغییر وضعیت (State Changing Call) در بخش Write Contract صفحه قرارداد اتراسکن قرار دارند. بنابراین میتوانید به آدرس Etherscan contract page > Contract tab > Read Contract بروید و تابع latestAnswer را جستجو کنید.
این تابع نوع مقدار بازگشتی را برای هر تابع نشان میدهد و حاکی از آن است که تابع LatestAnswer واحد ۲۵۶ (Unit256) را برمیگرداند.
البته میتوان در گیتهاب (GitHub) یا در صفحه قرارداد اتراسکن نیز یک رابط قرارداد را جستجو کرد اما این روش به دلیل دسترسی سریعتر به پارامترهای تابع و انواع مقادیر برگشتی ترجیح داده میشود. در این روش حتی میتوان برخی مقادیر واقعی را بررسی کرد.
همانطور که در تصویر میبینید در این مثال یک قرارداد رابط اضافه شده است. البته شما فقط به توابع مورد استفاده نیاز دارید.
با استفاده از قرارداد رابط میتوان همانند تصویر زیر تابع latestAnswer() را روی قرارداد Attack فراخوانی کرد.
در مورد توابع فراخوان نیز اتفاق مشابهی میافتد. اجازه دهید موضوع را با مثالی از تابع قرضگرفتن (BorrowAmount) پروتکل Inverse Finance در قرار دادی به نام anDola روشنتر کنیم:
اگر به آدرس Etherscan contract page > Contract tab > Write Contract بروید، متوجه میشوید که برای BorrowAmount واحد ۲۵۶ تعریف شده است.
سپس میتوان رابطی مانند تصویر زیر را با سایر عملکردهای مینت اضافه کرد.
بعد از راهاندازی همه رابطها، میتوان با استفاده از ابزار BlockSec تمام آرگومانهایی را که در طول تراکنش به قرارداد پروتکلهای دیفای ارسال میشوند را کپی کرد. سپس آنها با test/Attack.test.ts تست میشوند و اسکریپت script/attack.ts اضافه میشود.
از آنجایی که مهاجم قرارداد واقعی خود را در اتراسکن اعتبارسنجی نکرده است، نمیتوان قرارداد او را دید. به هر حال با وجود ابزارهای تجسم داده میتوان از فرایند تغییر قیمت در اوراکل Inverse Finance و سود مهاجم مطلع شد.
سخن پایانی
پروتکل اینورس فایننس یک پروتکل وامدهی است که به دلیل آسیبپذیری در اوراکل هک شد. فرد مهاجم با دستکاری اوراکلِ قیمت در پروتکل Inverse Finance و دریافت وام سریع از پروتکل وامدهی آوه (AAVE) در میننت اتریوم هک را انجام داد. او توانست توکنهای رپدبیت کوین (WBTC) و استیبل کوین USDT را مجموعا به ارزشی بالغ بر ۱ میلیون دلار به سرقت ببرد. سعی شد با بازسازی کد حمله در محیط توسعه هاردهت ماجرای حمله دستکاری اوراکل پروتکل اینورس فایننس