안녕하십니까 이번에는 level10을 한 번 풀어보겠습니다. 홈페이지로 들어가 문제를 한 번 봅시다.

시리얼이 WWWCCCJJJRRR일 때 이름값을 구하라고 되어있습니다. 이름은 4자리자로 하는군요. 프로그램을 다운받아 실행셔키봅시다.

이름과 시리얼이 매치가 안될 경우 실패문자열을 출력합니다. 올리디버거에서 문자열을 찾아봅시다.

CMP EAX,0C를 하여 EAX값이 0C가 아닐 경우 실패문자열이 출력되는것을 확인 할 수 있습니다. C가 10진수로 12이므로 아마 이부분은 시리얼의 자리수를 검사하는 부분인 것 같습니다. 계속 진행합시다.

00402092부분을 보시면 0022FEA3스택의 값과 0을 비교하는 것을 볼 수 있습니다. 만약 0022FEA3스택의 값이 0이라면 실패문자열이 출력되는 곳으로 점프하는군요. 0022FEA3스택에 하드웨어 브레이크를 건 후 다시 실행시켜봅시다. 

그러면 00401F8F에서 AL의 값을 0022FEA3에 대입하는 것을 확인할 수 있습니다. EAX레지스터는 보통 함수의 반환값을 저장하므로 위의 0040144C함수에서 값을 받을 확률이 큽니다. 0040144C함수를 살펴봅시다.

함수 내부로 가서 살펴보면 00401C80에서 22FD84스택의 값을 EAX에 옮기는 것을 확인할 수 있습니다. 22FD84스택에 하드웨어 브레이크를 걸고 재실행해봅시다.

그러면 00401BC2에서 22FD3C스택의 값을 EDX에 옮기고 그 EDX를 22FD84에 옮기는 것을 확인할 수 있습니다. 이번엔 22FD3C스택에 브레이크를 걸고 재실행해봅시다.

이번엔 00401B79에서 22FDDF스택의 값을 EAX에 옮기고 그 EAX를 22FD3C에 옮기는 것을 확인할 수 있습니다. 지겹지만 22FDDF에 브레이크를 걸고 또 재실행해봅시다.

그러면 00401B5C에서 CMP구문을 수행하고 그 결과에 따라 JLE명령어 수행. JLE가 수행되지 않으면 22FDDF에 0을 집어넣는 것을 확인할 수 있습니다. 즉 EAX가 5보다 클 경우 22FDDF에 0을 집어넣는 것을 볼 수 있으며 우리가 원하는 성공문자열을 출력하기 위해서는 22FDDF에 0이 들어가지 않아야 하는 것을 알 수 있습니다.

간단하게 00401B5C에서 EAX값이 5이하 여야 한다는 것이지요. EAX값이 5이하라면 JLE코드에서 점프를 하게 되므로 22FDDF에 0을 대입하는 코드를 생략할 수 있게 딥니다.

그렇다면 이 EAX는 어디서 오는 것일까요? 코드를 다시 한 번 분석해보니 다음과 같은 알고리즘을 찾을 수 있었습니다.

여기서 하나라도 CMP EAX,5에 의해 0022FDDF에 0이 넣어지면 실패하게 됩니다.

자 그러면 이제 이름으로 만든 22FDCC스택의 값과 시리얼로 만든 22FDD0스택의 값이 어떻게 만들어지는지 살펴볼 차레입니다. 분석을 한 결과 다음과 같은 알고리즘을알아내었습니다.

즉 CMP연산에 필요한 EAX와 EDX에서 EDX는 시리얼값을 토대로 만들어진 값이며 EAX는 이름값을 토대로 만들어진 값이라고 결론지을 수 있습니다. 이것을 코딩으로 한 번 구현해봅시다.

a배열에는 알파벳이 저장된 배열입니다.

i는 이름값을 차례대로 대입하기 위한 카운트이며 j는 EAX와 EDX값을 구하기 위한 카운트입니다.

for문이 총 5번 쓰였는데 첫번째 for문은 이름값을 차례대로 대입하기 위한 for문이고 그다음 실행하는 2개의 for문은 이름값을 토대로 만든 EDX값을 구하기 위해, 그리고 나머지 2개의 for문은 시리얼값을 토대로 만든 EAX값을 구하기 위해 사용하였습니다.

