티스토리 뷰

level 17번 문제입니다. 그 전의 문제들과 다르게 시리얼 값을 알려주고 Name을 찾는 문제입니다. 


실행을 해봤더니 name에는 1~2글자를 넣으면 오류가 납니다. 3글자 이상을 허용하는 것 같습니다.


Exeinfo PE를 실행하면 패킹이 되어있지 않습니다.


OEP는 0045C714입니다.


문자열이 있는 루틴에 BP를 걸고 실행을 하면 문자열을 받습니다. 



0045BAE8 주소부터 분석을 시작하겠습니다.


0045BB12 ~ 0045BB18 이 곳은 입력했던 name값을 가져오네요.



0045BB24는 0045BB22줄에서 가져온 name의 길이와 비교를 해서 길이가 3이 안될 경우에는 프로그램의 오류가 나는 부분입니다. 하지만 문제의 힌트를 보면 한자리 라고 했으니까 저기 0045BB24 부분에서 [CMP EAX, 1]로 패치 후 덤프를 뜨고 나서 문제를 풀어야 할 것 같습니다. 하지만 지금은 어떤식으로 돌아가는지 보는 것이기 때문에 나중에 바꿔보겠습니다.

  



아래 부분은 Name의 길이가 3 미만일 경우에는 0045BB29부터 실행을 하고, 0045BB39 줄에서 JMP문으로 실패루틴으로 점프하는 동작입니다. 




아래 루틴은 1E(30)과 현재 EAX(5) 문자열 길이를 비교합니다. 즉, name은 3보다 같거나 커야하고, 30보다는 같거나 작아야 합니다.




0045BB83은 serial 값을 [LOCAL.4]에 저장되어 있는 것을 EAX로 불러 들이고 스택에 저장합니다. 현재 EAX에는 serial을 입력한 BEDA-2F56-BC4F4368-8A71-870B 입니다.




분석을 해본 결과 0045BB9B 줄의 0045B850 함수에서 name값을 가지고 복잡한 계산을 한 후에 시리얼 값을 만듭니다.




위의 그림에서 0045B850으로 들어가서 쭉 내리다 보면 첫 번째 루틴이 나옵니다. 아 너무 꼬는거 아닌가라는 생각을 했습니다. 아래의 루틴을 하나하나 분석을 해보겠습니다.




0045B898줄을 실행하면 일단, ECX에 1을 집어 넣습니다. ECX의 용도는 아래에 나옵니다.




0045B8A0 줄을 실행해서 [EBX+ECX-1]을 계산하게 되면 EBX = 00A8C6D0안에 있는 문자열 a의 헥스값(61) + ECX(1) -1 을 하게 되면 ESI는 61 + 1 - 1 = 61이 됩니다. 오른쪽의 그림은 0045B8A5를 실행하면 ESI와 EDX를 더해서 ESI에는 61이 그대로 존재하게 됩니다. 하지만 아래의 명령을 계속 실행하다 보면 EDX에 큰 숫자가 들어가는데 문자열 갯수만큼 실행이 되어 더해집니다.

 




0045B8A7 줄을 실행하면 ESI, ESI, 772가 곱해져서 ESI에는 0002D232 결과를 넣습니다.

 




아래 부터는 차례대로 왼쪽 -> 오른쪽 순서대로 0045B8AD부터 실행하여 나온 레지스터의 결과 창입니다. 

 

 

 



EAX가 1 감소하여 5->4가 되는 과정까지가 이 루틴의 전부입니다. 전체적으로 요약을 하자면 name으로 입력했던 값을 하나씩 불러와서 곱하고, 더하는 복잡한 과정을 통해서 EDX에 저장해 놓습니다. 그리고 EAX가 0이 될 때까지 EDX에 계속 저장을 합니다. 아래 부터는 한 루틴이 실행될 때마다 찍은 레지스터 창입니다. 

 


 



EDX와 ESI 에는 결국 8D4C1DF0이 들어가고 빠져나옵니다. 위의 루틴을 분석하면서 하나의 알고리즘이 생성되는 것을 알 수가 있습니다. 

