CodeEngn Reversing Basic_Level17

실행 시 모습이다. 이름이 한 글자라고 한 글자를 입력해보았다.

이런 메시지가 뜬다. 좀 더 길게 입력해야 하는 것 같다.

이 상태에서 check it을 누르면 아무 반응이 없다. 문제에서 주어진 key를 넣었을 때도 마찬가지이다. 틀린 key를 입력하면 반응을 하지 않는 것 같다.

패킹은 없는 것 같다. 올리디버거로 돌려보았다.

referenced text에서 찾은 문자열이다. 에러 문구를 참고하면 글자 수에 제한이 있는 것 같다. 일정 수 이상의 글자여야 하며, 30자 이상도 오류메시지를 낼 것 같다. 문자열 참조 코드에 bp를 걸고 실행해보자.

에러 메시지에 bp를 걸고 name에는 1, key에는 123을 입력한 뒤 실행했다. 바로 위에 분기문이 있어 위의 cmp에도 bp를 걸었다. cmp 바로 위에서 EAX가 가리키던 주소의 값을 읽어 3과 비교한다.

EAX가 가리키던 주소의 출처를 알아보니 EBP-8에 저장된 내용이고, 그 내용은 EBP-4에 저장된 내용이다. 결국 EBP-4에 저장된 값을 쓰는 것이다. 그리고 cmp하기 전에 EAX가 0인지 검사한다. 0이 아니면 EAX에서 4를 뺀다. 그렇다면 EBP-4에는 무엇이 들어있나?

00595128 에서 4가 빠지면 00595124이고, 이 주소에 저장된 값을 EAX에 저장한다.

1이 저장되어 있다. 아래 있는 문자열을 보아 name의 길이로 의심된다. name의 길이를 3보다 크게 설정한 뒤 다시 실행했더니 해당 에러문은 넘어갈 수 있었다.

문제에서는 name이 한 글자라 했다. 따라서 cmp코드에서 0과 비교하도록 업데이트하여 제거했다.

계속 진행하다 보니 성공 메시지를 띄우는 코드가 나타났다. 바로 위에 분기문이 있고, 그 위에는 call이 있다. 따로 cmp하는 부분이 없는 것을 보아 위에서 call 되는 함수에서 flag를 설정해 주는 것 같다. 이 call에 bp를 걸고 함수 내용을 살펴보자.

input과 serial의 주소를 같게 준 것이 아닌지 체크를 하는 루틴이 눈에 띈다. 또한 그냥 비교하는 것이 아니라 주소를 한 번 꼬아서 비교하는 점도 특이하다. 비교하는 함수보다는 serial을 만드는 부분이 궁금하니 이 정도만 분석하고 넘어가자.

에러 메시지 분기에서, 에러메시지를 내지 않는 경우의 코드를 분석해보았다. 분석 결과 앞의 please enter more chars 에러에서 분기하기 전 하는 일과 똑같은 일을 한다는 것을 알아냈다. 마지막에는 name의 길이를 받아와 0x1E(10진법으로 30)과 비교한다.

에러 처리를 끝낸 후 serial을 만드는 코드가 있을 것 같다. 30 chars 에러코드 아래 부분 코드를 살펴보자.

bp를 걸어놓은 0045BB75부터가 serial을 만드는 루틴은 것 같다. 그 밑에 bp가 걸린 call은 serial과 입력값 key를 비교하는 루틴이다. 이 사이에서 serial을 만들 것 같다.

불리는 함수들을 찾아가서 serial을 만드는 알고리즘을 찾아보자.

첫 번째 알고리즘을 통해 나온 값은 ESI, 두 번째는 Local.4(EBP -10), 세 번째는 Local.2(EBP - 8), 네 번째는 EDI, 다섯 번째는 EBX에 저장된다.

각 알고리즘은 주석을 읽어보자. 여기서 세 번째 알고리즘은 함수로 묶여있다. 실제로 키를 만들기 위해서는 세 번째 함수를 들어가볼 필요가 있다.

그 전에, 세 번째 알고리즘에 인자로 들어가는 문자열은 주석에도 써 있듯 input name + "w09/&720("=)=!)&")?'"(=(?."이다. 이름을 이용하여 만들고, 이 알고리즘으로 만들어진 문자열은 앞 8글자를 떼어내어 이용한다.

세 번쨰 알고리즘은 함수로 묶여있다. 함수에 들어가서 분석해 보았다.

이 함수 내에서 또 함수가 불린다. 빨간 네모친 맨 아래 함수가 시리얼을 만드는 함수이다.

그 함수의 내부이다. 저 네모 표시한 함수에서 시리얼을 생성한다.

위에서 네모 표시한 함수이다. 그리고 나는 이 시점에서 드랍하였다…

위 로직을 기반으로 시리얼의 앞자리를 이용하여 브루트포스 방식으로 찾아보았다. flag는 F이다. MD5변환은 인터넷으로 간단하게 할 수 있다.

브루트포스 코드는 어셈블리 코드를 그대로 옮겼다.


tags: writeup, reversing, pe file, windows, keygen, x86asm