abs함수는 절대값을 구해주는 함수이고 이렇게 반환된 값이 5이하 일경우 해당하는 이름값을 출력하도록 하였습니다.

자 그러면 한 번 실행해봅시다. 제일 먼저 시리얼값인 W에 해당하는 첫자리 이름값을 구해보겠습니다.

여기서 출력된 숫자와 영문자 값이 시리얼 W에 해당하는 값. 즉 이름의 첫자리에 올 수 있는 값입니다.

이번에는 시리얼 C에 해당하는 값. 즉 이름의 두자리에 올 수 있는 값입니다.

이번에는 시리얼 J에 해당하는 값. 즉 이름의 세자리에 올 수 있는 값입니다.

마지막으로 시리얼 R에 해당하는 값. 즉 이름의 네자리에 올 수 있는 값입니다.

정리하면 다음과 같습니다.

보시다시피 올 수 있는 단어가 많으므로 이로 만들 수 있는 이름값도 굉장히 많습니다.

31A6, 61A6 38A6, 3DJG.... 이런식으로 말입니다.

그런데 문제에서 보면 순서상 가장 먼저 오는 문자열이 바로 정답문자열이라고 합니다. 그렇다면 가장 먼저 출력된 값인 3,1,A,6으로 만든 문자열이 정답이 되겠군요. 일단 확인해봅시다.

올바른 이름과 키값이라고 출력되는군요. 한번 인증해봅시다.

성공적으로 인증이 된 것을 확인 할 수 있습니다.

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

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 10  (0) 2017.07.19
codeengn - Advance RCE level 9  (0) 2017.07.15
codeengn - Advance RCE level 8  (0) 2017.07.13
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

안녕하십니까 이번에는 level9를 한 번 풀어보겠습니다. 홈페이지로 들어가 문제를 한 번 봅시다.

패스워드를 찾으라고 되어있습니다. 파일을 다운받아 실행시켜봅시다.

이름과 패스워드를 입력하면 이름 혹은 패스워드가 틀렸다는 문구가 나옵니다. 올리디버거로 문자열을 찾아봅시다.

입력받을 때 출력된 문자열인 Username과 password가 보입니다. 따라 들어가봅시다.

00EC1000 함수를 호출하면 실패 문자열이 출력되는 것을 확인할 수 있네요. 따라 들어가봅시다.

계속 코드를 수행하다 보면 위의 TEST문과 CMP구문에 의해 실패 문자열이 출력되는 루프 부분으로 점프하는 것을 볼 수 있습니다. 즉 성공문자열을 출력하기 위한 루프로 가기 위해서는 위의 점프 명령어에 점프하지 않아야 한다는 것을 할 수 있습니다.

조건은 총 2개입니다.

TEST BL,BL -> BL의 값이 0이면 JZ로 인해 점프하게 됩니다. 즉 BL은 0이 아니어야 합니다.

CMP BYTE PTR SS:[ESP+0B], 0 -> ESP+0B주소값인 스택의 값이 0이면 JE에 의해 점프하게 됩니다. 즉 ESP+0B의 스택값은 0이 아니어야 합니다.

다시 한 번 코드를 살펴봅시다.

재시작하여 다시 코드를 수행하면 윗부분의 첫루프 부분에서 우리가 입력한 Name의 값이 첫번째자리랑 0x00(NULL값)을 비교하는 것을 알 수 있습니다. 코드를 계속 수행해봅시다.

코드를 계속 수행하면 JNE로 인해 SBB명령어 부문으로 점프하게 되고 SBB 명령어 부문에서 EAX를 0이 아닌 값으로 만듭니다.

그리고 TEST EAX,EAX 코드를 수행하여 그 ZF의 값에 따라 SETZ 명령어가 수행됩니다.

SETZ 명령어는 ZF의 값이 1일 때 해당 부분의 값을 1로 수정시켜주는 명령어입니다. 여기서는 BL의 값을 변경시키는데 이 때 이 BL의 값은 앞에서 보셧던 성공 문자열 출력 분기점에서 TEST 코드를 수행하는 레지스터입니다. 즉 이 코드에서 BL의 값이 1이 되어야 분기점의 TEST BL,BL 에서 TEST가 ZF를 0으로 반환하고 ZF가 0이므로 JZ명령어가 수행되지 않게 됩니다. 즉 성공부분으로 갈 수 있는 첫 부분입니다.

