'lena's tutorial 17'에 해당되는 글 2건

  1. 2011.02.22 [Reversing With Lena] lena's tutorial 18 풀이
1. 개 요
예제 문제 및 강의 내용 출처 : http://www.tuts4you.com/
이번 Lena의 18장 강의에서는 리버싱을 어렵게 하는 decrypt code, self-modifyng 등에 대해 설명한다.

2. 사용도구
Ollydbg :
http://www.ollydbg.de


3. 내 용
먼저 크랙 대상이 되는 프로그램의 동작을 통해 이번 강의의 제거 대상이 되는 nag를 찾아보도록 한다.
[그림 1]과 같이 대상이 되는 "ReverseMe Tutorial.exe" 실행시 제거 대상이 되는 TutorialNag라는 메시지창이 나타나는 것을 알 수 있다.
[그림 1]


OllyDbg를 이용하여 해당 파일을 열어보자. 프로그램 시작 부분에 [그림 2]와 같이 OllyDbg가 제대로 해석을 하지 못해 엉뚱한 내용들이 출력되는 것을 볼 수 있다. 이럴 경우 "마우스 우클릭 → Analysis → Remove analysis from module" 실행시 해당 코드가 제대로 번역되는 것을 볼 수 있다. 이런 것을 미연에 방지하기 위해서는 "Options → Debugging options → Analysis1 → Auto start anaysis of main module"의 체크를 해제해 놓도록 한다.


조금만 살펴보면 [그림 3]와 같이 쉽게 MessageBox를 이용하여 제거 대상인 nag를 생성하는 부분을 쉽게 확인할 수 있다.(이게 끝이라면 18번 강의에 나올만한 내용이 아닐텐데라는 의구심이 들었다.) 아무튼 MessageBox 함수에 BP(Break Point)를 설정한 뒤 실행해보자.
[그림 3]
분명 MessageBoxA의 첫 파라미터를 PUSH 하는 부분(0x004012AF)과 MessageBoxA를 호출하는 부분(0x004012DB)에 BP를 설정하였으나 위와 같이 메시지 박스가 생성되는 것을 볼 수 있다. 따라서 해당 MessageBoxA 함수 부분은 속임수이며 실제로 메시지 창을 생성하는 부분은 다른 곳에 위치한다는 것을 유추할 수 있다.

다시 프로그램의 시작부분으로 돌아가 첫번째 함수를 CALL하는 부분을 살펴보자. [그림 4]와 같이 EAX를 4000000으로 EDI를 401011로 설정한 뒤 401299에서 첫번째 함수를 호출하는 것을 볼 수 있다.
[그림 4]

해당 함수로 Step-in 해서 들어가 보자. [그림 5]와 같이 해당 함수는 401000부터 401218까지 1 바이트씩 증가시키면서 5A와 XOR하는 함수임을 알 수 있다. 이는 XOR 연산을 통하여 실제 코드를 메모리상에  decryption(복호화)해주는 부분이다.
[그림 5]
위의 함수가 호출되기 전후의 메모리 상의 코드를 비교해 보면 [그림 6]과 같다.
[그림 6]

메모리 상의 실제 코드를 생성한 뒤 40129E에서 다시 함수를 CALL하는 것을 볼 수 있다. 해당 함수는 복호화 루틴에 의해 새로 생성된 401011 위치의 코드를 호출하는 것을 볼 수 있다. Step-in하여 해당 코드를 살펴보자. [그림 7]과 같이 401011 부터는 ADD 연산을 통하여 EDI 값을 증가시켜 가면서 MOV 연산을 통하여 EDI가 가르키는 값을 변경하고 있는 것을 볼 수 있다. 최초 EDI 값은 401011로 현재 서브루틴의 최초 진입점임을 알 수 있다. 즉, 아래 과정이 진행되면서 현재 자신의 코드값을 변형시키는 것을 볼 수 있다. 이를 Lena171의 강의에서는 self-modifying이라는 용어를 사용하고 있다.
[그림 7]

self-modifying 과정을 거친 후 401011의 값들은 [그림 8]과 같이 변경되는 것을 볼 수 있다. 또한 CALL EDI 명령을 통하여 401000으로 흐름이 넘어가는 것을 볼 수 있다. self-modifying 과정을 거치면서 MessageBoxA 함수를 호출하는 부분이 생성된 것을 볼 수 있다.
[그림 8]
하지만 아직 MessageBoxA가 호출되기 전 PUSH 되는 파리미터를 보면 Title과 Text의 값이 알아볼 수 없는 문자들인 것을 볼 수 있다. 이는 401000에 있는 JL에 의한 반복문에 의해 0B3과 XOR이 되면서 Title과 Text에 전달되는 파라미터 값들이 decryption되는 것을 볼 수 있다. 최종적으로 MessageBoxA가 호출되기 전의 상태를 보면 [그림 9]와 같다.
[그림 9]
우리가 제거하고자 하는 nag가 40101F에서 생성되는 것을 확인할 수 있다. 이후 JMP 구문에 의해 40106A로 분기하게 된다.

