티스토리 뷰

level14 문제를 보면 Name에 CodeEngn을 입력하면 나오는 Serial 루틴에서 나오는 값을 찾으라는 것입니다. bruteforce가 필요하다고 했는데, 딱히 필요성은 느끼지 못했네요.


실행을 하면 이상한 name과 serial값에 입력을 받는 식으로 사용하고, 틀리다면 시리얼이 틀리게 나오네요. name에 따라서 serial이 생성된다는 것을 예상할 수가 있습니다.


Exeinfo PE로 보면 UPX로 걸려있습니다. 


문제를 푸는 데 오류가 나면 다시 수동 언팩하기 귀찮아서 UPX 언패킹 툴을 소개합니다. UPX 3.03w 버전인데, 요즘 나온 버전으로 하면 더 잘될 것이라 예상되네요. 하지만 기본적인 프로그램이라 쉽게 됩니다. 기본적인 사용법은 -d 만 알면 됩니다. 압축을 푸는 decompress 입니다.


upx -d [패킹이 되어있는 파일] 이런식으로 적어주면 언패킹이 진행됩니다.


언팩이 완료가 되었습니다. 따로 다른이름으로 저장하지 않고, 패킹이 되어있는 파일을 그냥 언팩시켜줍니다. 


다시 Exeinfo PE로 실행하면 패킹이 풀려있고, TASM 어셈블러 도구로 작성이 되어있습니다.


용량 크기도 다릅니다. 58.0KB -> 207KB 


디버거로 실행해보면 OEP(00401000)로 실행이 됩니다.이제 언패킹된 파일로 디버깅을 편하게 진행하겠습니다.


밑에 보면 GetDlgItemTextA로 문자열을 읽어들입니다. 두 개가 나오는거 보니, name과 serial을 받아서 작업을 하는것으로 예상할수 있습니다.


GetDlgItemTextA에 BP를 걸고 실행을 하면 입력창이 나오는데 문제에 나온대로 name에는 CodeEngn을 넣고 serial에는 모르니까 임의 숫자 1234를 넣어서 비교하는 루틴과 비교할것으로 예상됩니다.


이 루틴은 name으로 입력한 CodeEngn을 읽어와서 값을 바꾸는 루틴입니다. 


첫 번째 줄에서 EDX에 MOV를 하는 403038값은 name에 입력했던 CodeEngn에서 "Code"부분입니다. 일단 4바이트만큼 EDX에 넣습니다. 


두 번째 줄에는 EAX+403037부분을 실행하는데 즉, 403037은 아무것도 아닌 값이고 EAX는 현재 레지스터를 보면 '1'입니다. 둘을 더하면 입력했던 name의 첫 글자 403038에 포인터가 가게되어 DL에 43(C) 을 DL에 가져옵니다. EDX를 보면 이미 DL에 43이 들어가 있기 때문에 변동이 없습니다.


세 번째 줄에서는 EDX에 있는 "Code"와 0xFF를 AND 시킵니다. 값은 00000043 이 되었습니다.


네 번째 ,다섯 번째 줄을 보면 일단 EDX의 값(AND된 값)을 EBX에 옮기고 다시 둘이 IMUL을 진행합니다. 값은 1189가 됩니다.


여섯 번째 줄에서는 EBX(IMUL된 값)와 ESI를 더해서 ESI(0)는 1189 값이 됩니다.


일곱, 여덟, 아홉, 열 번째 줄을 보면 일단 EBX에 43을 복구합니다. 그리고 SAR로 EBX를 오른쪽으로 1을 SHIFT합니다. 21이 됩니다. 그리고 다시 ESI와 EBX를 더해주면 ESI에는 11AA 값이 들어갑니다. 그리고 ESI에 다시 EDX를 빼주어서 1167이 됩니다.

     


INC EAX와 DEC ECX를 해주는 이유는 EAX는 포인터 위치를 정하는 값입니다. 두 번째 줄을 보면 EAX에 403037을 더하는걸 볼 수가 있습니다. 2를 더해서 43(C)가 끝나고 다음 값 6F(o)를 가져오는 역할을 합니다. ECX는 문자열의 길이를 가져오는데, C가 끝났으니 size(odeEngn) == 7 이기때문에 1을 빼줍니다. 

루틴은 CodeEngn 8글자가 모두 완료 될 때 종료가 됩니다. 


아래 레지스터는 8글자를 모두 검사했을 때 마지막으로 나오는 값들입니다. 결국은 ESI값들을 모두 더해서 루틴을 빠져나오네요. CodeEngn을 이용해서 ESI를 구한 값은 129A1 이 됩니다. 


루틴을 종료하고 다음 줄인데, ESI와 아까 임의로 입력한 Serial "1234"를 인자로 하고 00401383 함수를 실행합니다. 안으로 한번 들어가서 보겠습니다.


두 번째 루틴입니다. 아까 보다는 루틴이 좀 복잡하지만 하나하나 설명 하겠습니다.


