CTF & Wargame(REVERSING)

[dreamhack] level 2 crc 문제 풀이

KWAKBUMJUN 2025. 2. 24. 22:17

바이너리 분석

crc 파일 실행 결과

crc 파일을 실행하면 위와 같은 결과를 얻을 수 있다. 특정 문자열이 출력되고 stage1이라는 문구와 함께 입력란이 나온다. 아무 값이나 넣어보면 nop 이라는 문구가 출력이 되는 것을 볼 수 있다. 입력란에 특정한 값을 넣어야 플래그를 주는 바이너리인 것 같다.

 

IDA로 바이너리 분석

해당 파일을 IDA를 통해 main 함수를 찾고 main함수를 디컴파일 하게 되면

main 함수를 디컴파일한 코드

위의 코드를 살펴보면 sub_1357() 함수의 반환값이 1이 아니거나 sub_14DC 함수의 반환값이 1이 아니면 nop이라는 문구를 출력한다. 그리고 다른 경우에는 flag를 출력하는 것을 알 수 있다. 따라서 해당 함수들이 1을 반환해야 한다는 것을 알 수 있다.

 

sub_1357() 함수 분석

sub_1357() 함수의 코드

1. v2라는 변수에 사용자가 입력한 값을 저장한다.

2. v4가 63보다 작거나 같으면 v7에 v2를 저장한다.

3. \x137(16진법 : 0x1337u) 으로 rand 시드값 고정

4. v0에 v7[i] + j 연산하고 저장 

5. v7에 (rand() - j) ^ v0 연산하고 저장

6. 만약 v7의 값이 byte_4020의 값과 다르면 0을 반환, 다른 경우에는 boring stage... isn't it? 문구 출력하고 1 반환

 

sub_1357() 함수 익스플로잇 

sub_1357() 익스플로잇 코드

어떤 값을 입력해야 sub_1357() 함수가 1을 반환하는지 알 수 있도록 브루트 포스를 통해 익스플로잇을 진행하였다. 코드의 핵심만 간단하게 설명하자면, 해당 함수의 코드에선 원래 사용자의 입력값을 v7이라는 변수에 담아두고 byte_4020 배열에 저장된 값들과 비교하였다. 하지만 우리는 어떤 값을 입력해야하는지 모르기 때문에 아스키 코드를 하나하나 대입하여 어떤 값이 byte_4020과 일치하는지 확인하며 입력값을 알아낸 것이다.

byte_4020 배열에 저장된 값

sub_14DC() 함수 분석

sub_14DC 함수를 디컴파일한 코드

1. v10에 사용자가 입력한 값을 저장함

2. v0에 time(0)의 값을 저장

3. rand의 시드를 v0의 값으로 고정

4. v8에 v10 + byte_40E0을 연산한 값을 저장

5. v10에 코드와 같은 연산을 수행한 값을 저장함

6. 만약 v10의 값이 byte_4060과 다르면 0을 반환하고 같다면 "This is better than stage 1 :p" 라는 문구를 출력하고 1을 반환한다.

 

sub_14DC() 함수 익스플로잇

일단 위의 디컴파일 코드에서 확인할 수 있는데, 우리는 byte_40E0에 저장된 값을 알아내야 한다.

해당 배열을 더블 클릭하여 안으로 들어가면 sub_1209 함수와 관련이 있는 것을 알 수 있다. 그렇다면 sub_1209 함수에 들어가보자.

sub_1209() 함수 디컴파일 코드

위의 코드를 보면 byte_40E0 배열에 랜덤한 값을 저장하는 것을 알 수 있다. 따라서 한번 그대로 작성해서 컴파일 해보자.

sub_1209() 함수 작성

sub_1209 함수를 그대로 작성하여 컴파일 해보면 언제 실행해도 계속 같은 값을 출력해주는 것을 확인할 수 있다.

출력값 :

103,198,105,115,81,255,74,236,41,205,186,171,242,251,227,70,124,194,84,248,27,232,231,141,118,90,46,99,51,159,201,154,102,50,13,183,49,88,163,90,37,93,5,23,88,233,94,212,171,178,205,198,155,180,84,17,14,130,116,65,33,61,220,135

 

따라서 byte_40E0 에는 위와 같은 값들이 들어있다는 것을 알 수 있다.

 

byte_4060 배열에 저장된 값
sub_14DC() 함수 익스플로잇 코드

위에서 알아낸 정보들을 토대로 코드를 작성하면 위와 같이 작성할 수 있다. 배열을 각각 작성하고 아까 sub_1357 함수를 익스플로잇 했던 코드와 같은 원리로 연산만 다르게 해주면 stage2의 flag도 알 수 있다.