Code Engn - Basic 20 RCE

Posted by ORANG ORANG(오랑)
2015.06.10 02:01 Reversing/Code_Engn(Basic)



코드엔진 basic 마지막 문제. 위와같은 방식으로 출력되도록 하면 된다.

먼저 PEiD로 확인해보니 어셈블리어로 코딩되어있는 듯하다.



실행해보면 그냥 아래와 같음


먼저 코드부터 확인해보니 CreateFileA()에서 반환값이 -1이다.

Mode = OPEN_EXISTING 인데 "CRACKME3.KEY" 파일이 존재하지 않기 때문이다. 파일을 만들고 진행해보면..



아래와 같은 코드들이 나오는데 이부분이 핵심이다.


먼저 file로부터 0x12(18)바이트 를 읽어오는데, 읽어온 데이터는 0x402008 에, 읽어온 데이터의 길이값은 0x4021A0에 저장한다.

그리고 조건 분기문을 두번 통과하면 Cracked가 출력되는 함수로 이어지게 된다.


먼저 첫번째 조건문은 0x401066 을 보면 읽어온 길이값이 0x12인지 체크한다.


두번째 조건문이 되는 부분은 0x401093 인데, 먼저 해당라인 윗쪽의 코드를 봐야한다.

0x401311 함수에 0x402008(버퍼 포인터)를 인자로 전달하는데 해당 함수는 밑밑그림(0x401311~0x40133b)과 같다.

해당 함수를 보면..

간단하게 0x41부터 1씩증가하면서 버퍼에 읽어온 문자열들을 1바이트씩 xor하고,

버퍼의 문자열의 헥사값을 1바이트씩 반복해서 0x4020f9 에 더해준다.

그리고 xor 연산 결과가 0 이거나 14번 루프를 반복한 후에는 종료