계속 다음 코드로 넘어가봅시다.

SETZ명령어 바로 아래의 코드를 보시면 CMP EAX,DWORD PTR DS:[ECX]부분이 보입니다. 이 때 비교하는 값은 우리가 입력한 패스워드(EAX)와 0088228F를 비교하는 것을 볼 수 있습니다. 그리고 이로 인한 ZF가 설정되어 밑의 SETE BYTE PTR SS:[ESP+0F]에서 값이 입력되는 것을 알 수 있습니다.

SETE 명령어는 ZF가 0일 때 해당 주소의 값을 1로 수정시켜주는 0이며 이 때 수정시키는 주소값인 BYTE PTR SS:[ESP+0F]는 우리가 성공문자열로 가기 위한 분기점에 존재하는 BYTE PTR SS:[ESP+0B]의 값이랑 동일한 것을 알 수 있습니다.

즉 CMP EAX,DWORD PTR DS:[ECX]부분에서 두 값이 서로 같아야 ZF가 0을 반환하고 이 ZF에 의해 SETE코드에서 BYTE PTR SS:[ESP+0F]의 값을 1로 수정하여 성공분기점에서 JE명령어를 수행하지 않게 할 수 있습니다.

최종적으로 정리를 하면 다음과 같습니다.

1. 우리가 입력한 이름의 첫자리 값이 NULL이어야 한다.

2. 우리가 입력한 패스워드 값이 16진수 0088228F이어야 한다.

다만 패스워드를 입력받을 때에는 10진수로 받으므로 우리는 16진수값인 0088228F를 10진수로 바꿔줄 필요가 있습니다. 10진수로 바꾸면 값은 8921743가 됩니다.

즉 이 8921743값이 패스워드라고 볼 수 있겠습니다. 이름 같은 경우에는 NULL을 입력해주면 될 것 같은데 NULL값을 입력할 방법이 없어 시연은 생략하겠습니다.

이 패스워드를 인증해봅시다.

정답이 맞는 것 같군요.

추가로 재미있는 부분이 하나 있다면 코드에 이름과 DonaldDuck를 비교하는 부분이 나오는데 이름을 DonaldDuck으로 주면 "니가 그것(DonaldDuck)을 이름으로 느꼈다는 걸 못믿겠어" 라는 문자열이 추가로 출력됩니다. 일종의 낚시라고 볼 수도 있겠네요.

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

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 10  (0) 2017.07.19
codeengn - Advance RCE level 9  (0) 2017.07.15
codeengn - Advance RCE level 8  (0) 2017.07.13
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

안녕하십니까. 오랜만에 코드엔진 문제를 포스팅하겠습니다. 이번에 포스팅 할 문제는 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 8  (0) 2017.07.13
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

안녕하세요. 오늘은 Advance RCE level 6을 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요.

4

파일을 실행시켜봅시다.

처음엔 1이라고 적힌 창이 떴습니다. 그리고 창을 닫으니 그다음은 2가 적힌 창이 뜹니다. 이렇게 계속 반복된 창이 뜹니다. 엔터를 눌러 창을 계속 닫으니 700대에서 창이 닫히는 것을 볼 수 있습니다. Exeinfo PE를 통해 분석을 해봅시다.

Autoit으로 작성된 파일이군요. 디컴파일러인 Exe2Aut를 이용합시다.

for문을 이용해 790번까지 창을 반복해서 띄우는 것을 알 수 있습니다. 즉 남은 군생활은 790일입니다. MD5인코딩 합시다.

인증해봅시다.

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

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 9  (0) 2017.07.15
codeengn - Advance RCE level 8  (0) 2017.07.13
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
codeengn - Advance RCE level 3  (0) 2016.08.07
Posted by englishmath

안녕하세요. 오늘은 Advance RCE level 5를 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요.

파일을 실행시켜 봅시다.

흠 peid로 파일을 분석해봅시다.

VB로 만들어진 파일입니다. 문제에선 시리얼을 구하라고 했음으로 사용자가 입력한 값과 옳은 시리얼을 비교하는 함수가 쓰였을 것입니다. 그리고 VB에서 그러한 역할을 하는 함수는 vbaStrCmp함수입니다. 함수를 한 번 찾아봅시다.

예상대로 하나가 있음을 알 수 있습니다. 들어가 봅시다.

