반응형

Crackme 10.exe
0.01MB
10_patched.exe
0.01MB

 

 

프로그램을 실행하면 위와 같이 나온다.

 

 

slay라고 입력하니 Wrong C0d3!!!라고 한다.

 

 

가운데에 있는 ??? 버튼을 누르니 위와 같이 뜬다.

(위의 URL은 접속해보니 없다고 뜬다 ㅎㅎ)

 


분석

 

 

EP 코드이다.

 

IsDebuggerPresent 함수로 디버깅 중인지 체크하여 디버깅 중이라면 호출 후 eax의 값이 1이 되어 40102F 주소로 점프하여 프로세스를 종료한다.

 

즉, 안티 디버깅 문제인 것 같다.

 

 

문자열 찾기 기능을 이용하면 위와 같이 문자열들이 뜨는데 “Lucky”와 “Rigth number !!!” 문자열이 있다.

 

 

 

Lucky 문자열 부분으로 가면 위와 같이 성공했을 때와 실패했을 때의 문자열을 띄우는 부분들이 보인다.

 

 

그리고 스크롤을 조금 위로 올려보면 Serial 값을 생성하는 부분이 나온다.

 

위의 사진에서 4011A6부터 jmp 까지가 Serial 값을 생성하는 알고리즘이다.

 

4011D0 주소에서 eax와 ebx의 값이 같지 않으면 4011F1 주소로 점프인데, 4011F1 주소에는 Serial 값이 맞지 않았을 때의 문구를 띄운다.

 

그리고 eax와 ebx의 값이 같고 edi의 값이 Eh(=14)라면 4011DC 주소로 점프하는데, 4011DC 주소는 성공했을 때의 문구가 띄워지는 부분이다.

 

 

스크롤을 조금 더 올려 40114A 주소를 보면 스택 프레임 구문이 있다.

 

이 부분이 함수의 시작 부분인 것이다.

 

40114A 주소에 BP를 설정하여 Serial 값을 입력하고 Check 버튼을 눌렀을 때 바로 멈추게 한다.

 

 

Ctrl + F2 키로 재실행 하고 F9키를 눌러 EP 부분으로 이동한 후 F8 키를 사용해 디버깅을 진행하려고 하면

 

 

ExitProcess 함수 호출 부분으로 가져 프로세스가 종료된다.

 

즉, IsDebuggerPresent 함수 호출 후 eax의 값을 0과 비교한 후 같지 않으면 프로세스를 종료한다.

 

이 부분은 안티 디버깅 부분으로 디버깅이 힘들게 하기 위함이라 우회해야 한다.

 

 

Ctrl + F2 키로 재실행 후 필자는 IsDebuggerPresent 함수 호출 구문을 mov eax, 0 구문으로 수정했고, 이 수정은 재실행하면 사라지므로 저장하여 다른 파일을 생성하고 패치된 파일을 가지고 디버깅을 진행했다.

 

 

 

Ctrl + p를 누른 후 위의 화면에서 오른쪽 하단에 있는 파일 패치 버튼을 누른 뒤 10_patched.exe 라는 이름의 파일로 저장 후 10_patched.exe 파일을 디버거로 연다.

 

 

 

F9 키를 눌러 Serial 값 입력까지 실행하고 “slay”를 입력한 뒤 Check 버튼을 누르고 디버깅을 진행한다.

 

 

그러면 BP를 설정해뒀던 40114A 주소에 멈추게 된다.

 

이 부분부터 F8 키를 이용해 디버깅을 진행하면

401155 주소에서 strlen 함수를 호출하는데 인자로 사용자가 입력했던 값이 넘어간다.

 

즉, 이 부분은 우리가 입력한 값의 길이를 구하는 것이다.

 

 

strlen 함수 호출 후 eax에는 4가 들어가있다.

 

eax의 값을 ebp-4에 담고, ebp-4의 값과 Eh(=14)를 비교한 후 같지 않으면 4011F1 주소로 점프하여 Wrong 문구를 띄운다.

 

그렇다면 입력값이 14 글자여야 한다는 것이다.

 

입력값이 14 글자라면 401167 주소에서 스택에 “VaZoNeZ” 문자열을 넣고 4031A4를 넣은 뒤 strcpyA 함수를 호출한다.

 

즉, “VaZoNeZ” 문자열을 4031A4 주소에 복사하는 함수이다.

 

그 후 “VaZoNeZ” 문자열이 있는 403148 주소를 스택에 넣고, “VaZoNeZ” 문자열이 있는 4031A4 주소를 스택에 넣은 뒤 strcatA 함수를 호출한다.

 

즉, “VaZoNeZ” 문자열을 이어붙여 “VaZoNeZVaZoNeZ” 형태로 만든다.

 

그 후 40118E 주소에서 GetUserNameA 함수를 호출하여 Windows 사용자 계정 이름을 가져와 계정 이름이 0글자인지 비교 후 0글자이면 Wrong 문구를 띄우는 부분으로 점프한다.

 

사용자 계정 이름을 성공적으로 가져왔다면

 

edi에 Windows 사용자 계정 이름이 담긴 주소, ecx에 “VaZoNeZVaZoNeZ” 문자열이 담긴 주소를 담고

 

