2016년 PCTF 문제인 quick 문제이다. 프로그램은 swift언어로 짜여져있고 실행환경은 64비트 리눅스 환경이다.

프로그램을 실행시키면 아래와 같이 문자열을 입력받는다.



quick 파일을 Ida를 사용해서 분석해보면 main 함수에서 'Nope!'이란 문자열을 출력하는 부분을 찾을 수 있다. 아래의 사진에서 확인할 수 있듯이 'Nope!'이란 문자열을 출력하는 부분을 보면 조건문을 통해 'Good job!'이란 문자열을 출력하는것을 확인할 수 있다.

이 사진을 보면 'if(v35&1)'이라는 조거너문을 통해 문자열을 출력한다. 결국 v35가 1이여야 'Good job!'이란 문자열이 출력된다는 얘기가 된다. 사진의 맨 윗부분에서 확인할 수 있듯이 "v35 = sub_403660(v69,v68,v67)"이란 함수를 통해 값을 가진다. 이 함수를 살피기 전에 함수의 인자로 입력되는 v69,v68,v67이란 변수를 살펴보려 메인함수의 윗부분을 찾아 올라가면 아래 사진과 같이 v72,v71,v73이란 변수이다. 

v71,v72,v73이란 변수는 &unk_6054A8이란 주소에서 값을 가져온다.


&unk_6054A8의 값은 변수 v82이고 v82는 입력받는 문자열이란 것을 아래의 사진을 보면 알 수 있다.

이제 main함수에서 필요한 정보는 모두 알아냈기에 sub_403660함수를 살펴보아야 한다. 이 함수를 살펴보면 함수가 0이나 1만을 리턴한다는 것을 알 수 있다. 이 문제를 풀기 위해서는 1을 리턴해야하기 때문에 1을 리턴하는 조건을 찾아 분석해 보았다. 함수를 보면 0을 리턴하는곳이 2곳, 1을 리턴하는곳이 한곳이 있다.  1번째 0을 리턴하는 곳은 아래의 사진 부분이다.

위의 사진을 보면 v17과 v70이 다르면 0을 리턴하는데 해당하는 2개의 변수를 찾아 올라가보면 두개의 변수가 다른 값이 나올 수 없다는것을 알 수 있다. 위의 부분은 분석을 복잡하게 만들기 위해 일부러 문제 출제자가 만들어 놓은 부분인것으로 보인다.

위의 사진은 0을 리턴하는 부분과 1을 리턴하는 부분이 같이 있다. 이 부분은 이 함수의 마지막 부분으로 이 함수 내에서 v46와 v75가 같으면 1을 리턴하면서 문제가 풀리게 된다. 이제 v46과 v75를 따라 올라가다 보면 v51과 47의 영항을 받는다는 것을 알 수 있다. v51을 따라 올라가면 코드 내에서 데이터를 저장하는데 이 값과 관련이 있음을 알 수 있다. 해당 값은 아래의 사진과 같다.

v47을 따라 올라가보면 v113과 같은 값이고 v113은 아래 사진 부분에서 v72의 영향을 받는다는것과 v72가 sub_403510함수의 영향을 받는다는것을 알 수 있다.

sub_403510함수를 보기 전 v112와 v52를 보면 v52는 sub_402ad0함수의 영향을 받고 v112는 0값부터 시작하여 반복문이 돌 때마다 v52의 값을 가진다. v73,v74를 찾아 올라가면 입력값과 관련이 있단것을 알 수 있다. 이제 sub_403510함수를 보면 아래와 같다.

이 함수를 보면 입력값을 해당 연산을 통해 값을 바꿔준다는 것을 알 수 있다.

위의 과정을 정리하면 입력받은 문자열을 위의 함수(sub_403510)을 거친 값이 코드에서 데이터를 저장하는 부분(v39=80...)과 같으면 1을 리턴하여 'Good job!'이란 문자열을 출력한다. 이를 코드로 바꿔 연산하면 아래 사진과 같이 코드를 구현할 수 있다.

위의 코드를 실행해보면 아래와 같은 플래그를 얻을 수 있다.


By curons

'Reversing > CTF Write up' 카테고리의 다른 글

[PCTF 2016] quick  (0) 2017.06.01

+ Recent posts