전체 글 (34)
2024-11-21 10:47:01

이번 글에서는 솔리디티 프로그래밍과 보안을 입문하기 위한 이더리움의 기본 개념과 특징을 서술한다.

1. 솔리디티란?

이더리움에서 제공하는 스마트 컨트랙트 개발 언어. 이더 [ETH]를 보내고 받는 데에 이용된다. 여기서 등장하는 용어는 낯설 수 있지만 추후에 다시 설명한다.

  • EVM [Ethereum Virtual Machine]을 타깃으로 디자인되었고
  • 튜링 완전성: 어떤 프로그래밍 언어 및 머신이 튜링 머신과 동일하 계산 능력으로 문제를 풀고 해결할 수 있다는 의미.
    • 솔리디티는 자체적인 튜링 완전 언어들을 지원하기 때문에 사실상 가능한 모든 형태의 거래를 코드로 작성할 수 있다.

2. 이더리움이란?

암호화폐라고 하면 떠오르는 것이 크게 두 개 있다.

  1. 비트코인
  2. 이더리움

거래를 해본 사람도 있을 것이고 들어만 본 사람도 있을 것이다. 적어도 프로그래밍 및 블록체인을 몰라도 이름은 알 것이라 생각한다. 사실 이더리움을 개념적으로 이해하는 것은 상당히 복잡하다(

적어도 나는 그렇다

)

우선 암호화폐를 정의할 필요가 있겠다.
암호화폐는 공개키 암호화를 통해 안전하게 전송하고 해시 함수를 이용해 쉽게 소유권을 증명해낼 수 있는 자산이다. 다르게 말하면 검산은 쉬운데 역산은 어렵다는 것이다.

이더리움도 비트코인과 같은 암호화폐이다.
그러나 비트코인은

    1. 튜링 불완전성: 스크립트로 작성된 비트코인은 비교적 단순한 편이라 화폐 이상의 기능을 수행하기 어렵다.
    1. 상태표현제한: 표현 가능한 상태가 사용완료 or 안함 둘뿐이라 잔액을 일부 남기고 계약이 불가하다.
    1. Blockchain-blindness: UTXO(비트코인 잔액)이 블록헤더 데이터들을 해독하지 못해서 화폐 기능 이외 다른 분야의 어플리케이션을 만들기 어렵다.

위처럼 비트코인은 단순하고 제한적이다.
이러한 배경에서 더 세련된 언어로 분산 어플리케이션 [Decentralized Application; dApp] 을 이용할 수 있는 플랫폼을 만들자! 는 시도에서 나온 게 블록체인이다.

이것들을 구현하기 위해 사용되는 기술들이 있다.
비트코인은 스크립트를 사용하여 튜링불완전한데,
이더리움은

  • Solidity
  • Serpent
    등을 이용하기 떄문에 튜링완전하고, 이게 곧 Smart Contract를 가능하게 한다.

3. 이더리움의 기술

GAS

이더리움 플랫폼에서는 이더(ether)라는 자체 화폐토큰이 있고 이더를 가지고 GAS라는 어플리케이션을 구입한다. 이것은 이더리움이 Smart Contract를 하는 데 연산력과 저장공간 제공을 위한 연료로 쓰인다.

Smart Contract

블록체인 기술을 활용해 제3의 인증기관 없이 개인 간 계약이 이루어질 수 있도록 하는 기술이다.

스마트 컨트랙트는 다음과 같은 성질을 가진다.

    1. 관측가능성(obsevability): 서로의 계약 이행 가능성을 관찰하거나 성과를 입증할 수 있어야 함
    1. 검증가능성(verfifiability): 계약을 이행하거나 위반할 경우 계약 당사자들이 이를 알 수 있어야함
    1. 프라이버시(privity): 계약 내용은 계약에 필요한 당사자만 알 수 있어야 함
    1. 강제 가능성(enforceability): 계약이 이루어질 수 있도록 구속력이 있어야 함

4. 이더리움의 블록

이더리움의 블록은 함수처럼 작동한다.

124번 블록이 상태 1에서 2로 바꿔주는 역할을 하는데,
여기서 상태 1은 블록1

123이 연결된 블록체인 상태를 의미하고, 상태 2는 1

