rev-basic-0 LEVEL 1
1. 문제 정보
1.1 문제 이름
rev-basic-0 (dreamhack)
1.2 문제 설명
문제를 실행하면 문자열을 받도록 되어있다. 문자열을 넣었을 때 프로그램 내부에서 검증을 거쳐 검증이 통과하면 Correct 통과하지 못하면 Worng을 출력한다.
1.3 문제 분야
◼️ 리버싱
2. 풀이
2.1 정적 분석
Shift + f12를 눌러 문자열을 검색하였다.
'Input :', 'Correct', 'Wrong' 등 다양한 문자열이 존재를 한다. 검증부분이 통과할 때 Correct 부분이 출력될 것이므로 이 부분을 분석하겠다. 더블클릭으로 Correct 부분에 접근한다.
x를 통해 문자열이 어떤 함수를 호출하는지 알 수 있다.
그림 3번을 보면 main+57번째에서 호출하는 것을 알 수 있다. main함수로 들어가보도록 하겠다.
main 함수를 디컴파일 하면 그림 4와 같이 내용이 나오게 된다.
먼저 sub_140001190 함수를 분석 해 보겠다.
va_start() 함수와 _acrt_iob_func(1)함수를 사용한다.
_acrt_iob_func의 인자가 1이므로 stdout 스트림을 가져오므로 출력함수인 printf 함수로 유추가 가능하다.
즉, printf 함수로 'Input :' 문자열을 출력한다.
그 다음 sub_1400011F0 함수를 분석 해 보겠다.
이것또한 va_start() 함수와 _acrt_iob_func() 함수를 사용한다. 하지만 _acrt_iob_func의 인자가 0이므로 stdin 스트림을 가져오므로 printf의 반대인 입력함수 scanf임을 유추할 수 있다.
즉, scanf 함수로 v4에 우리가 입력한 문자열을 저장할 것이다.
scanf로 입력받은 v4를 sub_140001000의 인자로 호출한 뒤 "Compar3_the_str1ng"와 비교를 한다.
strcmp함수는 두개의 문자열이 같으면 1, 다르면 0을 출력하는 함수이다.
해당 함수의 반환값이 0이면 Wrong을 출력하고, 1이면 Correct를 출력하므로 correct를 출력하기 위해서는 "Compar3_the_str1ng" 문자열을 입력해야 한다.
flag값은 "Compar3_the_str1ng"이다.
다음으로는 동적분석으로 한번 확인해 보도록 하겠다.
2.2 동적 분석
x64dbg를 이용해 문제를 열어본다.
문자열을 검색하여 검증부분에 접근하도록 하겠다.
Correct 부분을 클릭하여 해당 부근에 접근한다.
Correct 부근에 접근을 하니 아래에 Wrong을 출력하는 곳도 발견을 하였다.
위에서 부터 분석을 하면 "input : "문자열을 rcx에 저장하고 call로 호출을 한다.
ida에서 분석한것 과 같이 _acrt_iob_func 함수가 보이고 ecx에 1을 넣고 함수를 실행하므로 _acrt_iob_func(1)이 될것이다.
따라서 이 call은 printf 호출임을 알 수 있다.
두번째 call 역시 _acrt_iob_func 함수가 보인다. 하지만 그림 12번과 다르게 _acrt_iob_func 함수를 호출하기 전 ecx를 xor로 0으로 초기화를 하였다. 즉, _acrt_iob_func(0)이 되는 것이다.
따라서 이 call은 scanf 호출임을 알 수 있다.
세번째 call을 분석하면 rdx에 "Compar3_the_str1ng"문자열 저장하고 rcx에는 rsp+40위치인 우리가 입력한 값을 저장한 후 strcmp명령어를 실행한다.
그 후 문자열이 다른 경우 ret으로 0을 저장하고, 문자열이 같은 경우 ret 으로 1을 저장한다.
그림 14에서 ret된 값을 test eax, eax로 eax끼리 and연산을 한다. eax가 0일경우 and 연산을 하면 0이 나와 zero 플래그가 설정이 되어 점프를 하여 Wrong을 출력한다.
만약 eax가 1일경우 and연산을 하면 0이 아니므로 zero 플래그가 설정되지 않기 때문에 점프를 하지 않아 Correct를 출력한다. 따라서 eax가 1이 되도록 해야하므로 그림 14에서 ret값이 1이 되어야한다. ret값이 1이 되려면 strcmp를 할때 우리가 입력한 문자가 "Compar3_the_str1ng"이 되어야한다.
따라서 정답은 "Compar3_the_str1ng"이다.