이 함수를 호출하는 부분에 브레이크를 걸고 레지스터값을 확인해봅시다.

사용자가 입력한 값 123과 677345를 비교하는 것을 알 수 있습니다. 677345를 입력해봅시다.

아까와는 다른 메세지가 출력되었습니다. 인증을 하러 가봅시다.

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

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 8  (0) 2017.07.13
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
codeengn - Advance RCE level 3  (0) 2016.08.07
codeengn - Advance RCE level 2  (0) 2016.08.03
Posted by englishmath

안녕하세요. 오늘은 Advance RCE level 4를 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요

실행시켜봅시다.

잘못된 값을 치면 Invalid Serial이라 나오는 군요. 올리디버그로 열어서 문자열을 검색해봅시다.

문자열이 나와있지 않군요. 함수를 찾아 봅시다.

함수도 종료프로세스 밖에 없군요.. 아무래도 패킹되어 있는 것 같습니다. peid로 확인해봅시다.

정보가 나와있지 않군요. 아마 알려지지 않은 패킹방법인 것 같습니다. 올리디버거로 열어 코드를 뜯어봅시다.

한줄씩 실행하다 보면 위와 같이 401006으로 가는 코드가 있습니다. 가 봅시다.

아무래도 여기가 OEP인 것 같습니다. 그러므로 올리덤프 플러그인을 이용해 덤프합시다.

밑의 박스를 체크해제한 후 덤프버튼을 눌러 저장합시다. 그리고 덤프된 파일을 열어 봅시다.

덤프된 파일을 열어보니 유니코드를 비교하는 lstrcmp함수가 보입니다. 브레이크를 걸고 시리얼 값을 입력해봅시다.

이름이 CodeEngn일때 입력한 값 123과 LOD-59919-A0024900과를 비교하는 것을 볼 수 있습니다. 입력해보시다.

성공문자열이 떴습니다. 인증해봅시다.

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

'codeengn' 카테고리의 다른 글

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
codeengn - Advance RCE level 3  (0) 2016.08.07
codeengn - Advance RCE level 2  (0) 2016.08.03
codeengn - Advance RCE level 1  (0) 2016.08.03
Posted by englishmath

안녕하세요. 오늘은 Advance RCE level 3을 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요

실행시켜 봅시다.

아무값이나 넣고 체크를 하면 문자열이 뜹니다. 올리디버그로 열어봅시다.

코드를 몇줄 보다 보면 유니코드문자열을 비교하는 lstrcmp함수를 찾을 수 있습니다. 브레이크를 걸고 실행해봅시다.

이름을 CodeEngn, 시리얼을 123을 주고 실행했을 때 123과 3265754874랑 비교하는 것을 볼 수 있습니다.

넣어보니 성공문자열이 출력되었습니다. 3265754874이 정답입니다.

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

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 5  (0) 2016.08.07
codeengn - Advance RCE level 4  (0) 2016.08.07
codeengn - Advance RCE level 3  (0) 2016.08.07
codeengn - Advance RCE level 2  (0) 2016.08.03
codeengn - Advance RCE level 1  (0) 2016.08.03
codeengn - basic rce level 6  (0) 2016.08.02
Posted by englishmath

안녕하세요. 오늘은 Advance RCE level 2를 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요

정답을 찾으라는 군요. 파일을 실행해봅시다.

패스워드입력창이 떴습니다. 아무거나 입력하고 엔터를 누르니 프로그램이 종료되는군요. 일단 PE로 분석을 해봅시다.

패킹은 안되어있으며 C++로 만들어졌다고 합니다. 올리디버그로 열어봅시다. 열었으면 우리가 아까 파일을 실행했을 때 본 문구열을 찾아봅시다. 오른쪽마우스 - Search for - All referenced text strings을 눌러주세요.

문자열을 찾아봅시다.

실행했을 때 본 문자열이 나와있습니다. 해당 주소로 진입해봅시다.

진입한 후 한줄씩 실행해보니 Enter Password: 를 출력하고 004012D2에서 사용자의 입력값을 받는 것을 알 수 있습니다. 계속 코드를 실행해 봅시다.

하나의 루프를 거치고 004013C5에서 CALL EDX를 호출하여 프로그램을 종료하고 있있음을 알아냈습니다. F7키를 이용하여 진입해봅시다.

