1. 문제

아래의 컨트랙트 코드를 잘 살펴보고 소유권을 탈취하라 
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Telephone {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

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

2. tx.origin 개념

tx.origin : 트랜잭션의 발신자를 가리키는 전역 변수

msg.sender : 메시지를 직전에 요청한 contract의 주소를 가르키는 변수

아래 그림처럼 메타마스크에서 트랜잭션을 실행하면 Attack → Telephone 순으로 contract 가 실행된다고 가정한다면

image.png

tx.origin은 메타마스크의 주소인 0x965B…57EF 가 되고, 이는 Attack, Telephone contract에서 tx.origin을 호출 했을 때 모두 같은 결과가 나온다.

image.png

하지만 msg.sender는 Attack, Telephone contract에서 다른 값을 나타나게 된다.

Attack : 메타마스크의 주소인 0x965B…57EF

Telephone : Attack contract의 주소인 0x6789…5aa6

image.png