Ethernaut Challenge #4 솔루션 — 전화
The Ethernaut is a Web3/Solidity based wargame created by OpenZeppelin.
Each level is a smart contract that needs to be 'hacked'. The game acts both as a tool for those interested in learning ethereum, and as a way to catalogue historical hacks in levels. Levels can be infinite and the game does not require to be played in any particular order.
도전 #4: 전화
Claim ownership of the contract below to complete this level.
Level author: Kyle Riley
이 챌린지의 최종 목표는 계약의 소유권을 주장할 수 있는 것입니다.
계약 연구
Telephone
계약은 매우 작기 때문에 읽고 문제를 해결하는 방법을 이해하는 것이 빠를 것입니다.owner
상태 변수는 constructor
에서 초기화됩니다. owner
를 업데이트하는 유일한 함수는 changeOwner
입니다.function changeOwner(address _owner) public
하나의 매개변수만 사용하는 공용 함수입니다
address _owner
.tx.origin
값이 msg.sender
와 다른 경우 함수 입력 매개변수owner
로 _owner
를 업데이트합니다.이 문제를 해결하려면
msg.sender
및 tx.origin
가 무엇인지 이해해야 합니다.Solidity 공식 문서의 문서 페이지Block and Transaction Properties를 보면 다음 정의를 찾을 수 있습니다.
tx.origin
( address
): 트랜잭션 발신자(전체 콜 체인)msg.sender
( address
): 메시지 발신자(현재 통화)tx.origin
와 msg.sender
는 모두 글로벌 네임스페이스에 항상 존재하는 "특수 변수"로 주로 블록체인에 대한 정보를 제공하거나 범용 유틸리티 기능으로 사용됩니다.그러나 우리는 다음 사항에 주의를 기울여야 합니다.
msg
및 msg.sender
를 포함하여 msg.value
의 모든 구성원 값은 모든 외부 함수 호출에 대해 변경될 수 있습니다. 여기에는 라이브러리 함수에 대한 호출이 포함됩니다. tx.origin
는 트랜잭션을 보낸(원본에서) 주소를 반환하고 msg.sender
는 external
호출을 시작한 값을 반환합니다. 이것은 무엇을 의미 하는가?
예를 들어 두 값의 서로 다른 값을 살펴보겠습니다.
시나리오 A: Alice(EOA)가 직접 호출
Telephone.changeOwner(Bob)
tx.origin
: 앨리스 주소msg.sender
: 앨리스 주소시나리오 B: Alice(EOA)는
Forwarder.forwardChangeOwnerRequest(Bob)
를 호출할 스마트 계약Telephone.changeOwner(Bob)
을 호출합니다.인사이드
Forwarder.forwardChangeOwnerRequest
tx.origin
: 앨리스 주소msg.sender
: 앨리스 주소인사이드
Telephone.changeOwner(Bob)
tx.origin
: 앨리스 주소msg.sender
: 포워더(계약) 주소이것은
tx.origin
가 항상 트랜잭션을 생성한 주소를 반환하고 msg.sender
가 마지막 외부 호출을 한 주소를 반환하기 때문에 발생합니다.솔루션 코드
Telephone
계약에 대한 호출 중간에 있을 계약을 생성하기만 하면 됩니다.contract Exploiter {
function exploit(Telephone level) public {
level.changeOwner(msg.sender);
}
}
솔루션 코드에서 배포하고 호출하기만 하면 됩니다.
function exploitLevel() internal override {
vm.startPrank(player, player);
Exploiter exploiter = new Exploiter();
vm.stopPrank();
}
이전 블로그 게시물을 주의 깊게 살펴보셨다면 이미 치트 코드
startPrank
를 보셨을 것입니다. startPrank
에는 또 다른 오버로드 버전이 있습니다.// Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called
function startPrank(address) external;
// Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input
function startPrank(address, address) external;
이 경우에는
tx.orgin
가 될 이니셜address(this)
도 재정의해야 하기 때문에 두 번째 것을 사용하고 있습니다. 즉, 테스트 계약 자체의 주소입니다!챌린지 오프닝의 전체 솔루션을 읽을 수 있습니다Telephone.t.sol.
추가 자료
Solidity 문서
tx.origin
부인 성명
이 리포지토리의 모든 Solidity 코드, 관행 및 패턴은 DAMN VULNERABLE이며 교육 목적으로만 사용됩니다.
나는 어떠한 보증도 하지 않으며 이 코드베이스의 사용으로 인해 발생하는 손실에 대해 책임을 지지 않습니다.
생산에 사용하지 마십시오.
Reference
이 문제에 관하여(Ethernaut Challenge #4 솔루션 — 전화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/stermi/ethernaut-challenge-4-solution-telephone-33bp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)