코드를 한줄 씩 실행하다보면 CMP를 이용해 ECX와 특정 값들을 비교하고 있음을 알 수 있습니다. CMP부문으로 간 뒤 ECX값을 확인해봅시다.

EAX는 우리가 입력한 시리얼값이고 ECX는 41이군요. 이 41과 43을 비교한다고 나와있습니다. 비교해서 ZF가 0이면 JNZ에 의해 18FF8A로 점프하게 되고 18FF8A로 가면

사진에 나와있듯이 ECX를 호출하게 되고 프로그램이 종료되어 버립니다. 계속 분석해봅시다.

코드를 밑으로 내려보면 위와 같은 코드가 보입니다.

57 45 4C 4C 20 44 4F 4E 45 21을 차례대로 넣는 군요.  아스키코드로 확인해봅시다.

W E L L 스페이스바 D O N E ! 이네요. WELL DONE!

아무래도 성공문자열인것 같습니다. 그렇다면 이 코드를 실행할 수 있도록 해줄 필요가 있습니다. 일단 코드를 처음부터 다시 봅시다.

밑 부분의 코드를 보시면 JE SHORT 0018F839가 나옵니다. 이 0018F839는 어디일까요?

성공문자열을 만드는 부분입니다. 즉 우리는 JE SHORT 0018F839에서 점프를 해야 합니다. 앞의 비교문은 TEST인데 일단 잠시 미뤄두고 앞의 CMP들부터 해결해봅시다.

첫번째 CMP는 ECX와 43을 비교합니다. 그런데 여기서 ECX의 값은 41입니다. 41을 아스키값으로 바꾸면 A입니다. 즉 우리가 입력한 A12의 첫번째 값이지요. 즉 우리가 입력한 패스워드의 첫번째 글자와 43을 비교하는 것입니다. 확인을 위해 ECX를 43으로 수정하고 실행해봅시다.

두번째 CMP에 걸렸을 때의 ECX값입니다. ECX와 52를 비교하는 곳이지요. 여기서 ECX는 31. 아스키 값으로 1입니다. 그렇다면 우리가 입력한 값을 처음부터 끝까지 비교하는 것을 알 수 있습니다. CMP로 비교하는 구문은 총 10개. 각각의 값은

43 52 41 41 41 43 4B 45 44 21입니다. 아스키값으로 바꾸면

CRAAACKED!입니다. 즉 입력한 값과 CRAAACKED!를 비교하는 것이군요. 패스워드에 한번 CRAAACKED!를 입력해봅시다.

WELL DONE!이란 창이 뜨는 것을 볼 수 있습니다. 패스워드는 CRAAACKED!이네요.

인증해봅시다.

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

 

 

 

 

 

 

 

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 4  (0) 2016.08.07
codeengn - Advance RCE level 3  (0) 2016.08.07
codeengn - Advance RCE level 2  (0) 2016.08.03
codeengn - Advance RCE level 1  (0) 2016.08.03
codeengn - basic rce level 6  (0) 2016.08.02
codeengn - basic rce level 5  (0) 2016.08.02
Posted by englishmath

안녕하세요. 오늘은 Advance RCE level1을 풀어보겠습니다. 홈페이지로 들어가 파일을 받아주세요.

어디서 많이 본 문제입니다. 파일을 PEID로 열어 봅시다.

예상대로 Autoit으로 만들어져있습니다. Exe2Aut 디컴파일러로 열어봅시다.

창이 뜨고 닫히는 시간이 13.179초입니다. 단위를 밀리세컨드로 바꾸면

13179ms입니다. 문제에서는 이 값을 MD5로 변환해서 인증하라고 했으니 MD5변환해서 인증해봅시다.

인증해봅시다.

사실 문제풀이라곤 해도 그냥 프로그램 돌려서 간단하게 풀었네요. 네 이것으로 문제풀이를 마치겠습니다.

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 3  (0) 2016.08.07
codeengn - Advance RCE level 2  (0) 2016.08.03
codeengn - Advance RCE level 1  (0) 2016.08.03
codeengn - basic rce level 6  (0) 2016.08.02
codeengn - basic rce level 5  (0) 2016.08.02
codeengn - basic rce level 20  (0) 2015.10.02
Posted by englishmath

안녕하세요. 누락된 마지막 문제 basic rce level 6을 풀어보겠습니다.

