Codegate 2014 예선전 리버싱 200점 문제 dodoCrackme의 Writeup입니다. 

 

 

 

우선 Exeinfo를 통해 파일의 정보를 봅니다.

 

 

파일은 64비트 환경의 리눅스 실행파일임을 알 수 있습니다.

파일 실행을 위해 64비트 리눅스를 설치했습니다.

Ubuntu Install : ftp://ftp.kaist.ac.kr/ubuntu-cdimage/ubuntu-gnome/releases/13.04/release/

 

리눅스에서 파일을 실행시켜봤습니다.

 

 

하드코딩된 패스워드를 찾아서 입력하면 풀릴 것 같네요.

 

리눅스 툴 중 strace를 통해 파일에서 사용하는 시스템콜 함수를 찾아봅니다.

strace Joinc : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/1/strace

 

 

출력되는 문자열이 보이고 그 뒤 read함수를 통해 패스워드를 입력받는 것을 볼 수 있습니다.

그럼 이제 64비트 환경에서 read()는 어떻게 호출되는지 살펴봅시다.

linux system call table for x86-64 : http://blog.rchapman.org/post/36801038863/linux-system-call-table-for-x86-64

 

 

여기서 rax는 확장된 64bit register를 의미하므로 각각 eax, edi, esi, edx와 같다고 보시면 됩니다.

그럼 eax값이 0인 부분을 찾는다면 read()를 찾을 수 있겠네요.

IDA에서 eax가 0인 값을 찾습니다.

 

 

하나가 바로 나오는데 위의 linux system call table과 비교해봅니다.

read()와 일치하는 레지스터를 사용하고 있으니 맞게 찾은 것 같습니다.

 

 

여기서 read()의 size_t count 값으로 1을 받아오는 것으로 보아 1byte만을 가져오는 것 같습니다.

그리고 read() 실행 시 이미 입력된 문자열과 비교를 해야하므로 어딘가에(버퍼?) 키 값인 문자열이 올라올 것입니다.

따라서 해당 주소 부분에 브레이크 포인트를 걸고 디버깅을 해보겠습니다.

 

 

사용한 명령어들은 다음과 같은 의미입니다.

gdb -q : gdb 버전정보 출력 없이 실행

b : breakpoint - 브레이크 포인트 설정

r : run - 프로그램 실행

i : info - 보통 r과 함께 정보를 보는데 사용

r : registers 약자

x : examine(조사하다) 약자

x/100c $rbp : rbp의 내용 100개를 character형으로 출력

 

위 system call table에서 read()의 버퍼에 rbp를 넣었으므로 버퍼 확인을 위해 rbp의 내용을 출력해봤습니다.

하지만 알아보기 힘들게 나왔지만 '\000'값들 사이에 영어가 보입니다.

다른 표현 방법을 알아보기 위해 gdb의 도움말을 찾아보았습니다.

 

 

보기 쉬운 조합으로 찾아보다가 다음과 같이 나오는 것을 확인했습니다.

 

 

이제야 문자열이 좀 보이네요.

'H4PPY_C0DEGaTE_2014_CU_' 뒤로 뭔가 더 있겠지만 짤린 듯 해서 200개까지 출력해보았습니다.

 

이 이후로는 '\000'값만 있어서 잘랐습니다.

 

이제 모든 문자열이 다 보이고 'H4PPY_C0DEGaTE_2014_CU_1N_K0RE4'라는 값이 보입니다.

 

 

q명령으로 gdb를 빠져나와 crackme에 값을 입력했더니 성공한 것을 볼 수 있었습니다. :)

 

 

이 문제는 대회 당시 배점도 낮고, 다른 팀들은 다 풀어서 어렵지 않다고 생각했는데 결국 못 풀었던 문제였습니다.

대회 문제를 많이 풀어 본 경험이 있었다면 그래도 쉽게 풀 수 있지 않았을까 생각이 드네요..ㅠㅠ

 

도움이 된 블로그








+ Recent posts

티스토리 툴바