일단, 입력한 Serial을 받아서 길이를 알아옵니다. EAX에 4를 리턴 시킵니다.


MOV ESI, [ARG.1]까지 트레이싱을 한 결과입니다. 일단, PUSH EBX를 해준 이유는 EBX가 이 루틴에서 필요없어서 PUSH를 시켜준 다음에 나중에 리턴하기 전에 POP으로 복원을 합니다. 즉, 밥을 먹을때 그릇이 부족하니, 그릇에 있던 음식을 다른 데에 놨다가 다먹고 다시 설겆이 후에 다시 그 음식을 가져오는 역할을 합니다. 개소리가 길었네요. 다음 XOR EBX, EBX 부분이 설겆이 부분입니다. 그리고 ECX에 EAX(1234의 문자열 길이)를 복사하고, ESI에는 1234가 들어있는 곳(403138)을 복사합니다.


아래의 루틴을 분석 해보겠습니다. 일단 첫, 두번째 줄은 ECX 원본을 다른 곳에 넣고, EAX를 설겆이 합니다.


LODS는 SI 내용을 AL에 로드시킵니다. ESI는 403139입니다. 그 안의 내용 1,2,3,4를 AL에 로드합니다. 일단, 1(31)을 로드하고 있습니다.


SUB EAX, 30으로 가져온 1(31)에서 30을 빼서 1을 만들고, ECX(길이)를 감소시킵니다.


이 루틴이 중요 루틴입니다. IMUL은 AX와 오퍼랜드를 곱셈하고 AX또는 DX:AX에 저장을 합니다. MUL은 부호가 없는 값이고, IMUL은 부호가 있습니다. 즉 곱해준다는 소리입니다. EAX, EAX, 0A를 곱합니다. 곱한 값을 EAX에 넣고, 다시 EAX를 EBX에 더해줍니다. EBX는 현재 0이기 때문에 1(31), 2(32), 3(33), 3(34) 모두 IMUL작업을 진행하고 EBX에 더해줍니다. 이런 형태로 반복이 됩니다. 




EAX가 1일 때 IMUL한 결과입니다. LOOPD를 통해서 반복을 합니다. 3번을 한 이유는 ECX가 3이기 때문입니다. ECX만큼 LOOPD를 돕니다. 형태를 보면 1 -> A -> 64 -> 3E8 이 되고 ADD EBX, EAX를 통해서 EBX에 값을 저장합니다.

    



EAX가 2가 될 때 IMUL한 결과입니다. 2 -> 14 -> C8 이 됩니다. EBX에 더하면 3E8 + C8 = 4B0 이 저장됩니다.

 

   



EAX가 3가 될 때 IMUL한 결과입니다. 3 -> 1E 가 됩니다. EBX에 더하면 4B0 + 1E = 4CE 가 저장이 됩니다. ECX에서 잘못 나왔네요. BP를 잘 못찍어서 값이 변환 되었네요 ECX를 2 -> 0으로 생각해주세요. 죄송합니다.

  


EAX가 4가 될 때 결과입니다. ECX를 위에서 1을 빼고 오기 때문에 ECX는 0이 되므로 JE에서 바로 점프를 시켜서 IMUL을 마주치지 않고 바로 ADD 명령으로 갑니다. EBX에 있던 4CE와 4를 더해서 4D2를 만들어 냅니다.

 



아래 그림은 반복문을 탈출하고 리턴하기 전의 모습인데, EBX의 값을 EAX(리턴값)에 복사하고 EBX는 삭제를 합니다.

  


함수를 빠져나와서 바로 아래 줄을 보면 CMP로 EAX와 ESI를 비교합니다. 둘이 맞을 시에 성공을 하고 Z값이 1이 되어 JNZ를 통과하여 성공을 하게 됩니다.


EAX와 ESI를 비교하는걸 생각했을 때, ESI 아까 생각나시나요? NAME값을 조작해서 ESI에 129A1을 집어 넣어줬죠. 솔직히 답은 아까 전에 있었습니다. NAME값을 가지고 변조했을 때 말입니다. 즉, NAME값의 시리얼은 NAME값을 조작한 값입니다. 

이렇게 두 루틴을 모두 분석을 했습니다. 솔직히 답을 찾기 위해서는 성공 루틴 위에 BP를 걸고 풀어도 되지만 이렇게 하나하나 바뀌는 값을 봐야 나중에 어려운 문제를 풀때 도움이 많이 될 것입니다. 답만 찾으려고 하지마시기 바랍니다.
















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

[codeEngn] Basic RCE level16  (0) 2015.07.30
[codeEngn] Basic RCE level15  (0) 2015.07.29
[codeEngn] Basic RCE level13  (0) 2015.07.29
[codeEngn] Basic RCE level12  (0) 2015.07.29
[codeEngn] Basic RCE level11  (0) 2015.07.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함