버퍼를 xor하는 부분이 Cracked by : [####] 부분이 세팅되는 부분이고, 0x4020f9는 이후 조건 분기문에서 사용되는 부분이다.

해당 함수를 마치고 나면, 0x401079에서 0x4020f9의 값을 0x12345678과 xor 하게 된다.

그리고 이 값을 0x40133c(밑밑밑 그림)의 반환값으로 받는 0x402016(0x402008+0xE)에 있는 값과 비교하고 일치하면 Crack 성공!






위 함수의 내용을 파이썬 코드로 그대로 옮겼다.

앞부분 14바이트는 문자열이 나와야하고 // 뒤 4바이트는 연산과정에서 세팅되는 0x4020f9 부분이 된다.



'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 20 RCE  (0) 2015.06.10
Code Engn - Basic 19 RCE  (0) 2015.06.09
Code Engn - Basic 18 RCE  (0) 2015.06.09
Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
이 댓글을 비밀 댓글로

Code Engn - Basic 19 RCE

Posted by ORANG ORANG(오랑)
2015.06.09 15:45 Reversing/Code_Engn(Basic)




실행시켜보면 위와같은 메세지창 하나만 뜨고 누르면 종료된다.



UPX로 패킹되어있어서 일단 언패킹 후 디버깅을 시작해보면.. 제대로 동작하지 않고 경고창이 뜬다.


API 목록을 보니 IsDebuggerPresent()를 이용하여 안티디버깅이 되어있었다. 일단 이부분을 패치하고 진행해보면..




일단 문제에서는 밀리세컨드 단위로 종료되는 시간을 구하라고 하길래, sleep함수가 사용된 부분을 먼저 찾았다.

찾다보니 아래와 같이 timeGetTime()함수가 호출되는 부분이 있었고 해당 함수를 찾아보니..



윈도우 시작 시점으로부터 시간을 재는 용도의 함수였다.


일단 해당 함수가 호출되는 부분들을 모두 찾아봤는데, 문제에서 시간의 차이를 잰다는 점을 이용하여

timeGetTime() - timeGetTime() 이런 형식으로 되어있는 부분을 찾았다.



아래 부분을 보면..


EDI에 timeGetTime()의 주소를 넣어주고, EBP에 sleep()의 주소를 넣어준다.

제일먼저 timeGetTime() 한 리턴값을 ESI에 저장해두고,

다시 timeGetTime()을 호출하며 0x444d38로 점프하게된다.( 두번째 시간값이 첫번째 시간값보다 항상크므로 항상 점프)


0x444d38로 가게되면.. 두값의 차와 [EBX+4]에 있는 값을 비교하고, [EBX+4]의 값보다 클 경우 점프

그렇지 않을 경우 sleep(10) 이후 다시 2번째 시간을 재는 부분으로 점프하며 루프를 돌게된다.




조건 분기문에서 [EBX+4]값을 확인해보면..



'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 20 RCE  (0) 2015.06.10
Code Engn - Basic 19 RCE  (0) 2015.06.09
Code Engn - Basic 18 RCE  (0) 2015.06.09
Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
이 댓글을 비밀 댓글로

Code Engn - Basic 18 RCE

Posted by ORANG ORANG(오랑)
2015.06.09 01:58 Reversing/Code_Engn(Basic)




PEiD로 확인해보니 [Nothing found *] 라고만 뜬다. 불안했는데 패킹은 되어있지 않았고

실패 or 성공의 조건 분기점을 찾아 브포를 걸고 확인해보니 CodeEngn일때의 Serial 값이 바로보였다.




'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 20 RCE  (0) 2015.06.10
Code Engn - Basic 19 RCE  (0) 2015.06.09
Code Engn - Basic 18 RCE  (0) 2015.06.09
Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
이 댓글을 비밀 댓글로

Code Engn - Basic 17 RCE

Posted by ORANG ORANG(오랑)
2015.06.09 01:45 Reversing/Code_Engn(Basic)




Name은 1글자래서 넣었는데 Key값에 넣어준 문자얼이 위그림처럼 바뀌었다.


IDA로 열어보면 조건문 2개(35라인, 42라인)을 먼저 통과해야하는데, 길이값을 나타낸다.

찾아내야하는 Name은 1글자이므로 바이너리의 해당 조건문을 찾아서 nop으로 바꿔주었다.






'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 19 RCE  (0) 2015.06.09
Code Engn - Basic 18 RCE  (0) 2015.06.09
Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
Code Engn - Basic 14 RCE  (0) 2015.05.30
이 댓글을 비밀 댓글로

Code Engn - Basic 16 RCE

Posted by ORANG ORANG(오랑)
2015.06.08 13:46 Reversing/Code_Engn(Basic)




C++로 되어있다. IDA로 열어보면..



문자열 Name을 입력받고 58라인과 62 라인의 연산을 통해 세팅되는 v20과 Pssword로 입력받는 v19를 비교한다.

Name의 길이값만을 가지고 연산하기 때문에 크게 어렵지 않다.






'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 18 RCE  (0) 2015.06.09
Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
Code Engn - Basic 14 RCE  (0) 2015.05.30
Code Engn - Basic 13 RCE  (0) 2015.05.29
이 댓글을 비밀 댓글로

Code Engn - Basic 15 RCE

Posted by ORANG ORANG(오랑)
2015.06.04 16:55 Reversing/Code_Engn(Basic)





Main함수의 시작부분부터 찾아서, 인증 성공-실패의 분기점이 되는 조건문을 찾아보니

0x458831의 CMP EAX, DWORD PTR DS:[45b844] 이었다.


0x407774의 함수의 반환값으로 전달되는 EAX레지스터 값과 0x45b844에있는 값을 비교하는데,

0x45b844에 있는 값은 Name으로 전달된 "CodeEngn"의 값을 이용하여 0x458760 함수의 결과 이후 세팅되는 것 같다. 아마도


쨋든 비교되어지는 0x407774함수는 

serial로 입력된 값에 대하여 atoi와 비슷하게 동작하는데, 내부를 보면 0x와 같이 16진수도 계산이 되는듯


비교 조건문을 통과하면 크랙성공!





'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 17 RCE  (0) 2015.06.09
Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
Code Engn - Basic 14 RCE  (0) 2015.05.30
Code Engn - Basic 13 RCE  (0) 2015.05.29
Code Engn - Basic 12 RCE  (0) 2015.05.26
이 댓글을 비밀 댓글로

Code Engn - Basic 14 RCE

Posted by ORANG ORANG(오랑)
2015.05.30 00:51 Reversing/Code_Engn(Basic)




UPX로 패킹되어있길래 언패킹부터 하고 시작하였다.

성공 메세지 문자열을 기준으로 성공과 실패 출력 부분의 조건 분기문을 찾아보니 먼저 아래 입력받는 부분부터 시작되었다.

각각 0x403038 과 0x403138에 입력받은 문자열을 저장하게 되는데, 이후 각각 다른 연산을 통해 나온 결과값을 내게 된다.

이 두 결과값이 일치하면 성공, 다르면 실패.



먼저 첫번째 문자열의 연산과정

0x401309 ~ 0x40132c의 루프 부분.


IDA로 보면 아래와 같다.



두번째 문자열의 연산과정

0x401383에 위치한 함수를 통해서 값을 반환하게 되는데 해당 함수를 보면 아래와 같다.

읽어온 값에서 0x30을 뺀후 루프를 돌며 10을 곱하고, 이 값을 계속 더해나가는 것을 보니 atoi 함수와 같은 역할을 하는 것 같다.



IDA로 보면 atoi 함수와 기능이 같은걸 알 수 있다.


두번째 연산함수가 atoi()이므로, 브루트 포싱할 필요없이

"CodeEngn"에 대한 첫번째 연산 결과값(esi 레지스터에 저장된값)을 10진수 로 넣어주면 인증에 성공할 수 있다.



'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 16 RCE  (0) 2015.06.08
Code Engn - Basic 15 RCE  (0) 2015.06.04
Code Engn - Basic 14 RCE  (0) 2015.05.30
Code Engn - Basic 13 RCE  (0) 2015.05.29
Code Engn - Basic 12 RCE  (0) 2015.05.26
Code Engn - Basic 11 RCE  (0) 2015.05.26
이 댓글을 비밀 댓글로

Code Engn - Basic 13 RCE

Posted by ORANG ORANG(오랑)
2015.05.29 12:50 Reversing/Code_Engn(Basic)




그동안 디버깅해온 방법으로 디버깅하려했더니 제대로 디버깅이 되지 않았다.

Microsoft Visual C# / Basic .Net -> C# 으로 되어있는데, C#은 컴파일시 IL(Intermediate Language)이라는 중간 형태의 코드로 변환하고

실행시 이를 다시 CLR(.Net 플랫폼)을 통해 기계어로 변환된다고 한다.


일단 .Net 디컴파일러가 많은것같길래 ILSpy라는 프로그램을 통해서 디컴파일해보았다.



디컴파일해서 코드의 내용은 알 수 있었지만, 디버깅을 하지 못해 정확한 "text"의 값은 알 수 없었다.

여기서 한참 헤맸는데, 풀이를 찾아보니 F12("pause") 이후 Execute till return 을 통해 접근하는 방법이 있었다.


일단 프로그램을 실행시킨후 해당 PID에 attach해서 디버깅 시작 -> F12("pause") -> Execute till return 이후 진행하다보니 기계어로 변환된 부분을 찾을 수 있었다.

"text"와 입력받은 값을 비교하는 부분을 찾아 key값을 얻어냄







'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 15 RCE  (0) 2015.06.04
Code Engn - Basic 14 RCE  (0) 2015.05.30
Code Engn - Basic 13 RCE  (0) 2015.05.29
Code Engn - Basic 12 RCE  (0) 2015.05.26
Code Engn - Basic 11 RCE  (0) 2015.05.26
Code Engn - Basic 10 RCE  (0) 2015.05.14
이 댓글을 비밀 댓글로

Code Engn - Basic 12 RCE

Posted by ORANG ORANG(오랑)
2015.05.26 16:35 Reversing/Code_Engn(Basic)







'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 14 RCE  (0) 2015.05.30
Code Engn - Basic 13 RCE  (0) 2015.05.29
Code Engn - Basic 12 RCE  (0) 2015.05.26
Code Engn - Basic 11 RCE  (0) 2015.05.26
Code Engn - Basic 10 RCE  (0) 2015.05.14
Code Engn - Basic 09 RCE  (0) 2015.05.10
이 댓글을 비밀 댓글로

Code Engn - Basic 11 RCE

Posted by ORANG ORANG(오랑)
2015.05.26 15:40 Reversing/Code_Engn(Basic)







'Reversing > Code_Engn(Basic)' 카테고리의 다른 글

Code Engn - Basic 13 RCE  (0) 2015.05.29
Code Engn - Basic 12 RCE  (0) 2015.05.26
Code Engn - Basic 11 RCE  (0) 2015.05.26
Code Engn - Basic 10 RCE  (0) 2015.05.14
Code Engn - Basic 09 RCE  (0) 2015.05.10
Code Engn - Basic 08 RCE  (0) 2015.05.09
이 댓글을 비밀 댓글로