안녕하십니까. 오랜만에 코드엔진 문제를 포스팅하겠습니다. 이번에 포스팅 할 문제는 level8이며 level7은 C#의 이해도가 제법 필요한 문제라 생략하였습니다.

두자리인 Name값을 구하여 MD5로 변환시킨 값이 정답이라고 하는군요. 프로그램을 다운받아 실행시켜봅시다.

어디서 많이 본 그림이군요. 실행시켜봅시다.

이름은 두자리에 키값은 5D88-53B4-52A87D27-1D0D-5B09이라고 했으므로 한 번 Check it버튼을 눌러봅시다.

Please Enter More Chars...글자가 뜨는군요. 올리디버거로 살펴봅시다.

Search for의 All referenced strings를 눌러줍시다.

아까 본 문자열이 있는 것을 볼 수 있습니다. 그쪽으로 진입해봅시다.

보시면 문자열 위의 코드부분에 CMP EAX,3 구문이 있고 바로 밑에 있는 JGE명령어가 있는 것을 보아 EAX가 3이상일 경우 JGE에 의해 점프하는 것을 확인할 수 있습니다. 그리고 이 때 EAX반환값은 2인걸로 보아 아무래도 입력한 이름의 자리수를 EAX에 저장시킨다고 추측할 수 있습니다.

문제에서 Name은 두자리수라고 하였는데 프로그램은 3자리 이상만 값을 받으므로 프로그램의 코드값을 수정해줍시다.

덤프에서 해당 코드가 적혀있는 0045BB24로 이동한 다음 값을 Go To의 Executable file버튼을 눌러줍시다.

기존의 명령인 CMP EAX,3 을 뜻하는 83 F8 03 부분을 83 F8 02로 수정하여 CMP EAX,2 로 코드를 변경한 후 파일을 저장합니다.

저장한 파일을 다시 열면 코드가 변경된 것을 볼 수 있으며 두자리 수를 입력하면 정상적으로 시리얼 생성 부문으로 갈 수 있게 됩니다. 물론 JGE를 JMP로 바꾸는 방법도 괜찮은 방법입니다.

코드를 수행하면 CALL 0045B850코드에 의해 시리얼이 생성된 것을 볼 수 있습니다. 내부로 들어가 봅시다.

내부로 들어가 코드를 수행하다 보면 첫번째 반복 부분에서 우리가 입력한 Name값을 이용하여 ESI의 값을 만드는 것을 볼 수 있습니다.

성공적으로 반복문이 끝나면 ESI값은 2D7B9F20가 되는데 이 ESI값의 상위16비트(2D7B)가 시리얼 값의 첫번째 4자리값이 되는것을 알 수 있습니다.

자 그럼 이제 정리해봅시다.

대충 정리하면 이런식으로 시리얼의 첫 4자리 값을 구할 수 있을 것 같습니다. 코딩으로 한 번 구현해봅시다.

arr배열에는 이름값이 들어가게 됩니다. 첫자리는 arr[0], 두번째 자리는 arr[1]에 들어가게 됩니다.

그다음 for문을 이용하여 첫자리수를 0x30부터 0x7A까지 반복하도록 코딩합니다.

0x30은 아스키코드 값으로 0을 의미하며 0x7A는 아스키코드 값으로 z를 의미합니다.

즉 0부터 소문자 z까지를 전부 반복하기 위해 이렇게 작성하였습니다.

두번째 for문도 마찬가지이며 이런식으로 for문이 진행되게 되면

0 0 -> 0,1 -> 0,2 .......... 0,z

1,0 -> 1,1 -> 1,2 ........... 1,z

최종적으론 z,z까지 반복하게 됩니다.

이렇게 for문을 만들어 name값을 전부 주게 만든다면 이제 그다음은 for문을 이용하여 어셈블리어를 연산하도록 해주면 끝입니다. 다만 코드를 보시면 연산for문을 시작하기 전에 EDX를 0으로 주는 부분이 있는데 이는 코드의 add ESI,EDX 에서 첫자리수를 연산할 때 EDX값이 0이기 때문에 이렇게 구현하였습니다. 두번째 자리 수를 연산할 때에는 EDX값이 첫자리 수를 연산하고 남은 값이 저장되어 있어 일부러 초기화를 하지 않았습니다. 실제로 올리디버거에서 본 코드로 이런식으로 연산합니다.

그리고 마지막으로 연산한 ESI값은 result에 저장시키고 이 result의 상위16비트 값이 문제에 적힌 시리얼의 첫 4자리 값인 5D88일 경우 이 때의 name값들을 알기 위해 16진수로 출력시키도록 하였습니다. 자 그럼 이제 한 번 실행시켜봅시다.

딱 하나가 나온 것을 볼 수 있습니다. name의 첫번째 자리값은 0x43이고 두번째 자리값은 0x36일 때 5D88이 나오는군요.

0x43을 아스키코드로 바꾸면 C, 0x36을 아스키코드로 바꾸면 6입니다. 이 값을 한번 프로그램에 입력해봅시다.

성공했다는 박스가 나타났습니다. 이 값을 MD5해쉬화 합시다.

나온 값을 인증해봅시다.

네 이것으로 문제풀이를 마치겠습니다.

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 10  (0) 2017.07.19
codeengn - Advance RCE level 9  (0) 2017.07.15
codeengn - Advance RCE level 6  (0) 2016.08.07
codeengn - Advance RCE level 5  (0) 2016.08.07
codeengn - Advance RCE level 4  (0) 2016.08.07
Posted by englishmath
,