본문 바로가기

Malware Analysis

SecondSample.vir(가칭) 분석

개요

 

파일 정보

 

파일 이름 : SecondSample.vir(가칭)

파일 유형 : 리치 텍스트 포맷(*.rtf)

파일 크기 : 366KB(375,322 Bytes)

파일 해시 : 비공개

악성 행위 : CVE-2017-11882 사용, 파일 다운로드(URL 만료), 파일 실행

 

흐름도 

 

악성코드가 실행될 때 어떤 과정을 거쳐서 어떤 행위를 하는지 표현해봤다.

 

 

특징

 

[*] SecondSample.vir

 

해당 파일을 열면 CVE-2017-11882 취약점이 발동하며 쉘코드가 실행된다.

1단계 쉘코드는 XOR Encrypt된 2단계 쉘코드를 복호화하는 작업을 진행한다.

2단계 쉘코드는 특정 URL에 접속하여 파일을 다운로드 받고 실행한다.

 

[*] ugopx6413.exe

 

SecondSample.vir에 의해 로컬 컴퓨터에 다운로드받아진 후, 실행되는 악성코드이다.

실질적인 악성 행위를 할 것으로 추정되는데, URL이 만료되어 해당 파일을 구할 수 없었다.

분석자가 악성코드의 동작을 설명하기 위해서 간단한 메세지박스를 띄워주는 프로그램을 만들었고

해당 보고서에서는 악성코드가 잘 동작한다는 것을 증명하기 위해서 사용된다.

 


분석

 

정적 분석

 

Detect It Easy로 Sample.vir 파일을 확인해본 결과, 해당 파일은 Rich Text Format, RTF 문서이다.

 

 

Hxd를 이용하여 파일의 데이터를 살펴봤다.

분석을 방해하기 위한 기법들이 사용된 것을 확인할 수 있었다.

(각 기법에 대한 설명이나 예제는 아래 포스트를 참조하길 바란다.)

 

 

Anti-Analysis Tricks in Weaponized RTF | Decalage

This article describes several anti-analysis tricks found in recent malicious RTF documents, and how I improved rtfobj to handle them. Weaponized RTF documents The RTF format has always been considered as quite safe compared to other MS Office formats. It

www.decalage.info

 

1. Dummy RTF Control Words Within the Hex-encoded Data

 

 

2. Extra Whitespace Between Hex Digits

 

 

문서에 삽입된 OLE 객체의 목록을 살펴보고 쉘코드로 의심되는 데이터를 추출하기 위해서

rtfobj.py를 사용했다. 

 

 

-s 옵션을 추가하여 쉘코드로 추정되는 0번 객체를 추출 및 저장했다.

해당 객체의 데이터를 0xA부터 디스어셈블했을 때 "확실히 쉘코드일 확률이 높다"라는 생각이 들었다.

하지만 확신하기는 어려웠고 동적 분석 과정에서 추출한 파일이 쉘코드가 맞는지 확인하기로 결정했다.

 

동적 분석

 

정적 분석 과정에서 악성코드가 CVE-2017-11882를 사용할 수 있다는 정보를 얻었다.

동적 분석을 진행하기 위해서 CVE-2017-11882가 발생하는 환경을 구축해야 한다.

 

하지만 분석자는 CVE-2017-11882를 분석해본 경험이 없었다.

그래서 해당 취약점에 대한 조사를 먼저 진행했다.

 

해당 취약점은 Microsoft Office 프로그램에서 공용으로 사용하는 수식 편집기 프로그램(EQNEDT32.exe)에서

발생하는 취약점이다.

 

아래 목록의 버전에서 해당 취약점이 발생할 수 있다.

 

  • Microsoft Office 2007  Service Pack 3
  • Microsoft Office 2010  Service Pack 2
  • Microsoft Office 2013  Service Pack 1
  • Microsoft Office 2016

 

 

 

Windows x86 환경에서 "HKLM\SOFTWARE\Microsoft\Office\Common\COM Compatibility\{0002CE02-0000-0000-C000-000000000046}" 해당 레지스트리 경로에 "Compatibility Flags" 해당 속성과 0x400 해당 값이 있다면 취약점이
제대로 발동되지 않을 수 있다.

 

환경을 구축할 때, Microsoft Office를 설치하고 난 후, 레지스트리 편집기에 가서 해당 경로에 해당 속성과 값이 있는지