124가 연결된 블록체인 상태이다.
이가 의미하는 건 블록이 추가될 때마다 상태가 계속해서 변한다는 것이다.

이러한 상태 변환 연산을 수만 개의 노드가 하나의 컴퓨터처럼 연산한다. 수만 개의 노드가 똑같은 연산을 중복하여 똑같은 데이터를 가지고 항상 동일한 상태의 합의에 도달한다.

이에 필요한 연산력을 아까 말했던 GAS의 구입을 통해 제공받는다.

5. 이더리움과 계좌

이더리움의 구성은
이더리움 = 이더 + 계좌 + GAS
로 표현될 수 있다.

아까도 언급했지만

  • 이더: 이더리움의 자체토큰
  • 계좌: 말그대로 이더를 가지고 있는 계좌
  • GAS: 연산력에 필요한 연료와 같은 것

이 중 계좌는 다음과 같이 다시 구분된다.

외부 소유계좌(EOA)

  • 개인키를 가지고 통제하는 계좌
  • 이더를 주고받을 수 있는 일반적인 은행 계좌와 비슷

계약계좌

  • 개인키가 아니라 계약 코드에 의해서 통제
  • 계약 코드계약 정보 저장 공간을 가지고 있고, 내부 저장공간의 데이터를 읽고 쓸 수 있다.

EOA는 일반적인 은행 계좌와 비슷한 개념이지만, 계약계좌는
GAS를 구입해 계약 코드를 걸어놓으면 코드의 조건이 만족될 때에만 계약계좌가 메시지를 받고 계약의 내용이 실행된다.

예를 들면 '과속을 했을 때' '1ETH를 부과하는 계약 코드'를 걸어놓으면 과속을 했을 때 메시지를 받고 1ETH가 계약계좌에서 빠져나간다.
이러한 계약 코드는 이더리움 플랫폼에서 정해놓은 헌법과도 같아서 누구도 통제가 불가능하다.

'보안 > web3' 카테고리의 다른 글

web3 시작하기  (0) 2024.11.18
2024-11-18 09:34:11
2024-11-12 20:05:18

https://dreamhack.io/wargame/challenges/1364

[datestring

Description Time is gold... but shell is diamond. Flag Format: DH{...}

dreamhack.io](https://dreamhack.io/wargame/challenges/1364)

파일을 다운받으면 따로 주어진 소스코드는 없다.

실행시

./datestring
Calendar v0.1
Year: 2024
Month: 1 
Day: 12
Hour: 19
Minute: 46
Second: 19
Formatted date: Fri Jan 12 19:46:19 2024

상단과 같이 나옴.

먼저 gdb에 넣어봤었는데 flag라는 함수가 있다는 걸 찾음.

flag호출 시 쉘을 취득가능한듯함.

flag호출 조건을 ida로 좀 더 편하게 볼 수 있는데 결론적으로

printf("Formatted date: %s", v16);
  if ( monthminusone == 11 && date_1 == 25 && !v15 && valuezero )
  {
    puts("A Present for Admin!");
    flag("A Present for Admin!");
  }

변수명을 조금 바꿔보면 month: 12, date: 25이고, 처리해야되는 부분은 !v15 이면서 valuezero를 0이 아닌 값으로 바꾸기.

 v15 = (year / -100 + year / 4 + 23 * month / 9 + date + 4 + year / 400) % 7;
  calendar(v16, v11);

v15는 이 부분을 처리해줘야함. 저게 0이 되면 된다.
해석하면 12/25가 일요일인 연도를 찾는 문제다

그런데 아무 연도나 입력하면 valuezero값이 안 덮어져서 플래그를 얻을 수 없다.
calendar를 이용해 버퍼오버플로우를 일으켜서 0이 아니도록 덮어버리면 될 일이다.
따라서 특정 연도라기보단 매우 크면서 12/25가 일요일인 연도 찾기를 하면됨
100000000 이상이면 무관하다.

가장 작은 친구로는

Year: 100000005
Month: 12
Day: 25
Hour: 2
Minute: 2
Second: 2
Formatted date: Sun Dec 25 02:02:02 100000005
A Present for Admin!

가 있겠다.
저 문구가 나오면 쉘을 취득했으니 플래그를 cat 하면 끝