サポート情報 | フォーカスシステムズ サイバーフォレンジックセンター

メールでのお問い合わせ
お問い合わせはこちら
東京証券取引所 プライバシーマーク ISMS JUSE

サポート情報

ホーム > サポート情報一覧 > 再展開されたプログラムのImportテーブル

再展開されたプログラムのImportテーブル

目次へ

 新しいスレッドの追跡を実際に行っていきましょう。ここでも、序盤は紆余曲折で、何度も実行して大まかにどのようなことをしているのか、ということを把握していきます。やり方は人それぞれとなりますが、今回はルートになる処理からcallしている処理が、概ねどのような処理をしているか、を把握しながら進めていきました。また、その過程で、特異点があればそこから深く掘り下げていくのも方法でしょう。

 この再展開され、新しいスレッドで実行されたコードでも、やはりWindows APIは使用されていました。「仮想メモリ内のWindows API使用フロー」でもあったとおり、APIの使用の流れを見ていくことで、処理の流れを掴むことの助けになります。

 しかし、「新たな仮想メモリに展開された情報の内容」で抽出したプログラムを解析しても、Importテーブルはありませんでした。ということは、恐らく「仮想メモリ内のWindows APIの使用」と同様のことを行っているだろう、という予想し、調査を進めてみました。すると、「仮想メモリ内のWindows APIの使用」と少し違ったことを行っていました。

 その「少し違った」という部分は、「Windows APIのポインタを探しにいく」という点は同じなのですが、それを序盤にまとめて行い、テーブル化していたのです。そのため、実際の処理中は、「仮想メモリ内のWindows APIの使用」のように毎回GetProcAddressを行うのではなく、テーブルのベースポインタから、それぞれのAPIの固定のオフセットの位置からポインタを取得する方法となっています。

 テーブルの作成では、テーブルの領域を確保するために、0x0040172Aで「NtAllocateVirtualMemory」のAPIポインタを得るcallを行い、そのポインタを用いて0x0040175Aでメモリの取得を実行し、0x0042FC04に格納します。さらに0x00401765以降で、APIのポインタの取得処理を行っています(【図66】参照)。その結果、APIのポインタテーブルができあがります(【図67】参照)。

IDA_Cryptowall_MakeImport1

【図66】APIのポインタをテーブル用メモリ上に展開する処理

 

IDA_Cryptowall_MakeImport2

【図67】APIのポインタをテーブル用メモリ上に展開された結果

 

 利用時には、0x004016E0をコールして、APIのポインタテーブルの開始アドレスを取得し、そのアドレスにAPI固有のオフセットを加算してAPIのポインタを取得して、callを実行しています(【図68】参照)。

IDA_Cryptowall_MakeImport3

IDA_Cryptowall_MakeImport4

【図68】APIのポインタを取得して実行する例

 

 この自作のImportテーブルは、マルウェアの開発者向けの「キット」の可能性もありますが、「マルウェアの表層解析」でも述べたとおり、Importテーブルには「通常のプログラムではあまり使わないがマルウェアがよく使うAPI」があることが予想されます。そのため、ここに展開されたAPIのリストを作成してみました(【表2】参照)。これが、解析しているCryptoWall亜種の「真のImportテーブル」と言えるのではないかと思います。

 表のAPIを見てみると、前半にプロセスやスレッドの制御、それらのメモリの操作、権限の操作、レジストリに関するAPIが多く見られます。中盤は一般的にも使われる文字列操作やファイルに関するAPIが多く見られます。後半にはセキュリティや暗号に関するAPIが多く見られます。

 「マルウェアの表層解析」の【図4】のImportテーブルと比べれば差は歴然で、【表2】からはマルウェアが攻撃する気満々なのが見て取れるくらいです。なにしろ、前半部分でマルウェアによるインジェクションや不正プロセスの起動、操作に必要なAPIや自動起動等を設定するためのレジストリ操作に必要なAPIがあり、中間はそこで使用する文字列の編集やファイル作成のAPIがあり、後半はサービスの操作やマルウェアが通信等を行うときに暗号化に利用できるAPIが見られます。また、ランサムウェアの場合は、CryptEncryptを用いている可能性があります。攻撃者にとって、鍵なしでは解読できない十分な強度があれば、APIの利用のほうが省力化になるためです。

 では、スレッドの処理の続きを見ていきたいと思います。

 

< 新しいスレッドの追跡 目 次 PC毎固有の「ハッシュ値」の計算 >

 

【表2】自作のImportテーブル

オフセット

Windows API

オフセット

Windows API

0x0000

NtClose

0x0150

_swprintf

0x0004

LdrLoadDll

0x0154

sscanf

0x0008

LdrGetProcedureAddress

0x0158

RtlInitAnsiString

0x000C

NtAllocateVirtualMemory

0x015C

RtlInitUnicodeString

0x0010

NtFreeVirtualMemory

0x0160

RtlAnsiStringToUnicodeString

0x0014

NtProtectVirtualMemory

0x0164

RtlUnicodeStringToAnsiString

0x0018

NtQueryVirtualMemory

0x0168

RtlFreeAnsiString

0x001C

NtWriteVirtualMemory

0x016C

RtlFreeAnsiString(重複)

0x0020

NtReadVirtualMemory

0x0170

RtlDosPathNameToNtPathName_U

0x0024

(Null)

0x0174

RtlConvertSidToUnicodeString

0x0028

RltFreeHeap

0x0178

