Tổng quan
Tổng quan
phân tích tấn công
Vào ngày 13 tháng 4 năm 2023, Yearn Finance đã bị hack, dẫn đến khoản lỗ khoảng 10 triệu USD. Bài viết này sẽ phân tích quá trình tấn công và nguyên nhân của lỗ hổng.
https://etherscan.io/tx/0xd55e43c1602b28d4fd4667ee445d570c8f298f5401cf04e62ec329759ecda95d
phân tích tấn công
Đây là một giao dịch tấn công:
Kẻ tấn công đã bắt đầu một khoản vay nhanh từ Balancer, vay 5 triệu DAI, 5 triệu USDC và 2 triệu USDT:
Sau đó, trên Curve, kẻ tấn công đã đổi 5 triệu DAI lấy 695.000 USDT và 3,5 triệu USDC lấy 151 USDT:
Kẻ tấn công gọi hàm đề xuất của IEarnAPRWithPool để kiểm tra APR hiện tại. Tại thời điểm này, chỉ có APR của Aave là không bằng 0:
Tiếp theo, kẻ tấn công đã chuyển 800.000 USDT sang hợp đồng tấn công 0x9fcc1409b56cf235d9cdbbb86b6ad5089fa0eb0f. Trong hợp đồng này, kẻ tấn công đã gọi hàm trả nợ của Aave: Lending Pool V1 nhiều lần để giúp người khác trả nợ, do đó APR của Aave bằng 0:
Kẻ tấn công đã gọi chức năng gửi tiền của yUSDT, thế chấp 900.000 USDT và thu được 820.000 yUSDT:
Tiếp theo, kẻ tấn công gọi chức năng đúc của bZx iUSDC, sử dụng 156.000 USDC để đúc 152.000 bZx iUSDC và chuyển nó sang Yearn yUSDT:
Kẻ tấn công gọi chức năng rút tiền của Yearn:yUSDT để chuyển 820.000 yUSDT thành 1.030.000 USDT. Tại thời điểm này, chỉ có bZx iUSDC do kẻ tấn công chuyển giao vẫn còn trong hợp đồng:
Tiếp theo, kẻ tấn công gọi hàm tái cân bằng của Yearn:yUSDT để phá hủy bZx iUSDC:
Sau đó, trên Curve, kẻ tấn công đã đổi 70.000 yUSDT lấy 5.990.000 yDAI, 400 triệu yUSDT lấy 4.490.000 yUSDC và 1.240.133.244.352.200 yUSDT lấy 1.360.000 yTUSD:
phân tích lỗ hổng
Sau đó gọi rút tiền theo năm: yDAI và năm: yUSDC tương ứng, rút 6,78 triệu DAI và 5,62 triệu USDC, đồng thời trả lại khoản vay nhanh:
phân tích lỗ hổng
Điểm mấu chốt nhất trong cuộc tấn công này là kẻ tấn công đã sử dụng 100.000 USDT để đúc 1.252.660.242.850.000 yUSDT. Kiểm tra việc thực hiện chức năng gửi tiền:
Có thể thấy rằng số lượng chia sẻ có liên quan đến nhóm biến, nhóm càng nhỏ, chia sẻ càng lớn và giá trị của nhóm được lấy bởi _calcPoolValueInToken:
Sau khi kẻ tấn công gọi chức năng cân bằng lại, chỉ có USDC tồn tại trong hợp đồng, nhưng _balance() lấy số dư USDT và số dư USDC không được bao gồm trong đó, vì vậy nhóm tại thời điểm này là 1 (do kẻ tấn công chuyển) :
Đây rõ ràng là lỗi cấu hình của phía dự án. Hợp đồng yUSDT phải là tất cả các mã thông báo USDT, nhưng biến điểm tựa của nó là mã thông báo bZx IUSDC liên quan đến USDC, vì vậy USDC trong yUSDT không được đưa vào số dư:"newProvider != provider"Tại sao kẻ tấn công có thể gọi chức năng cân bằng lại để ghi mã thông báo bZx iUSDC? Kiểm tra việc thực hiện chức năng tái cân bằng:
Có thể thấy rằng sẽ có các hoạt động đổi và ghi trong _withdrawFulcrum(), vì vậy chúng ta cần để
được thiết lập, nơi thực hiện khuyến nghị():
Kẻ tấn công thao túng newProvider bằng cách kiểm soát giá trị trả về của IIEarnManager(apr).recommend(token) bằng 0:
Làm cách nào để biến tất cả chúng thành 0? Giá trị trả về của hàm này có liên quan đến APR được tính toán trong mỗi DeFi. Vì không có pool trong Compound, bZx và dydx, bạn chỉ cần kiểm soát Aave (Aave: Lending Pool Core V1) :
Để trả về giá trị 0, giá trị trả về đầu tiên của hàm apr.calculateInterestRates cần phải là 0:
_totalBorrowsVariable bằng 0, tức là Aave: Lending Pool Core V1 không có khoản nợ nào tại thời điểm này. Để đạt được điều kiện này, kẻ tấn công phải trả nợ cho mọi người trong nhóm:
tóm tắt
Nguyên nhân sâu xa của sự cố tấn công Yearn là lỗi cấu hình của bên dự án. Những kẻ tấn công đã khai thác lỗ hổng theo một loạt cách tinh vi và cuối cùng kiếm được khoảng 10 triệu USD tiền lãi.
về chúng tôi
At Eocene Research, we provide the insights of intentions and security behind everything you know or don't know of blockchain, and empower every individual and organization to answer complex questions we hadn't even dreamed of back then.
