ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 국가암호공모전 2018 (II-A)분야 8번 문제 풀이
    문제 풀이/2018 국가암호공모전 2020. 3. 6. 12:19

    주의: 아래 풀이에 해당하는 답은 틀렸을 수도 있습니다. 공식적으로 확인을 하기가 힘들어 풀이과정만 작성해보았습니다.

     

    아 문제는 여기서 다운 받을 수 있어요!

     

    이제 이 문제를 확인을 해보면 간단히 "runtime 스마트 컨트랙트"의 bytecode를 던져준 문제입니다. Solidity 언어로 작성되었고, 힌트로 verifyIt 이라는 함수를 포함한다는 정보를 제공했네요. 이 함수의 input과 output 정보가 있는데, 이 정보가 실제 문제를 풀 때 꽤 도움이 되었던 것으로 기억을 합니다.

    어쨌든 저는 이 문제를 보기전에 스마트 컨트랙트나 solidity 언어에 대한 이해가 전혀 없었기 때문에 막막했는데, 해당 bytecode를 hex decode 해보니까 "Ethereum Signed Message:" 라는 문자열이 박혀있습니다. 그래서 바로 검색을 해보니 해당 링크(ethereum stackexchange)를 찾을 수가 있었어요. 애초에 verify 함수 내에서 ecrecover 함수를 불러서 "verify a cryptographic signature that was produced by an Ethereum address key pair" 를 하는것이 일반적인 패턴으로 보입니다. 특히 verify의 input이 address이고 output이 bool 인것을 보아 특정 address를 넣었을 때 맞는지 아닌지 여부를 체크하는 함수로 보이므로, 문제의 의도가 이를 바탕으로 해결하는 것임을 알 수 있겠습니다.

    이제 해당 정보를 바탕으로 열심히 리버싱을 해서 대회때 작성한 답안을 아래에 써보았습니다.

     

    ------------------------

    A. evm_runtime.bin.hex 분석

    https://etherscan.io/opcode-tool에서 bytecode를 opcode로 변환할 수 있는 disassembler를 제공한다. 이를 이용하여 제시된 bytecode를 변환하여 이를 분석하였다. opcode로 변환된 결과는 evm_runtime_ins.txt에 첨부하였다.

    evm_runtime_ins.txt
    0.01MB

    Opcode로 변환된 결과를 확인하면 일련의 Instruction이 수행된다는 것을 알 수 있다. i번째 instruction을 [i]로 표기하겠다. 아래에 opcode 분석 과정을 제시하였다.

    1. [17]에서 verifyIt 함수를 호출할 준비를 한다.

    2. [57]에서 0x4478f6d9의 값은 “verifyIt(address)”라는 string의 KECCAK-256 해싱 결과와 같다. 다시 말하여 KECCAK256(“verifyIt(address)”)의 결과와 같다. 그러므로 제시된 bytecode는 모두 verifyIt 함수에 대한 정보를 담고 있음을 알 수

    있다.

    3. [137]부터 verifyIt 함수의 실행이 시작된다. 실행하기 전 다양한 메모리 값들을 PUSH한 후 MSTORE 하는 과정을 거친다.

    4. 3.의 과정 중 [181]의 메모리 값에는 다음과 같은 string이 저장된다.

    “\x19Ethereum Signed Message:\n32\x00\x00\x00\x00”. 이는 Solidity 함수의 ‘ecrecover’와 관련된 함수이다. ecrecover 함수는 특정 string이나 byte의 signature을 생성하는 4개의 인자를 받는 함수이다. 결과로 address 자료형을 반환한다.

    https://ethereum.stackexchange.com/questions/15364/ecrecover-from-geth-and-web3-eth-sign을 참고하였다.

    5. [181] PUSH 후 다음의 값을 PUSH한다. 0x4f5bc00a7951f210ffb34117bef14856553bbe04df8e38205e57aac4736a2fef

    6. [262]까지 keccak256 함수를 실행한다. Solidity 로 keccak256 함수를 컴파일하여 유사한 bytecode를 생성하는 것을 관찰하였기 때문이다. 따라서 코드는 다음과 같다. keccak256(“\x19Ethereum Signed Message:\n32\x00”,0x4f5bc0...

    7. [294]부터 ecrecover 함수가 실행된다. Solidity로 ecrecover 함수를 컴파일하여 유사한 bytecode를 생성하는 것을 관찰하였다. [421], [458], [496]에 3개의 인자를 대입 후, ecrecover 함수가 실행되는 instruction이전에 앞서 호출하였던 keccak256 함수의 return value를 인자로 넣어주는 부분이 있기에 ecrecover 함수의 모든 인자가 준비되었다.

    8. 마지막으로 함수의 return 값과 user가 넣어준 address를 비교하여 일치하면 true, 그렇지 않으면 false를 반환한다.

     

    B. verifyIt 함수의 return value를 true로 만들기

    A.의 분석 결과를 바탕으로, 제시된 bytecode가 true를 반환하기 위해서는 ecrecover 함수가 반환한 address와 user가 input으로 대입한 address가 같아야 한다. 분석 결과를 바탕으로 작성한 Solidity 코드를 작성하여 evm_runtime_code.txt에 첨부하였다. https://remix.ethereum.org/에서 제공하는 remix-solidity IDE를 사용하여 작성한 코드를 컴파일하여 ecrecover 함수가 반환하는 address를 확인하였다. 이제 주어진 bytecode를 실행하여 address 값을 input으로 사용하면 true의 결과를 반환 받아 문제에서 제시한 조건을 만족할 수 있다. 필요한 address값은 다음과 같다.

    input value(address): 0x627306090abaB3A6e1400e9345bC60c78a8BEf57

    다음은 remix-solidity IDE를 사용하여 컴파일 후 실행하여 반환된 address를 확인하는 과정이다.

     

    remix solidity IDE

    -------------------------------------------------

     

    위의 풀이로 얻어낸 해답을 bytecode를 다시 실행시켜서 맞나 체크를 해보고 싶었는데, 다양한 시도를 해보았지만 해낼 수 없었습니다... 그래서 해당 답이 맞는지 틀린지는 아직까지 모릅니다. 혹시 문제를 푸신 분이 계시면 댓글로 작성 부탁드립니다 ^^

    댓글

Designed by Tistory.