Phân tích nguyên tắc lỗ hổng thay thế địa chỉ tùy ý trong ERC2771 Multicall từ SharkTeam

robot
Đang tạo bản tóm tắt

Vào ngày 8 tháng 12 năm 2023, OpenZeppelin đã phát hành một cảnh báo quan trọng về an ninh. Hóa ra, khi sử dụng tiêu chuẩn ERC-2771 và các chức năng kiểu Multicall có nguy cơ bị thay đổi địa chỉ! Tôi đã nghiên cứu sâu về lỗ hổng này và muốn chia sẻ những phát hiện của mình.

Phân tích cuộc tấn công

Hãy xem xét một trong những cuộc tấn công:

  • Tấn công: 0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
  • Giao dịch: 0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

Sơ đồ tấn công thật sự đơn giản:

  1. Kẻ xấu đã đổi 5 WETH lấy khoảng 3,455,399,346 TIME
  2. Sau đó, tôi đã thiết kế các tham số calldata tinh vi và gọi [Forwarder].execute
  3. Chức năng này đã khởi động multicall trong hợp đồng TIME, và calldata còn lại được sử dụng để burn() - tiêu hủy token trong pool!

Nó hoạt động như thế nào?

Trong cuộc tấn công này, các ngôi sao đã hội tụ: ERC-2771, Multicall và dữ liệu được tổ chức một cách cẩn thận. Hợp đồng TOKEN kế thừa ERC2771Context, và đây là lúc bắt đầu những điều thú vị nhất!

ERC-2771 cho phép một msg.sender ảo, cho phép ủy quyền giao dịch cho bên thứ ba. Trong trường hợp này, địa chỉ thực được thêm vào calldata. Khi [Forwarder] gọi hợp đồng, _msgSender() kiểm tra dữ liệu này và cắt bỏ 20 byte cuối cùng như là "msg.sender" thực.

Multicall biến một cuộc gọi thành nhiều cuộc gọi, tiết kiệm gas. Nó nhận một mảng các cuộc gọi và thực hiện chúng thông qua deleGatecall().

Và đây là cái bẫy! Kẻ tấn công dịch calldata sao cho 4 byte đầu tiên của dữ liệu mới tương ứng với hàm burn(), và tham số - một số lượng lớn token. Trong dòng 0x20, địa chỉ của pool thanh khoản TIME-ETH được thêm vào, trở thành "msg.sender" "được mong đợi"!

Gốc rễ của vấn đề

Trong ERC-2771 [Forwarder] không bao giờ được lên kế hoạch để hoạt động với multicall! Kẻ tấn công đã thêm các tham số _msgSender() vào cuộc gọi bên ngoài multicall. Bên trong hàm multicall, một số hàm cũng đã thêm các tham số này, cho phép giả mạo cuộc gọi từ BẤT KỲ địa chỉ nào!

Biện pháp bảo vệ

  1. Phiên bản mới của OpenZeppelin Multicall hiện lưu độ dài ngữ cảnh ERC-2771 và xem xét nó trong mỗi cuộc gọi con.

  2. ThirdWeb đã đi xa hơn và cấm bất kỳ hợp đồng nào gọi multicall, ngăn chặn việc sử dụng [Forwarder].

Lỗ hổng này là một ví dụ rõ ràng về cách mà sự kết hợp của các thành phần an toàn riêng lẻ có thể tạo ra một lỗ hổng thảm khốc! Tất cả các nhà phát triển nên nhớ: luôn kiểm tra sự tương tác giữa các tiêu chuẩn khác nhau.

ETH1.02%
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Đăng lại
  • Chia sẻ
Bình luận
0/400
Không có bình luận
  • Ghim
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)