꼭 확인해보고 있다면 악성코드를 분석하기 위해서 반드시 삭제해야 한다.

 

 

취약점의 원인인 수식 편집기 프로그램이 실행될 때, 디버거를 붙여야 한다.

그러므로 gflags, x64dbg를 이용하여 동적 분석을 진행할 것이다.

 

Image File 탭에서 EQNEDT32.exe라는 이름으로 프로세스가 실행되면 해당 경로의 디버거가 실행될 수 있도록

설정을 해준다.

 

 

문서를 열었고, 수식 프로그램이 실행됐을 때 디버거에 붙여주는 것을 성공했다.

 

 

0x41160F, 0x411874에 중단점을 설치하고 스택과 EBP의 변화를 관찰하며 프로그램을 실행시켰다.

그 결과, 쉘코드가 실행되기 시작했을 때부터 디버깅을 진행할 수 있게 됐다.

 

 

일단 메모리를 덤프한 후, 정적 분석에서 뽑았던 OLE 객체의 데이터가 지금 실행되고 있는 쉘코드의 데이터랑 어느 정도

일치하는지 비교해볼 것이다.

 

아래 사진은 rtfobj.py를 이용하여 추출한 OLE 객체의 데이터를 IDA의 Hex-View 기능을 통해서 살펴본 것이다.

 

 

아래 사진은 덤프한 메모리의 데이터를 IDA의 Hex-View 기능을 통해서 살펴본 것이다.

 

 

완벽히 일치하는 결과까지는 아니지만 그래도 쉘코드에 해당하는 데이터들을 뽑아내는데 성공했다.

이제 실질적으로 디버거를 통해서 분석을 진행할 일만 남았다.

 

1단계 쉘코드에 진입하기 위해서 ecx, edi를 이용해서 핸들과 edx, eax를 이용해서 GlobalLock 함수의 주소를

찾은 뒤 GlobalLock 함수를 호출하고 반환값으로 받은 주소에 0x2CE70을 더한 후 jmp하는 코드이다.

 

 

아래 사진들은 1단계 쉘코드의 수행하는 명령어들을 모아놓은 것이다.

(2단계 쉘코드를 XOR연산을 이용하여 복호화 시켜주는 것)

 

1. edx 레지스터에 add 명령어를 이용하여 복호화 시작 지점의 주소를 저장한다.

 

 

2. ebp 레지스터에 lea 명령어를 이용하여 복호화 끝 지점의 주소를 저장한다.

 

3. ecx 레지스터의 값을 imul 명령어를 이용하여 0으로 만들어준다.

 

 

4. ecx 레지스터의 값에 0x2B275ABB를 곱한 결과를 다시 저장한다.

 

 

5. ecx 레지스터 값에 0x554E0F85를 더해준 값을 다시 저장한다.

 

 

6. edx 레지스터가 가르키는 주소의 값과 ecx 레지스터의 값을 XOR 연산한 후, 주소에 결과를 저장한다. 

 

 

7. edx 레지스터 값에 4를 더한 값을 다시 저장한다.

 

 

8. ebp 레지스터의 값이 edx 레지스터보다 큰지 확인하고 크다면 다시 4번부터 8번까지의 과정을 반복한다.

 

 

중요한 연산을 할 때마다 JMP 명령어가 존재해서 일일히 트레이싱하며 사진을 찍었다.

이해를 돕기 위해서 해당 복호화 코드를 C언어로 다시 작성했다.

 

#include <stdio.h>

int main()
{
	unsigned char data[] = { 0x04,0xE3,0xCE,0x57,0xAC,0x27,0xE3,0xD9,0x29,0x82,0x9A,0xEA, ...};
	unsigned int key = 0;

	
	printf("[*] decrypt start\n");

	for (int i = 0; i < sizeof(data); i = i + 4)
	{
		
		key = key * 0x2B275ABB;
		key = key + 0x554E0F85;

		unsigned int temp = key ^ (data[i] | data[i + 1] << 8 | data[i + 2] << 16 | data[i + 3] << 24);
		
		data[i] = temp & 0xFF;
		data[i + 1] = (temp & 0xFF00) >> 8;
		data[i + 2] = (temp & 0xFF0000) >> 16;
		data[i + 3] = (temp & 0xFF000000) >> 24;

	}

	printf("[*] decrypt end\n");

	printf("[*] decrypt result-----------------\n");

	for (int i = 0; i < sizeof(data); i++)
		printf("%02X ", data[i]);
	printf("\n");
	printf("------------------------\n");

	return 0;
}

 