1. ESI에 입력한 name의 값(한 자리수)과 0x772를 곱셈

2. ESI를 EDX에 저장

3. EDX와 ESI를 저장해서 EDX에 저장

4. ESI와 EDX를 더해서 ESI에 저장

5. ESI에 0x474를 곱해서 ESI에 저장

6. ESI에 ESI를 더해서 ESI에 저장



아래 루틴들을 분석하면서 중요한 사실을 깨달았습니다. 아래 루틴은 위에서 분석한 루틴입니다. 이 중에서 40B8BC 줄에서 ADD ESI, ESI 를 실행하면서 ESI에는 결국 오른쪽 사진과 같이 8D4C1DF0이 됩니다. 이 값중에서 왼쪽 4바이트를 남긴채 오른쪽 4바이트는 버리게 됩니다. 결국 8D4C - XXXX - XXXX - XXXX 이런식으로 키 값이 생성이 된다는 것을 예상이 가능합니다. 

문제에서 Serial을 알려줬는데, 처음 문자열은 BEDA 입니다. 즉, 정답의 name은 아래의 루틴을 거치면서 ESI에는 BEDA???? 값이 나와야 한다는 것을 알 수가 있습니다.

 




아래 4개의 사진을 보시면 공통점이 있습니다. 각각의 Serial 값을 생성하고 각각 [MOV ECX, 4]와 [MOV EDX, 1]이 있고 00404D0C 함수의 인자로 실행이 됩니다. 즉, 8비트에서 4비트만 가지고 리턴하는 것을 예상할 수가 있습니다. 


 



 



함수를 빠져나와서 0045BBA0을 빠져나와서 [LOCAL.5]에 있는 값을 EDX에 넣으면 아래와 같습니다. 전체적인 KEY 값을 보여줍니다. 즉, NAME 값에 따라서 SERIAL값이 생성된 것을 볼 수가 있습니다. 

  




이제 전체적으로 정리를 해보겠습니다. 첫 번째 루틴말고는 다른 루틴을 분석해본 결과 너무 버거웠기에 첫 번째 루틴의 알고리즘만을 가지고 파이썬으로 작업을 해봤습니다.

아래의 코드는 제가 작업한 코드입니다. range 부분에 0x30에서 0x7A까지 준 이유는 문제에서는 한 글자라고 힌트를 줬으니 0x30과 0x7A를 각각 아스키코드로 바꾸면 0과 z입니다. 0부터9, A부터Z, a부터z를 하나씩 대입해서 아래의 알고리즘대로 실행을 하여 프린트를 해줍니다.




위에서 봤듯이 8비트만을 리턴하므로 앞의 4비트는 버리고 검색을 하여 Serial의 첫 번째 문자 BEDA를 검색해 본 결과 70에서 발견이 되었습니다. 70은 10진수이므로 16진수로 바꾸면 46이되고 46을 아스키코드로 바꾸면 F가 됩니다.




실행을 다시해보려는데 NAME의 길이를 3 이하면 실패하는 루틴에서 1으로 패치하고 덤프를 떠서 다시 실행을 했습니다.

NAME에 F를 주고 실행을 합니다.

 


그러면 Key 값이 정확하게 바뀌는 것을 볼 수가 있습니다.



위와 같이 분석을 하여 풀었더니, 너무 힘드네요..간단하게 풀려면 위와 같이 처음부터 0045BB24부분에서 [CMP EAX, 1]로 패치를 하고 BruteForce를 한 글자씩 진행하면 풀 수 있는 문제였지만, 별로 공부에 도움은 안 될 것같습니다. 




'Wargame > codeengn' 카테고리의 다른 글

[codeEngn] Basic RCE level19  (0) 2015.07.31
[codeEngn] Basic RCE level18  (0) 2015.07.30
[codeEngn] Basic RCE level16  (0) 2015.07.30
[codeEngn] Basic RCE level15  (0) 2015.07.29
[codeEngn] Basic RCE level14  (0) 2015.07.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함