홈페이지로 들어가 파일을 받아주세요. 언팩을 한 후 OEP와 Serial을 알아내는 문제이군요. peid로 파일을 분석해봅시다.

UPX이군요. 언패킹합시다.

파일을 열어봅시다.

음.. 올리디버거로 얼어봅시다.

성공적으로 언팩이 되었군요. 문자열을 찾아봅시다.

문자열이 없습니다.. 그럴리가 없는데 말이지요.. 우리는 Wrong이라는 메세지박스를 똑똑히 봤습니다. 언팩한 파일을 한 번 살펴봅시다.

하필 그 많은 언어중에 디버깅이 힘들다는 C++로 만들어졌습니다. 문자열을 찾지 못한다면 함수로 찾아봅시다. 올리디버그로 돌아가서 오른쪽마우스 - Search for - All intermodular calls를 눌러주세요.

Destination을 눌러 함수를 정렬시켜주고 우리가 본 메세지박스를 출력시키는 함수를 찾아봅시다.

찾았으면 진입합시다.

호오 우리가 원하던 곳으로 왔습니다. 조건문을 한번 볼까요. TEST EAX,EAX라고 되어있군요. TEST는 AND연산이죠. 한번 브레이크를 걸고 실행해보겠습니다.

시리얼값에 123을 넣고 실행시켜 TEST코드까지 왔을때의 EAX값은 1이군요.

여기서 TEST를 자세히 알아보겠습니다. TEST EAX,EAX는 EAX와 EAX를 and연산하여 0이 아닌 값이 나오면 ZF를 0으로 설정합니다. 반대로 연산값이 0이 나오면 ZF를 1로 설정하지요. 즉 EAX가 1이기 때문에 and연산을 하면 1이 나오고 ZF는 0으로 바뀝니다. 즉 ZF를 1로 만들기 위해서는 우리는 EAX를 0으로 만들어줘야 합니다. EAX는 보통 함수의 반환값 저장에 쓰입니다. 그러므로 근처코드에 함수를 호출하는 주소가 아마 있을 것입니다. 찾아봅시다.

찾을 것도 없이 위에 있네요. 진입해봅시다.

대략 소스를 해석해보자면

1. EDX와 ECX에 어떤 값을 집어 넣는다.

2. 4012A0(빨간 상자땜에 코드가 짤렸네요.)에서 EDX의 1byte를 EAX에 넣는다.

3. 그 EAX(AL)과 ECX를 비교한다.

4. ZF가 0이면 주소로 점프하여 EAX를 1로 만들고 리턴시킨다.

5. ZF가 1이면 EAX의 다음값과 ECX의 다음값을 비교한다.

6. 조건을 충족하지 않았을 경우 반복한다.

대충 이런 식입니다. 그렇다면 일단 EDX와 ECX에 어떤 값이 들어왔는지 확인해 봅시다.

ECX는 우리가 입력한 시리얼값이고 EDX는 어떤 문자열이군요. 정리하면

우리가 입력한 시리얼 값을 1byte씩 떼와서 EDX랑 비교하고 만약 값이 다를 경우  (ZF = 0) EAX를 1로 만들고 리턴시켜 실패 메세지박스가 출력되도록 한다. 대충 이렇게 정리할 수 있겠군요. 그러면 뭐 간단하죠.

시리얼 값을 AD46DFS547로 주면 끝입니다. 한번 해봅시다.

 

성공메세지박스가 출력되었습니다. 시리얼 값은 AD46DFS547입니다.

여기서 끝이면 좋겠지만 우리는 OEP를 찾아야 합니다. OEP란 프로그램이 처음 시작되는 주소입니다. 단 패킹된 파일은 패킹을 풀고 난 후의 시작주소가 OEP입니다.

OEP야 뭐 간단합니다. 우리는 파일은 언패킹했으니 그 언패킹된 파일의 시작주소를 보면 됩니다.

OEP = 00401360입니다. 즉 정답은 00401360AD46DFS547입니다.

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

 

'codeengn' 카테고리의 다른 글

codeengn - Advance RCE level 2  (0) 2016.08.03
codeengn - Advance RCE level 1  (0) 2016.08.03
codeengn - basic rce level 6  (0) 2016.08.02
codeengn - basic rce level 5  (0) 2016.08.02
codeengn - basic rce level 20  (0) 2015.10.02
codeengn - basic rce level 19  (0) 2015.10.02
Posted by englishmath