복호화 작업 전, 2단계 쉘코드의 데이터이다.

해당 데이터들을 봤을 때, 어떤 행동을 하는지 감이 잡히지 않는다.

 

 

복호화된 데이터를 살펴봤을 때, 2단계 쉘코드에서 어떤 행위를 할지 추측할 수 있는 정보들이 존재한다.

(핑크색 : 모듈 이름, 노란색 : 함수 이름, 초록색 : 파일 다운로드 경로, 하늘색 : 파일 다운로드 URL)

 

 

실질적인 악성 행위를 수행하는 2단계 쉘코드의 데이터가 복호화 되었으므로 메모리를 덤프하고

IDA를 이용하여 분석을 진행했다.

명령어와 문자열 데이터가 섞여 있기 때문에 제대로된 디스어셈블 결과를 얻는데 시간이 걸렸다.

 

getKernel32Address 함수는 Kernel32 모듈이 로드된 메모리의 주소를 얻어오는 함수이다.

customGetFunctionAddress 함수는 모듈에서 API의 주소를 직접 구해오는 함수이다.

 

Kernel32 모듈이 로드된 메모리 주소를 얻어오고 LoadLibraryW, GetProcAddress 함수의 주소를 얻어오는 코드다.

 

 

ExpandEnvironmentStringW 함수의 주소를 구하고 환경 변수가 섞인 문자열을

환경 변수가 의미하는 값(디렉토리 경로)으로 환경 변수에 해당하는 문자열을 바꿔준다.

 

 

URLMON 모듈을 메모리에 로드한다.

URLDownloadToFileW 함수의 주소를 구한다.

C2 서버에서 악성코드를 다운로드 받아서 아까 환경 변수 값을 바꿨던 문자열, 디렉토리 경로에 저장한다.

 

 

GetStartUpInfoW 함수의 주소를 구하고 호출하여 CreateProcessW 함수를 실행할 준비를 하고

CreateProcessW 함수의 주소를 구하고 호출하여 다운로드 받은 악성코드를 실행한다.

 

마지막으로 ExitProcess 함수의 주소를 구하고 호출하여 프로그램을 종료시킨다.

 

 

마지막으로 악성코드가 잘 동작하는 것을 확인하기 위해서 프로그램이 실행될 때 메세지박스를 띄워주는 코드를

작성하고 컴파일하여 악성코드가 제대로 실행되는지 확인하고 분석을 마무리하겠다.

 

(MessageBoxA 함수를 이용하여 메세지박스를 띄어주는 프로그램을 만들고 이름을 바꿔주고 알맞은 경로에 옮겨줬다.)

 

 

URLDownloadToFile 함수가 실패했지만 아까 배치한 프로그램 때문에 CreateProcessW 함수는 정상적으로 실행된다.

 

 

메세지박스가 정상적으로 뜨는 모습을 확인할 수 있다.

 

 

후속 악성코드를 다운로드 받기 위해 URL에 접속해봤지만 URL이 만료되어 파일을 다운로드 받을 수 없었다.

아쉬움이 남아 악성코드가 이렇게 작동한다는 점을 확인하고 분석을 마친다.

 


결론

 

해당 샘플은 CVE-2017-11882를 사용하여 쉘코드를 실행시켜 파일을 다운로드하고 실행하는 분명한 악성코드이다.

 


참조

 

(RTF 악성코드가 사용하는 분석을 방해하는 기법)

www.decalage.info/rtf_tricks#Anti-Analysis_Tricks

 

(CVE에 대해 조사할 때 참조 자료를 찾기 위해 방문했던 사이트)

nvd.nist.gov/vuln/detail/CVE-2017-11882

 

(수식 편집기 프로그램에 의해서 취약점이 발동된다는 정보를 확인한 사이트)

reversingminds-blog.logdown.com/posts/3907313-fileless-attack-in-word-without-macros-cve-2017-11882

 

(특정 레지스트의 경로의 특정 속성, 값을 등록하면 취약점 발동을 막을 수 있다는 정보를 확인한 사이트)

blog.alyac.co.kr/1413

 

(CVE-2017-11882를 어떻게 분석해야 하는지 실질적인 정보를 얻은 사이트)

monster-bbulman.tistory.com/19

 

(RTF Control Word를 조사하는데 참조했던 자료)

Word2007RTFSpec9.pdf
2.06MB