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

[Reversing.kr] (Reversing] Position 풀이

by snwo 2020. 3. 25.

 

키젠문제이다. 시리얼이 76876-77776 일때의 name 을 찾으라한다.

총 4글자로, 마지막글자는 p 이고, 여러값이 나올수있단다


 

입력폼이있다. default 문자열을 확인해두자.


 

MFC 32bit EXE 파일이다. 올리디버거로 분석해야겠다.


글자를 입력했을때 반응하는함수이다.

0x01191740 함수에서 리턴한값으로

Correct인지 Wrong 인지 텍스트를 설정한다.


[ 0x01191740 ]


0119178E  |.  50            PUSH EAX                                 ; /Arg1 = 4
0119178F  |.  81C1 30010000 ADD ECX,130                              ; |
01191795  |.  C645 FC 02    MOV BYTE PTR SS:[EBP-4],2                ; |
01191799  |.  FF15 80321901 CALL DWORD PTR DS:[<&mfc100u.#7006>]     ; \mfc100u.70FD3C63
0119179F  |.  8B4D E8       MOV ECX,DWORD PTR SS:[EBP-18]
011917A2  |.  8379 F4 04    CMP DWORD PTR DS:[ECX-0C],4
011917A6  |.  74 31         JE SHORT 011917D9

 

첫번째관문, #7006 호출 후, 4와 비교한다. #7006 은 Getwindowtext 함수를 호출한다.

즉, name 을 가져온뒤, 길이를 4와 비교하는것이다.


011917E0  |> >56            /PUSH ESI
011917E1  |. |8D4D E8       |LEA ECX,[EBP-18]
011917E4  |. |FF15 C4321901 |CALL DWORD PTR DS:[<&mfc100u.#4478>]
011917EA  |. |66:83F8 61    |CMP AX,61
011917EE  |.^|72 B8         |JB SHORT 011917A8
011917F0  |. |56            |PUSH ESI
011917F1  |. |8D4D E8       |LEA ECX,[EBP-18]
011917F4  |. |FF15 C4321901 |CALL DWORD PTR DS:[<&mfc100u.#4478>]
011917FA  |. |66:83F8 7A    |CMP AX,7A
011917FE  |.^|77 A8         |JA SHORT 011917A8
01191800  |. |46            |INC ESI
01191801  |. |83FE 04       |CMP ESI,4
01191804  |.^\7C DA         \JL SHORT 011917E0

 

#4478 함수는 AX 에 push한 인덱스의 문자를 반환해준다. 4글자가 0x61 ~ 0x7a 범위에있어야한다.

아스키코드로 변환해보면, a~z 로 모두 소문자여야한다.


01191806  |> /33F6          /XOR ESI,ESI
01191808  |> |3BFE          |/CMP EDI,ESI
0119180A  |. |74 1C         ||JE SHORT 01191828
0119180C  |. |56            ||PUSH ESI
0119180D  |. |8D4D E8       ||LEA ECX,[EBP-18]
01191810  |. |FF15 C4321901 ||CALL DWORD PTR DS:[<&mfc100u.#4478>]
01191816  |. |57            ||PUSH EDI
01191817  |. |8D4D E8       ||LEA ECX,[EBP-18]
0119181A  |. |66:8BD8       ||MOV BX,AX
0119181D  |. |FF15 C4321901 ||CALL DWORD PTR DS:[<&mfc100u.#4478>]
01191823  |. |66:3BC3       ||CMP AX,BX
01191826  |.^|74 80         ||JE SHORT 011917A8
01191828  |> |46            ||INC ESI
01191829  |. |83FE 04       ||CMP ESI,4
0119182C  |.^|7C DA         |\JL SHORT 01191808
0119182E  |. |47            |INC EDI
0119182F  |. |83FF 04       |CMP EDI,4
01191832  |.^\7C D2         \JL SHORT 01191806

 

한 문자씩가져와 나머지문자들과 비교해, 똑같은 글자가 있는지 체크한다.


0119183A  |.  52            PUSH EDX                                 ; /Arg1 = 0
0119183B  |.  81C1 A4010000 ADD ECX,1A4                              ; |
01191841  |.  FF15 80321901 CALL DWORD PTR DS:[<&mfc100u.#7006>]     ; \mfc100u.70FD3C63
01191847  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
0119184A  |.  8378 F4 0B    CMP DWORD PTR DS:[EAX-0C],0B
0119184E  |. \0F85 54FFFFFF JNE 011917A8

 

이번엔 serial 값을 가져와 길이가 0xB (11d) 와 같은지 체크한다.


01191854  |.  6A 05         PUSH 5
01191856  |.  8D4D EC       LEA ECX,[EBP-14]
01191859  |.  FF15 C4321901 CALL DWORD PTR DS:[<&mfc100u.#4478>]
0119185F  |.  66:83F8 2D    CMP AX,2D
01191863  |.^ 0F85 3FFFFFFF JNE 011917A8

 

인덱스 5, 즉 6번째글자가 '-' (0x2D) 와 같아야한다.


00DB1869  |.  6A 00         PUSH 0
00DB186B  |.  8D4D E8       LEA ECX,[EBP-18]
00DB186E  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1874  |.  8AC8          MOV CL,AL
00DB1876  |.  80E1 01       AND CL,01
00DB1879  |.  884D E0       MOV BYTE PTR SS:[EBP-20],CL
00DB187C  |.  8045 E0 05    ADD BYTE PTR SS:[EBP-20],5
00DB1880  |.  8AC8          MOV CL,AL
00DB1882  |.  D0E9          SHR CL,1
00DB1884  |.  8AD0          MOV DL,AL
00DB1886  |.  8AD8          MOV BL,AL
00DB1888  |.  80E1 01       AND CL,01
00DB188B  |.  C0EA 02       SHR DL,2
00DB188E  |.  C0EB 03       SHR BL,3
00DB1891  |.  C0E8 04       SHR AL,4
00DB1894  |.  80C1 05       ADD CL,5
00DB1897  |.  80E2 01       AND DL,01
00DB189A  |.  24 01         AND AL,01
00DB189C  |.  80E3 01       AND BL,01
00DB189F  |.  8845 E4       MOV BYTE PTR SS:[EBP-1C],AL
00DB18A2  |.  8045 E4 05    ADD BYTE PTR SS:[EBP-1C],5
00DB18A6  |.  884D E1       MOV BYTE PTR SS:[EBP-1F],CL
00DB18A9  |.  80C2 05       ADD DL,5
00DB18AC  |.  80C3 05       ADD BL,5
00DB18AF  |.  6A 01         PUSH 1
00DB18B1  |.  8D4D E8       LEA ECX,[EBP-18]
00DB18B4  |.  8855 E2       MOV BYTE PTR SS:[EBP-1E],DL
00DB18B7  |.  885D E3       MOV BYTE PTR SS:[EBP-1D],BL

 

[EBP-0x18] = a[i] (name값) 이라고 보기쉽게 바꾸자.

 

[EBP-0X20] = a[0]&1+5

[EBP-0X1F] = a[0]>>1&1+5

[EBP-0X1E] = a[0]>>2&1+5

[EBP-0X1D] = a[0]>>3&1+5

[EBP-0X1C] = a[0]>>4&1+5

(연산순서는 왼쪽~오른쪽)


00DB18BA  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB18C0  |.  8AC8          MOV CL,AL
00DB18C2  |.  80E1 01       AND CL,01
00DB18C5  |.  884D D8       MOV BYTE PTR SS:[EBP-28],CL
00DB18C8  |.  FE45 D8       INC BYTE PTR SS:[EBP-28]
00DB18CB  |.  8AC8          MOV CL,AL
00DB18CD  |.  D0E9          SHR CL,1
00DB18CF  |.  8AD0          MOV DL,AL
00DB18D1  |.  8AD8          MOV BL,AL
00DB18D3  |.  80E1 01       AND CL,01
00DB18D6  |.  C0EA 03       SHR DL,3
00DB18D9  |.  C0E8 04       SHR AL,4
00DB18DC  |.  6A 0A         PUSH 0A
00DB18DE  |.  FEC1          INC CL
00DB18E0  |.  C0EB 02       SHR BL,2
00DB18E3  |.  80E2 01       AND DL,01
00DB18E6  |.  24 01         AND AL,01
00DB18E8  |.  6A 0A         PUSH 0A
00DB18EA  |.  8845 DC       MOV BYTE PTR SS:[EBP-24],AL
00DB18ED  |.  FE45 DC       INC BYTE PTR SS:[EBP-24]
00DB18F0  |.  884D D9       MOV BYTE PTR SS:[EBP-27],CL
00DB18F3  |.  FEC2          INC DL
00DB18F5  |.  80E3 01       AND BL,01
00DB18F8  |.  6A 0A         PUSH 0A
00DB18FA  |.  8D4D F0       LEA ECX,[EBP-10]
00DB18FD  |.  FEC3          INC BL
00DB18FF  |.  8855 DB       MOV BYTE PTR SS:[EBP-25],DL

 

[EBP-0X28] = a[1]&1+1

[EBP-0X27] = a[1]>>1&1+1

BL = a[1]>>2&1+1

[EBP-0X25] = a[1]>>3&1+1

[EBP-0X24] = a[1]>>4&1+1


00DB1902  |.  FF15 8432DB00 CALL DWORD PTR DS:[<&mfc100u.#4511>]	; arg1=0xA, arg2=[ebp-0x10]
00DB1908  |.  0FB655 E0     MOVZX EDX,BYTE PTR SS:[EBP-20]
00DB190C  |.  8B35 B430DB00 MOV ESI,DWORD PTR DS:[<&MSVCR100._itow_s
00DB1912  |.  0FB6CB        MOVZX ECX,BL
00DB1915  |.  50            PUSH EAX                                 ; |Arg2
00DB1916  |.  03CA          ADD ECX,EDX                              ; |
00DB1918  |.  51            PUSH ECX                                 ; |Arg1
00DB1919  |.  FFD6          CALL ESI                                 ; \MSVCR100._itow_s
00DB191B  |.  83C4 10       ADD ESP,10
00DB191E  |.  6A 00         PUSH 0
00DB1920  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1923  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1929  |.  6A 00         PUSH 0
00DB192B  |.  8D4D EC       LEA ECX,[EBP-14]
00DB192E  |.  66:8BF8       MOV DI,AX
00DB1931  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1937  |.  8D4D F0       LEA ECX,[EBP-10]
00DB193A  |.  66:3BC7       CMP AX,DI
00DB193D  |.- 0F85 68FEFFFF JNE 00DB17AB
00DB1943  |.  6A FF         PUSH -1                                  ; /Arg1 = -1
00DB1945  |.  FF15 8832DB00 CALL DWORD PTR DS:[<&mfc100u.#11494>]    ; \mfc100u.58ECF031
00DB194B  |.  6A 0A         PUSH 0A
00DB194D  |.  6A 0A         PUSH 0A
00DB194F  |.  6A 0A         PUSH 0A
00DB1951  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1954  |.  FF15 8432DB00 CALL DWORD PTR DS:[<&mfc100u.#4511>]

 

 

[EBP-0x14]=e[i] (serial) 으로 보기쉽게 바꾸겠다.

 

itow( [EBP-0x20]+BL, 0xa ) == e[0] 인 지 검사.

itow( [EBP-0x20]+BL, 0xa ) -> [EBP-0x20]+BL 을 문자로 바꾼다 ( 7 (0x7) -> '7' (0x37) )


00DB195A  |.  0FB64D E3     MOVZX ECX,BYTE PTR SS:[EBP-1D]
00DB195E  |.  50            PUSH EAX
00DB195F  |.  0FB645 DB     MOVZX EAX,BYTE PTR SS:[EBP-25]
00DB1963  |.  03C1          ADD EAX,ECX
00DB1965  |.  50            PUSH EAX
00DB1966  |.  FFD6          CALL ESI
00DB1968  |.  83C4 10       ADD ESP,10
00DB196B  |.  6A 01         PUSH 1
00DB196D  |.  8D4D EC       LEA ECX,[EBP-14]
00DB1970  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1976  |.  6A 00         PUSH 0
00DB1978  |.  8D4D F0       LEA ECX,[EBP-10]
00DB197B  |.  66:8BF8       MOV DI,AX
00DB197E  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1984  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1987  |.  66:3BF8       CMP DI,AX
00DB198A  |.- 0F85 1BFEFFFF JNE 00DB17AB
00DB1990  |.  6A FF         PUSH -1                                  ; /Arg1 = -1
00DB1992  |.  FF15 8832DB00 CALL DWORD PTR DS:[<&mfc100u.#11494>]    ; \mfc100u.58ECF031
00DB1998  |.  6A 0A         PUSH 0A
00DB199A  |.  6A 0A         PUSH 0A
00DB199C  |.  6A 0A         PUSH 0A
00DB199E  |.  8D4D F0       LEA ECX,[EBP-10]
00DB19A1  |.  FF15 8432DB00 CALL DWORD PTR DS:[<&mfc100u.#4511>]

위에있는 로직과 같은모양을가지고있다.

e[1]==[EBP-0X25] + [EBP-0X1D]) 인 지 검사


 

00DB19A7  |.  0FB655 DC     MOVZX EDX,BYTE PTR SS:[EBP-24]
00DB19AB  |.  50            PUSH EAX
00DB19AC  |.  0FB645 E1     MOVZX EAX,BYTE PTR SS:[EBP-1F]
00DB19B0  |.  03D0          ADD EDX,EAX
00DB19B2  |.  52            PUSH EDX
00DB19B3  |.  FFD6          CALL ESI
00DB19B5  |.  83C4 10       ADD ESP,10
00DB19B8  |.  6A 02         PUSH 2
00DB19BA  |.  8D4D EC       LEA ECX,[EBP-14]
00DB19BD  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB19C3  |.  6A 00         PUSH 0
00DB19C5  |.  8D4D F0       LEA ECX,[EBP-10]
00DB19C8  |.  66:8BF8       MOV DI,AX
00DB19CB  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB19D1  |.  8D4D F0       LEA ECX,[EBP-10]
00DB19D4  |.  66:3BF8       CMP DI,AX
00DB19D7  |.- 0F85 CEFDFFFF JNE 00DB17AB
00DB19DD  |.  6A FF         PUSH -1                                  ; /Arg1 = -1
00DB19DF  |.  FF15 8832DB00 CALL DWORD PTR DS:[<&mfc100u.#11494>]    ; \mfc100u.58ECF031
00DB19E5  |.  6A 0A         PUSH 0A
00DB19E7  |.  6A 0A         PUSH 0A
00DB19E9  |.  6A 0A         PUSH 0A
00DB19EB  |.  8D4D F0       LEA ECX,[EBP-10]
00DB19EE  |.  FF15 8432DB00 CALL DWORD PTR DS:[<&mfc100u.#4511>]

e[2]==[EBP-0X24]+[EBP-0X1F] 인 지 검사


00DB19F4  |.  0FB655 E2     MOVZX EDX,BYTE PTR SS:[EBP-1E]
00DB19F8  |.  0FB64D D8     MOVZX ECX,BYTE PTR SS:[EBP-28]
00DB19FC  |.  50            PUSH EAX
00DB19FD  |.  03CA          ADD ECX,EDX
00DB19FF  |.  51            PUSH ECX
00DB1A00  |.  FFD6          CALL ESI
00DB1A02  |.  83C4 10       ADD ESP,10
00DB1A05  |.  6A 03         PUSH 3
00DB1A07  |.  8D4D EC       LEA ECX,[EBP-14]
00DB1A0A  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1A10  |.  6A 00         PUSH 0
00DB1A12  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1A15  |.  66:8BF8       MOV DI,AX
00DB1A18  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1A1E  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1A21  |.  66:3BF8       CMP DI,AX
00DB1A24  |.- 0F85 81FDFFFF JNE 00DB17AB
00DB1A2A  |.  6A FF         PUSH -1                                  ; /Arg1 = -1
00DB1A2C  |.  FF15 8832DB00 CALL DWORD PTR DS:[<&mfc100u.#11494>]    ; \mfc100u.58ECF031
00DB1A32  |.  6A 0A         PUSH 0A
00DB1A34  |.  6A 0A         PUSH 0A
00DB1A36  |.  6A 0A         PUSH 0A
00DB1A38  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1A3B  |.  FF15 8432DB00 CALL DWORD PTR DS:[<&mfc100u.#4511>]

e[3]=[EBP-0X1E]+[EBP-0X28] 인 지 검사


00DB1A41  |.  0FB64D E4     MOVZX ECX,BYTE PTR SS:[EBP-1C]
00DB1A45  |.  50            PUSH EAX
00DB1A46  |.  0FB645 D9     MOVZX EAX,BYTE PTR SS:[EBP-27]
00DB1A4A  |.  03C1          ADD EAX,ECX
00DB1A4C  |.  50            PUSH EAX
00DB1A4D  |.  FFD6          CALL ESI
00DB1A4F  |.  83C4 10       ADD ESP,10
00DB1A52  |.  6A 04         PUSH 4
00DB1A54  |.  8D4D EC       LEA ECX,[EBP-14]
00DB1A57  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1A5D  |.  6A 00         PUSH 0
00DB1A5F  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1A62  |.  66:8BF8       MOV DI,AX
00DB1A65  |.  FF15 C432DB00 CALL DWORD PTR DS:[<&mfc100u.#4478>]
00DB1A6B  |.  8D4D F0       LEA ECX,[EBP-10]
00DB1A6E  |.  66:3BF8       CMP DI,AX
00DB1A71  |.- 0F85 34FDFFFF JNE 00DB17AB
00DB1A77  |.  6A FF         PUSH -1                                  ; /Arg1 = -1
00DB1A79  |.  FF15 8832DB00 CALL DWORD PTR DS:[<&mfc100u.#11494>]    ; \mfc100u.58ECF031

e[4]==[EBP-0X1C]+[EBP-0X27] 인 지 검사


 

 

a[2], a[3] 도 똑같은방식으로 serial 을 만든다.

시리얼만드는방식을 코드로 옮겨서, 76876-77776 이 되는 4글자를 브루트포스로 찾으면되겠다.


 

[ c ]

 

#include<stdio.h>
int main(void) {
	int v20,v1f,v1e,v1d,v1c,v28,v27,bl,v25,v24,i,j;
	for(i=0x61;i<=0x7a;i++){
		for(j=0x61;j<=0x7a;j++){
			v20=(i&1)+5;
			v1f=(i>>1&1)+5;
			v1e=(i>>2&1)+5;
			v1d=(i>>3&1)+5;
			v1c=(i>>4&1)+5;
			
			v28=(j&1)+1;
			v27=(j>>1&1)+1;
			bl=(j>>2&1)+1;
			v25=(j>>3&1)+1;
			v24=(j>>4&1)+1;
			if(v20+bl==7)
				if(v25+v1d==6)
					if(v24+v1f==8)
						if(v28+v1e==7)
							if(v27+v1c==6)
								printf("%c,%c\n",i,j);
		}
	}
	for(i=0x61;i<=0x7a;i++){
		int p=0x70; //마지막글자는 p 
		v20=(i&1)+5;
		v1f=(i>>1&1)+5;
		v1e=(i>>2&1)+5;
		v1d=(i>>3&1)+5;
		v1c=(i>>4&1)+5;
		
		v28=(p&1)+1;
		v27=(p>>1&1)+1;
		bl=(p>>2&1)+1;
		v25=(p>>3&1)+1;
		v24=(p>>4&1)+1;
		if(v20+bl==7)
			if(v25+v1d==7)
				if(v24+v1f==7)
					if(v28+v1e==7)
						if(v27+v1c==6)
							printf("%c,%c\n",i,p);	
	}
}

 

연산은 2글자씩 가져와서 하기때문에, 2중반복문 2개를 만들어서,

76876 을 만족하는 2글자, 77776 을 만족하는 두글자를 각각 출력했다. (마지막글자는 p)

 

 

만들수 있는 4글자는,

 

bugp

bump

cqgp

cqmp

ftgp

ftmp

 

총 6개가있다.

 

6개중에 하나일것이다.