안녕하세요. 누락된 마지막 문제 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 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
,