본문 바로가기
Wargame Write-Up/Reversing.kr

[Reversing.kr] (Reversing) Easy Keygen 풀이

by snwo 2020. 3. 18.

다운받고 압축을 풀면, Serial = 5B134977135E7D13 인 Name 을 찾으라한다.


Name 과 Serial 을 입력받는걸 볼 수 있다.


32bit EXE 파일이므로, 올리디버거로 연다음, 문자열검색으로 입력받는곳으로 가보자.


0040102E  |.  68 60804000   PUSH OFFSET 00408060                     ; ASCII "Input Name: "
00401033  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
00401035  |.  66:AB         STOS WORD PTR ES:[EDI]
00401037  |.  AA            STOS BYTE PTR ES:[EDI]
00401038  |.  C64424 10 10  MOV BYTE PTR SS:[ESP+10],10
0040103D  |.  C64424 11 20  MOV BYTE PTR SS:[ESP+11],20
00401042  |.  C64424 12 30  MOV BYTE PTR SS:[ESP+12],30
00401047  |.  E8 6D010000   CALL 004011B9
0040104C  |.  83C4 04       ADD ESP,4
0040104F  |.  8D4424 10     LEA EAX,[ESP+10]
00401053  |.  50            PUSH EAX                                 ; /Arg2 => OFFSET LOCAL.74
00401054  |.  68 5C804000   PUSH OFFSET 0040805C                     ; |Arg1 = ASCII "%s"
00401059  |.  E8 44010000   CALL 004011A2                            ; \Easy_Keygen.004011A2

Name을 입력받는다. buf = ESP+10


00401077  |> /83FE 03       /CMP ESI,3
0040107A  |. |7C 02         |JL SHORT 0040107E
0040107C  |. |33F6          |XOR ESI,ESI
0040107E  |> |0FBE4C34 0C   |MOVSX ECX,BYTE PTR SS:[ESI+ESP+0C]
00401083  |. |0FBE542C 10   |MOVSX EDX,BYTE PTR SS:[EBP+ESP+10]
00401088  |. |33CA          |XOR ECX,EDX
0040108A  |. |8D4424 74     |LEA EAX,[ESP+74]
0040108E  |. |51            |PUSH ECX
0040108F  |. |50            |PUSH EAX
00401090  |. |8D4C24 7C     |LEA ECX,[ESP+7C]
00401094  |. |68 54804000   |PUSH OFFSET 00408054                    ; ASCII "%s%02X"
00401099  |. |51            |PUSH ECX
0040109A  |. |E8 B1000000   |CALL 00401150
0040109F  |. |83C4 10       |ADD ESP,10
004010A2  |. |45            |INC EBP
004010A3  |. |8D7C24 10     |LEA EDI,[ESP+10]
004010A7  |. |83C9 FF       |OR ECX,FFFFFFFF
004010AA  |. |33C0          |XOR EAX,EAX
004010AC  |. |46            |INC ESI
004010AD  |. |F2:AE         |REPNE SCAS BYTE PTR ES:[EDI]
004010AF  |. |F7D1          |NOT ECX
004010B1  |. |49            |DEC ECX
004010B2  |. |3BE9          |CMP EBP,ECX
004010B4  |.^\7C C1         \JL SHORT 00401077

ESP+0C : 0x10,0x20,0x30 이 순서대로 저장되어있다.

Index 0,3,6~~ == 0x10 과 XOR

Index 1,4,7~~ == 0x20 과 XOR

Index 2,5,8~~ == 0x30 과 XOR

XOR 한 값은, 0x401150 함수에 의해, 문자열로 바뀌어 ESP+74 배열에 저장된다.


004010C1  |.  68 44804000   PUSH OFFSET 00408044                     ; ASCII "Input Serial: "
004010C6  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
004010C8  |.  E8 EC000000   CALL 004011B9
004010CD  |.  83C4 04       ADD ESP,4
004010D0  |.  8D5424 10     LEA EDX,[ESP+10]
004010D4  |.  52            PUSH EDX                                 ; /Arg2 => OFFSET LOCAL.74
004010D5  |.  68 5C804000   PUSH OFFSET 0040805C                     ; |Arg1 = ASCII "%s"
004010DA  |.  E8 C3000000   CALL 004011A2                            ; \Easy_Keygen.004011A2

이제 위에서 생성된 Serial 과 비교할 Serial 을 입력받는다.


004010EA  |> /8A10          /MOV DL,BYTE PTR DS:[EAX]
004010EC  |. |8ACA          |MOV CL,DL
004010EE  |. |3A16          |CMP DL,BYTE PTR DS:[ESI]
004010F0  |. |75 1C         |JNE SHORT 0040110E
004010F2  |. |84C9          |TEST CL,CL
004010F4  |. |74 14         |JZ SHORT 0040110A
004010F6  |. |8A50 01       |MOV DL,BYTE PTR DS:[EAX+1]
004010F9  |. |8ACA          |MOV CL,DL
004010FB  |. |3A56 01       |CMP DL,BYTE PTR DS:[ESI+1]
004010FE  |. |75 0E         |JNE SHORT 0040110E
00401100  |. |83C0 02       |ADD EAX,2
00401103  |. |83C6 02       |ADD ESI,2
00401106  |. |84C9          |TEST CL,CL
00401108  |.^\75 E0         \JNZ SHORT 004010EA

2020/03/18 - [Wargame Write-Up/Reversing.kr] - [Reversing.kr] (Reversing) Easy Crack 풀이

 

[Reversing.kr] (Reversing) Easy Crack 풀이

문제를 눌러 Easy_CrackMe.exe 파일을 다운받자. 일단 die ( Detect It Easy ) 로 열어보면, 32bit 파일임을 알 수 있다. 비밀번호를 입력하는칸과, 확인 버튼이 있는걸 알 수 있다. ollydbg 로 문자열을 찾아..

snwo.tistory.com

 

저번문제와 비슷한 구조로, 2글자씩 비교한다. 맞으면 Correct 를 출력한다.

 

Correct


시리얼 생성원리를 알았으니,

5B134977135E7D13 이 생성될때 Name 을 구하는 소스를 작성하자


1
2
3
4
5
6
7
8
9
ar=[0x10,0x20,0x30]
ar_c=0
serial='5B134977135E7D13'
Name=''
for i in range(0,16,2):
    Name+=chr(int(serial[i:i+2],16)^ar[ar_c])
    ar_c=(ar_c+1)%3
 
print(Name)

Serial 은 문자열이지만, 16진수가 그대로 저장되는거니까

Name의 길이= len(Serial)/2

두글자씩 가져와서 10,20,30 과 다시 XOR 해서 복호화 할 수 있다.