Reversing | reversing.kr 1번 Easy Crack
Easy Crack 문제 풀이
본 문제는 reversing.kr를 통해서 풀어 보실 수 있습니다.
해답을 이해하며 생각을 해보면서 풀이 해보시길 바랍니다.
필자는 CTF에서 리버싱을 맡게 되어 이번에 처음 입문하게 되었습니다. 리버싱에 대해 무지하지만 CTF 문제 풀이를 하면서 하면 어느정도 되지 않을까라는 생각에 맨 땅에 헤딩하듯이 시작했습니다.
아주 기초적인 어셈블리어를 독학하고, 이렇게 시작하게 되어서 많이 불안하지만 모두가 할 수 있다는 것을 이렇게 말씀드리고 싶습니다.
디버깅 프로그램은 수도 없이 많지만 저는 x64dbg를 이용했습니다. 해당 프로그램이 더 우수하다? 이런거는 첫 입문이라 모르지만 눈에 보여서 이것으로 실습을 진행했습니다.
문제 내용
Easy Crack.exe 파일에 ‘ABCDEFG’를 입력하고 확인했을 때 Incorrect Password가 나온다.
해당 프로그램에서 원하는 값을 입력해야 풀릴 것으로 예상되고, 리버싱을 통해서 해당 값을 추측해야 할 것 같다.
따라서, x32dbg를 통해서 값을 검사하는 메소드에 Breakpoint를 걸고 확인해보겠다.
문제 풀이
상단에 Az 아이콘을 통해 Incorrect Password, Congratulation !! 문자열이 어디에 있는지 확인해본다.
- 옳은 값에서는 ‘Congratulation !!’ 나오는 것을 확인할 수 있다.
F9[프로그램 실행] 이후, Ctrl + K [이전 참조]를 통해 제일 처음 참조하는 곳을 확인해본다.
-
call dword ptr ds:[&GetDlgItemTextA]를 통해서 우리가 입력한 값을 받는 것을 확인 할 수 있다. -
그렇다면, 위 시스템 콜 이후 값을 비교하여 옳은 값을 체크 할 것으로 예상이 된다.
-
call dword ptr ds:[&GetDlgItemTextA]밑jne easy_crackme.401135를 보자
해당 어셈블리 우클릭 > G로 그래프화 시켜서 볼 수 있다.
-
401135는 우리가 ABCDEFG를 입력했을 때 패스워드가 틀렸다고 메시지를 띄운 것으로 보면, cmp를 통해서 여기로는 들어오면 안된다는 것을 알 수 있다.
-
401135와 call 사이의 cmp byte ptr ss:[esp+5], 61를 확인해보겠다. 이 위치에
F2[Break Point 설정]하고 확인해본다.
61은 아스키 코드로 ‘a’이고, 이 값과 byte 단위로 esp+5의 값을 비교한다는 것인데 esp+5의 값을 확인한다.
오른쪽 상단을 보면 레지스터의 값을 모두 볼 수 있다.
왼쪽 하단 메모리쪽에서 Ctrl+G[표현식] 단축키를 통해 ESP+5의 값을 입력하여 따라가본다.
우리가 입력한 값을 확인할 수 있다.
-
우리가 입력한
ABCDEFG가 있지만 ESP+5는 ‘B’이다. -
즉, 두번째 값이 ‘a’인지를 확인하는 것이므로 패스워드의 두번째 값은 a인게 확정이 되었다.
Password : _ a _ _ _ _ _ (몇 글자인지는 모른다)
1a2345를 대입해보고 레지스터를 확인해본다.
-
우리가 건너 뛰어야 할 401135이다. 하지만, 위
cmp구문을 통해 두번째 값이 같으므로ZF가 1이 되었음을 알 수 있다. -
ZF란, 제로 플러그로 해당 구문 연산 결과 값이 0면 1로 설정된다. 즉, CMP가 참이면 1, TEST가 참이면 1이란 것이다. -
jne는 jump if not equal으로,jnz와 동일한 역할이다. not equal, not zero는ZF로 체크하고 ZF 값이 0이면 jump하지만 이 값이 1이므로, 401135으로 빠지지 않는다.
두번째 값을 알았으므로, 그 다음 구문을 확인해본다.
필자는 여기 부분에서 2일정도는 삽질을 했다. 아무리 봐도 어느 부분에서 어떻게 체크가 되는지 아무리 봐도 몰랐다.
- [ESP+A]에서 4byte에 해당되는 주소를 ecx에 넣고, eax의 값을 TEST해서 401135를 한다? 이전에 있는 함수를 들어가서 확인해봐야 왜 eax로 체크를 하는지 알 수 있을 것 같다.
lea ecx, dword ptr ss:[esp+A]: esp+A의 위치에서 4byte에 해당되는 주소는 ecx에 넣는것을 의미한다.F7[다음단계로 진행]으로 넘어가면서 값을 확인해보면 위 처럼 ecx에 값이 들어가있는 것을 알 수 있다.
의문의 call 401150를 확인해본다.
-
해당 명령어를 메모리에서 확인해보면 5A FA 19 00인데 Little Endian 이므로 0019FA5A이다.
-
이는 또 다른 메모리 값을 가져와서 edi에 넣는 것인데 오른쪽 하단 스택 영역을 확인해보면 세번째 글자부터인 ‘2345’를 넣는 것을 확인 할 수 있다.
-
7줄 밑에
mov esi, dword ptr ss:[esp+C]가 있다.[esp+C]주소에 5y라는 값을 대입하는 함수가 존재한다. 즉, esi에 ‘5y’값을 넣는 것이다.
esi 값을 Ctrl+G로 확인해보면 5y값이 있을 것이다.
al(eax)에 ‘5y’값을 넣고, 우리의 입력 값의 세번째부터(345)를 비교한다. 비교한 값을 통해ja로 가게 되면 eax값이 FFFFFFFF되고, RET 이후TEST eax,eax로 실패 함수로 빠진다. 결국 세번째부터의 값이 5y가 되어야 한다는 것이다.
Password : _ a 5 y _ _ _ _ _
-
이번엔 ‘1a5y234’를 대입해서 확인해본다.
-
esi에 ‘R3versing’ 값이 들어갔다. 결국엔 이 값을 다시 비교하는 것으로 예상된다.
-
eax에 들어간 값 1byte(‘2’)를 dl에, esi에 들어간 값 1byte(‘R’)을 cmp한다.
이후에 계속 한 글자씩 비교하고, 해당 비교 값이 False면 실패함수로 빠지는 것을 보면 R3versing이 이후 값임을 알 수 있다.
Password : _ a 5 y R 3 v e r s i n g
- 우리는 두번째 값이 [esp+5]임을 맨 처음에 알았다. 갑자기 [esp+4]값을 비교한다? 맨 처음 값이 결국 ‘E’라는 것이다. 그리고 우리가 원하는 Congratulation !!이 있다. 패스워드는 결국 Ea5yR3versing이라는 것이다.
Password : E a 5 y R 3 v e r s i n g
이렇게 reversing.kr의 첫 문제를 2일동안 풀어봤다. 리버싱을 이렇게 입문해보니 삽질만 죽어라 한 거 같은데 덕분에 어셈블리에 대한 이해도와 갈피가 어느 정도 잡힌거 같아서 다행이다.