사용자 계정 이름의 맨 첫 글자를 eax에 담은 뒤

“VaZoNeZVaZoNeZ” 문자열에서 맨 앞 한 글자를 edx에 담고

 

edx의 값이 0인지 확인하여 결과가 0이라면 문자열을 모두 작업한 것으로 판단하고 4011BC 주소로 점프하여

 

ecx에 암호화된 Serial 값이 담긴 주소를, edx에는 입력했던 serial 값이 담긴 주소를 담은 뒤

 

edi는 0으로 만들고, ecx에서 한 글자를 eax에 담고, edx에서 한 글자를 ebx에 담은 후 eax와 ebx를 비교하여 다르면 실패 문구 출력 부분으로 가고, 같으면 edi와 E를 비교한 후 이 역시 같다면 성공 메세지 출력 부분으로 간다.

 

그리고 위에서 edx의 값이 0인지 확인하여 결과가 0이 아니라면 한 문자 한 문자씩 암호화 작업을 거친 뒤 다시 ecx에 담고 ecx에 담긴 “VaZoNeZVaZoNeZ” 문자열에서 다음 문자를 가리키도록 ecx의 값을 1씩 증가한 다음 4011A6 주소로 점프하여 “VaZoNeZVaZoNeZ” 문자열에서 1 증가한 인덱스에 해당하는 문자를 가져와 암호화 작업을 진행한다.

 


풀이

 

그렇다면 조건은 아래와 같다.

  1. 입력한 값이 14글자여야 한다.
  2. 이 14글자는 암호화 작업이 끝난 Serial 값과 동일해야 한다.

 

 

Ctrl + F2를 눌러 재실행 한 후 F9를 실행하여 Serial 값을 입력받는 부분에서 “a” 문자를 14개 입력한 후 Check 버튼을 누른다.

 

 

그러면 이전과 같이 함수 스택 프레임 부분에서 멈추게 되는데 이제 F8 키로 하나씩 명령을 실행해가면 40115D 주소의 cmp 명령은 패스될 것이다.

 

 

401167로 넘어왔다면 이제 “VaZoNeZ” 문자열을 복사하고 이어붙여 “VaZoNeZVaZoNeZ” 형태로 만들것이다.

 

 

401180 주소까지 실행되었다면, 이제 40118E의 함수 호출 명령을 통해 Windows 사용자 계정 이름을 가져올 것이다.

 

 

GetUserNameA 함수 호출 후 403224 주소에는 Windows 사용자 계정의 이름이 들어가있다.

 

그리고 401193 주소에서 ebp-8 주소에 있는 값과 0을 비교하는데 이는 사용자 계정 이름의 길이와 0을 비교하는 것 같다.

 

 

이제 위의 사진에 있는 부분을 통해 “VaZoNeZVaZoNeZ” 문자열의 각 문자들과 사용자 계정 이름의 맨 첫 글자 “q”를 가지고 암호화한 뒤 Serial 값이 나올 것이다.

(사용자 계정 이름은 사용자마다 다를 수 있으므로 사용자 계정 이름의 맨 첫 글자도 다를 수 있다.)

 

 

F8키를 통해 이 루프를 끝내면, 4031A4 주소에는 Serial 값이 들어가게 된다.

 

 

“H^VnD^ZOe]uKea”를 입력하면 Rigth number !!! 문구가 뜬다.

 


Serial key 생성 알고리즘

 

 

403324 주소에는 Windows 사용자 계정 이름 “qtt15”

4031A4 주소에는 “VaZoNeZVaZoNeZ”가 들어있다.

 

“qtt15” 문자에서 맨 첫 글자 ‘q’를 eax에 담고, “VaZoNeZVaZoNeZ” 문자열에서 문자 하나씩 edx에 담아

  1. 71(’q’) 과 dl의 값을 더하고
  2. 더한 값에 5와 xor 연산을 하고
  3. 그 값에 “VaZoNeZVaZoNeZ”이 들어있는 주소의 맨 끝자리 1byte를 더한 뒤 (”VaZoNeZVaZoNeZ” 문자열에서 문자 하나를 처리하고 나면 다음 문자를 가리키게 되므로 문자를 가리키는 주소가 1씩 증가한다. 즉, 처음에는 4031A4 주소의 맨 끝자리 1byte인 A4를 더하지만 이후에는 그 다음 문자의 주소인 4031A5의 끝자리 1byte인 A5를 그 이후에는 그 다음 문자의 주소인 4031A6 주소의 맨 끝자리 A6을 더하는 것이다.)
  4. 더한 값에서 1E를 뺀 값을 다시 4031A4 주소에 담는다.

 

위의 과정을 “VaZoNeZVaZoNeZ” 문자열에서 더 이상 가져올 문자가 없을 때까지 반복한다.

반응형

'전쟁 > crackme' 카테고리의 다른 글

Crackme #12  (0) 2022.06.24
Crackme #11  (0) 2022.06.24
Crackme #9  (0) 2022.06.23
Crackme # 8(Crack me by hackereh@!)  (0) 2022.06.23
Crackme #7  (0) 2022.06.22

+ Recent posts