40106A로 이동 후 이번에도 ADD구문에 의해 EDI 값을 증가시키면서 MOV 구문을 통해 EDI가 가르키는 값을 변경하는 것을 볼 수 있다. [그림 7]에서 nag를 생성했던 부분과 비슷한 형식으로 되어있으며 역시 self-modifying 과정이 진행되는 것으로 유추할 수 있다.
[그림 10]
최종적으로 4010B4에서 CALL EDI 구문에 의해 401011로 이동하게 된다. 두번째 self-modifying 과정에 의해 생성된 코드 값은 [그림 11]과 같다. 이는 실제 메인 프로그램창을 생성하는 부분이다. 또한 메인 프로그램 창이 종료될 경우 401026의 JMP 구문에 의해 401054로 분기되는 것을 볼 수 있다.
[그림 11]

401325에서는 [그림 12]와 같이 기본에 nag의 title과 text의 값이 저장되어 있는 403000 주소의 값을 한 바이트씩 증가시키면서 8D와 XOR하는 것을 볼 수 있다. 이는 흔적을 없애기 위해 메모리 상에 생성되었던 값들을 다시 암호화 시켜주는 과정이다.
[그림 12]
이후 프로그램은 ExitProcess를 호출하여 종료된다.
정리하면 nag 생성 과정은 다음과 같다.
1. show diversion(decoy) code
2. decrypt code section
3. run self-modifying code to create the nag
4. run the nag
5. run some more self-modifying code to create the main program
6. run the main program
7. destory the data section by re-encrypting it with the nag!

4. nag 제거 방법
[그림 12]와 같이 self-modifying 과정이 끝난 뒤 코드를 보면 401024에서 MessageBoxA를 이용하여 nag를 생성하는 것을 볼 수 있으며, nag 생성 후 401024에서 JMP 구문을 통해 40106A로 분기하는 것을 볼 수 있다.
[그림 12]
따라서 MessageBoxA를 이용하여 nag를 생성하기 전인 401011에서 JMP 구문을 이용하여 40106A로 분기해 준다면 nag 창은 생성되지 않을 것이다. 이런 가정을 하고 [그림 13]과 같이 변경한 뒤 프로그램을 실행해 보면 nag 창이 생성되지 않는다는 것을 알 수 있다.
[그림 13]
decrypt 과정과 self-modifying 과정을 거친 후 401011 주소의 값을 보면 "6A 00"인 것을 알 수 있다. decrypt 과정에서 5A로 XOR 되므로 decrypt 이전의 값은 "30 5A" 인것을 알 수 있다. 최초 OllyDbg를 이용하여 프로그램을 로딩한 후 "30 5A" 값이 있는 주소를 찾아보면 [그림 14]와 같이 401016과 401017에 해당 값이 존재한다는 것을 알 수 있다.
[그림 14]
우리는 이 값이 [그림 13]과 같이 5A와 XOR 뒤에 "EB 57"이 되도록 변경해 주어야 하므로 각각 5A로 XOR 해주면 "B1 0D"인 것을 알 수 있다. 따라서 [그림 15]와 같이 401016~401017의 값을 "B1 0D"로 변경해 준다. 변경 방법은 해당 주소에서 우클릭 후 → Binary → Edit를 클릭한다.
[그림 15]
이후 프로그램 실행시 nag 창이 생성되지 않는 것을 볼 수 있다. 변경된 코드를 패치한 프로그램을 저장하기 위해서는 우클릭 → Copy to executable → All modifications → copy all → 우클릭 → Save file로 저장한다.

5. 결 론
decoy code와 decryption과정, self-modifying 과정을 거치는 프로그램에 대한 크랙 과정을 살펴보았다. 실제 악성코드에서도 본래의 코드를 숨기기 위해 많이 사용되는 방법으로 확실한 이해가 필요하지 않을까 한다. 이 포스팅에 있는 기술들을 악용하여 상용 프로그램을 크랙하는 우를 범하지 않았으면 한다.
                                                                                                    +---------------------------------+
                                                                                                    | Infinite Flow..                              |
                                                                                                    | mail : geekspark@gmail.com         |
                                                                                                    | Blog : http://sinun.tistory.com       |
                                                                                                    | twitter : @unpacker                      |
                                                                                                    | CISSP                                        |
                                                                                                    +----------------------------------+
저작자 표시 비영리 변경 금지
신고
Posted by By. PHR34K

티스토리 툴바