대충 열어보면 Visual C++ 컴파일러로 컴파일한듯한 바이너리가 나온다.
main함수를 습관적으로 찾다보면 0x4016B0이 나온다. 어떻게 찾나면, ExitProcess라는 함수가 맨 마지막에 호출되는데 이때 넣는 인수값이 "오류 코드"이다. 실행 후 %errorlevel% 환경변수로 쓰일 수 있는 값인데 여기 쓰이는 인자를 0x4016B0 함수에서 리턴한다. 이 함수를 main함수라 보면 된다.
main함수는 인자가 이렇다.
int argc, char *argv[], char *envp[]
argc가 2인지 검사한 후 맞으면 argv[1] (첫번 째 인자이다) 값을 하나하나 비교하는데, 첫글자부터 0x77, 0x69, 0x73, 0x65, 0x4F랑 비교해서 틀릴때마다 nope 를 출력하고 끝낸다.
코드로 설명해보자.
.text:004016BE cmp [ebp+arg_0], 2
.text:004016C2 jz short loc_4016E3
그렇다. arg_0(4를 뜻한다)이 2인지 체크해서 맞다면 4016E3으로 점프한다. 틀리면 argv[0]과 사용법을 출력한 후 바로 리턴한다.
4016E3으로 가보자.
.text:004016E3 mov eax, [ebp+arg_4]
.text:004016E6 add eax, 4
.text:004016E9 mov eax, [eax]
.text:004016EB movzx eax, byte ptr [eax]
.text:004016EE cmp al, 77h
.text:004016F0 jnz loc_4017A1
.text:004016F6 mov eax, [ebp+arg_4]
.text:004016F9 add eax, 4
.text:004016FC mov eax, [eax]
.text:004016FE add eax, 1
.text:00401701 movzx eax, byte ptr [eax]
.text:00401704 cmp al, 69h
.text:00401706 jnz loc_40178E
.text:0040170C mov eax, [ebp+arg_4]
.text:0040170F add eax, 4
.text:00401712 mov eax, [eax]
.text:00401714 add eax, 2
.text:00401717 movzx eax, byte ptr [eax]
.text:0040171A cmp al, 73h
.text:0040171C jnz short loc_40177B
.text:0040171E mov eax, [ebp+arg_4]
.text:00401721 add eax, 4
.text:00401724 mov eax, [eax]
.text:00401726 add eax, 3
.text:00401729 movzx eax, byte ptr [eax]
.text:0040172C cmp al, 65h
.text:0040172E jnz short loc_401768
.text:00401730 mov eax, [ebp+arg_4]
.text:00401733 add eax, 4
.text:00401736 mov eax, [eax]
.text:00401738 add eax, 4
.text:0040173B movzx eax, byte ptr [eax]
.text:0040173E cmp al, 4Fh
.text:00401740 jnz short loc_401755
.text:00401742 mov [esp+10h+var_10], offset aGood ; "good!"
.text:00401749 call puts
.text:0040174E mov eax, 0
그냥 보면 알 수 있다.
mov eax, [ebp+arg_4]
라는건..
ebp+arg_4, 즉 argv의 값을 eax에 넣는다.
그다음
add eax, 4
를 하는데, eax를 4만큼 더해준다. 즉 char *argv[]니까 argv[1]의 주소를 알려준다. 이 형식은 char *가 될것이다.
add eax, 1~4 (각각 다르다)
mov eax, [eax]
1, 2, 3, 4만큼 각각 더해준다. 0을 더하는건 생략되어있다.
그러니까 각각 argv[1][0], argv[1][1], argv[1][2], argv[1][3], argv[1][4]를 비교해서 wiseO면 된다.
wiseO의 아스키코드가 앞서 말했듯이 0x77, 0x69, 0x73, 0x65, 0x4F 이기 때문이다. 16진수로 그렇다.
실행해보면 good!이 뜬다.
cmd에서 그 경로로 가서
WinRev.exe wiseO
를 실행해보면 된다.
'writeup > 해킹캠프CTF 2014' 카테고리의 다른 글
2014 동계 해킴캠프 미니 CTF - 출제 실패한 문제 (0) | 2014.02.19 |
---|---|
2014 동계 해킹캠프 미니 CTF SleepSleepSleep 문제 풀이 (2) | 2014.02.19 |
2014 동계 해킹캠프 미니 CTF Optimize 풀이(python) (0) | 2014.02.19 |
2014 동계 해킹캠프 미니 CTF recovery 문제 풀이(python) (0) | 2014.02.19 |