스마트컨트랙트에서 코인을 훔쳐보자
[요약]
이더리움을 받을 수 있는 간단한 스마트컨트랙트를 작성하고
취약점을 발견하여 스마트컨트랙트 내에 있는 이더리움을 탈취한다.
- 사례1 [Test1] Full Script
pragma solidity 0.8.6;
contract Test1 {
uint nonce;
constructor(uint _nonce) payable {
nonce = _nonce;
}
function getNonce() public view returns (uint) {
return nonce;
}
function withdraw(uint _nonce) public {
require(nonce == _nonce);
payable(msg.sender).transfer(address(this).balance);
}
}
constructor(uint _nonce) payable {
nonce = _nonce;
}
constructor: 생성시 호출하는 함수
payable: 스마트 컨트랙트가 이더를 주고 받을 수 있게 만듬
nonce: _nonce에 값을 대입함.
function getNonce() public view returns (uint) {
return nonce;
}
getNonce 함수.
호출시 nonce값을 반환한다.
function withdraw(uint _nonce) public {
require(nonce == _nonce);
payable(msg.sender).transfer(address(this).balance);
withdraw 함수. uint 값 _nonce를 파라미터로 받는다.
입력한 _nonce 값이 nonce와 일치하면
스마트컨트랙트 호출자에게
스마트컨트랙트가 갖고 있는 잔고 모두를 전송한다.
- 스마트컨트랙트 배포 <= 해킹대상
이 스마트컨트랙트에는
0.0000000001 Ether = 100000000wei
를 갖고 있다.
스마트컨트랙트 배포시 Deploy에 nonce 값을 넣어준다.
이 값을 알게되면 스마트컨트랙트 내에 있는 이더를 탈취할 수 있다.
- 사례1 해킹시도
리믹스 > DEPLOY & RUN TRANSACTIONS > At Address
에 해킹할 스마트컨트랙트 주소를 입력하여 호출한다.
getNonce를 클릭하여 호출. nonce 값을 알아낸다.
nonce 값은 31.
withdraw에 nonce 값 31을 넣고
function withdraw(uint _nonce) public {
require(nonce == _nonce);
payable(msg.sender).transfer(address(this).balance);
트랜잭션을 날리면
위 조건을 충족하기 때문에
스마트컨트랙트에 있는 이더리움이
호출자에게 지급된다.
스마트컨트랙트의 잔고가 0으로 변경되면서
스마트컨트랙트가 갖고 있던 이더리움이 호출자에게 지급되었다.
해킹완료.
'블록체인' 카테고리의 다른 글
uint 자료형의 허점을 노린 스마트컨트랙트 해킹 (0) | 2021.07.28 |
---|---|
스마트컨트랙트 홀짝 해킹 #3 (0) | 2021.07.28 |
스마트컨트랙트에서 코인 훔치기 #2 (0) | 2021.07.27 |
이더리움 기반 ERC20 토큰 만들기 (0) | 2021.07.27 |
스마트컨트랙트 배포 (1) | 2021.07.26 |