RtlQueryEnvironmentVariable_U

0x002C

memset

0x017C

RtlCompressBuffer

0x0030

memcpy

0x0180

RtlDecompressBuffer

0x0034

memcmp

0x0184

RtlGetCompressionWorkSpaceSize

0x0038

memchr

0x0188

RtlAddVectoredExceptionHandle

0x003C

NtCreateEvent

0x018C

RtlRemoveVectoredExceptionHandle

0x0040

NtOpenEvent

0x0190

RtlInitializeCriticalSection

0x0044

NtSetEvent

0x0194

RtlDeleteCriticalSection

0x0048

NtWaitForSingleObject

0x0198

RtlEnterCriticalSection

0x004C

NtWaitForMultipleObjects

0x019C

RtlLeaveCriticalSection

0x0050

NtQuerySystemInfomation

0x01A0

NtQuerySystemTime

0x0054

NtShutdownSystem

0x01A4

RtlTimeToSecondsSince1970

0x0058

RtlGetNtProductType

0x01A8

NtQueryIntervalProfile

0x005C

NtOpenProcess

0x01AC

RtlRandom

0x0060

NtTerminateProcess

0x01B0

RtlRandomEx

0x0064

NtQueryInformationProcess

0x01B4

GetTickCount

0x0068

NtDelayExcution

0x01B8

CreateProcessInternalW

0x006C

RltAdjustPrivilege

0x01BC

OutputDebugStringA

0x0070

RtlSetProcessIsCritical

0x01C0

WinExec

0x0074

NtOpenThread

0x01C4

CreateFileW

0x0078

NtTerminateThread

0x01C8

ReadFile

0x007C

NtResumeThread

0x01CC

WriteFile

0x0080

NtSuspendThread

0x01D0

FlushFileBuffers

0x0084

NtQueryInformationThread

0x01D4

GetFileSize

0x0088

NtImpersonateThread

0x01D8

SetFilePointer

0x008C

RtlCreateUserThread

0x01DC

GetFileSizeEx

0x0090

NtCreateThreadEx

0x01E0

SetFilePointerEx

0x0094

CsrClientCallServer

0x01E4

GetFileAttributesW

0x0098

(Null)

0x01E8

SetFileAttributesW

0x009C

NtGetContextThread

0x01EC

SetEndOfFile

0x00A0

NtSetContextThread

0x01F0

GetFileTime

0x00A4

RtlExitUserThread

0x01F4

SetFileTime

0x00A8

NtQueueApcThread

0x01F8

GetLogicalDriveStringsW

0x00AC

NtSetInformationThread

0x01FC

GetVolumeInformationW

0x00B0

NtOpenProcessToken

0x0200

GetDriveTypeW

0x00B4

NtQueryInformationToken

0x0204

CloseHandle

0x00B8

NtCreateFile

0x0208

FindFirstFileW

0x00BC

NtOpenFile

0x020C

FindNextFileW

0x00C0

NtWriteFile

0x0210

FindClose

0x00C4

NtReadFile

0x0214

SetErrorMode

0x00C8

NtDeleteFile

0x0218

LocalFree

0x00CC

NtQueryInformationFile

0x021C

SetPriorityClass

0x00D0

NtSetInformationFile

0x0220

MoveFileExW

0x00D4

NtQueryVolumeInformationFile

0x0224

CreateThread

0x00D8

NtCreateSection

0x0228

CreateRemoteThread

0x00DC

NtMapViewOfSection

0x022C

GetCommandLineW

0x00E0

NtUnmapViewOfSection

0x0230

AllocateAndInitializeSid

0x00E4

RtlCreateSecurityDesciptor

0x0234

CheckTokenMembership

0x00E8

RtlSetDaclSecurityDescriptor

0x0238

FreeSid

0x00EC

NtSetSecurityObject

0x023C

LookupAccountSidW

0x00F0

NtCreateKey

0x0240

GetUserNameW

0x00F4

NtOpenKey

0x0244

OpenSCManagerW

0x00F8

NtQueryKey

0x0248

OpenServiceW

0x00FC

NtDeleteKey

0x024C

QueryServiceStatus

0x0100

NtQueryValueKey

0x0250

ControlService

0x0104

NtSetValueKey

0x0254

ChangeServiceConfigW

0x0108

NtDeleteValueKey

0x0258

CloseServiceHandle

0x010C

NtRenameKey

0x025C

CryptAcquireContextW

0x0110

NtEnumerateValueKey

0x0260

CryptReleaseContext

0x0114

NtEnumerateKey

0x0264

CryptGenKey

0x0118

NtFlushKey

0x0268

CryptDestroyKey

0x011C

strcpy

0x026C

CryptExportKey

0x0120

strncpy

0x0270

CryptImportKey

0x0124

strcat

0x0274

CryptEncrypt

0x0128

strcat

0x0278

CryptDecrypt

0x012C

wcscpy

0x027C

CryptDuplicateKey

0x0130

wcsncpy

0x0280

CryptCreateHash

0x0134

wcscat

0x0284

CryptHashData

0x0138

wcsncat

0x0288

CryptGetHashParam

0x013C

strcmp

0x028C

CryptDestroyHash

0x0140

strncmp

0x0290

CryptSetKeyParam

0x0144

wcscmp

0x0294

CryptGetKeyParam

0x0148

wcsncmp

0x0298

GetKeybordLayoutList

0x014C

sprintf

0x029C

GetSystemMetrics