shellcode

1. はじめに

 LabyREnth CTF Windows Track のLv6の問題 (Shellcode) にて. 覚書として.

 

 

2. shllcode

 Ambrosius.exeを対象に行う.

f:id:kmdnet:20160901115854p:plain

> cdb Ambrosius.exe

 

0:000> dt _TEB
ntdll!_TEB
 +0x000 NtTib : _NT_TIB
 +0x01c EnvironmentPointer : Ptr32 Void
 +0x020 ClientId : _CLIENT_ID
 +0x028 ActiveRpcHandle : Ptr32 Void
 +0x02c ThreadLocalStoragePointer : Ptr32 Void
 +0x030 ProcessEnvironmentBlock : Ptr32 _PEB  (省略)

 

0:000> dt _PEB -r2
ntdll!_PEB
 +0x000 InheritedAddressSpace : UChar
 +0x001 ReadImageFileExecOptions : UChar
 +0x002 BeingDebugged : UChar
 +0x003 BitField : UChar
 +0x003 ImageUsesLargePages : Pos 0, 1 Bit
 +0x003 IsProtectedProcess : Pos 1, 1 Bit
 +0x003 IsImageDynamicallyRelocated : Pos 2, 1 Bit
 +0x003 SkipPatchingUser32Forwarders : Pos 3, 1 Bit
 +0x003 IsPackagedProcess : Pos 4, 1 Bit
 +0x003 IsAppContainer : Pos 5, 1 Bit
 +0x003 IsProtectedProcessLight : Pos 6, 1 Bit
 +0x003 SpareBits : Pos 7, 1 Bit
 +0x004 Mutant : Ptr32 Void
 +0x008 ImageBaseAddress : Ptr32 Void
 +0x00c Ldr : Ptr32 _PEB_LDR_DATA
    +0x000 Length : Uint4B
    +0x004 Initialized : UChar
    +0x008 SsHandle : Ptr32 Void
    +0x00c InLoadOrderModuleList : _LIST_ENTRY
       +0x000 Flink : Ptr32 _LIST_ENTRY
       +0x004 Blink : Ptr32 _LIST_ENTRY
    +0x014 InMemoryOrderModuleList : _LIST_ENTRY
       +0x000 Flink : Ptr32 _LIST_ENTRY
       +0x004 Blink : Ptr32 _LIST_ENTRY 
    +0x01c InInitializationOrderModuleList : _LIST_ENTRY
       +0x000 Flink : Ptr32 _LIST_ENTRY
       +0x004 Blink : Ptr32 _LIST_ENTRY
    +0x024 EntryInProgress : Ptr32 Void
    +0x028 ShutdownInProgress : UChar
    +0x02c ShutdownThreadId : Ptr32 Void  (省略)

 

0:000> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
 +0x000 InLoadOrderLinks : _LIST_ENTRY
 +0x008 InMemoryOrderLinks : _LIST_ENTRY
 +0x010 InInitializationOrderLinks : _LIST_ENTRY
 +0x018 DllBase : Ptr32 Void
 +0x01c EntryPoint : Ptr32 Void
 +0x020 SizeOfImage : Uint4B  (省略)

 

0:000> r @$t0 = poi(poi(fs:30)+0C)+14
0:000> dt _LDR_DATA_TABLE_ENTRY poi(@$t0)-8
ntdll!_LDR_DATA_TABLE_ENTRY
 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4e2b60 - 0x776fab4c ]
 +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x4e2b68 - 0x776fab54 ]
 +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
 +0x018 DllBase : 0x00400000 Void
 +0x01c EntryPoint : 0x004010e7 Void
 +0x020 SizeOfImage : 0x2000
 +0x024 FullDllName : _UNICODE_STRING "C:\Users\akabane\Desktop\Ambrosius.exe"
 +0x02c BaseDllName : _UNICODE_STRING "Ambrosius.exe"  (省略)

 

0:000> dt _LDR_DATA_TABLE_ENTRY poi(poi(@$t0))-8
ntdll!_LDR_DATA_TABLE_ENTRY
 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4e3028 - 0x4e2c60 ]
 +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x4e3030 - 0x4e2c68 ]
 +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x4e3368 - 0x776fab5c ]
 +0x018 DllBase : 0x775f0000 Void
 +0x01c EntryPoint : (null)
 +0x020 SizeOfImage : 0x17b000
 +0x024 FullDllName : _UNICODE_STRING "C:\WINDOWS\SYSTEM32\ntdll.dll"
 +0x02c BaseDllName : _UNICODE_STRING "ntdll.dll"  (省略)

 

0:000> dt _LDR_DATA_TABLE_ENTRY poi(poi(poi(@$t0)))-8
ntdll!_LDR_DATA_TABLE_ENTRY
 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4e3358 - 0x4e2b60 ]
 +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x4e3360 - 0x4e2b68 ]
 +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x4e3dc8 - 0x4e3368 ]
 +0x018 DllBase : 0x74860000 Void
 +0x01c EntryPoint : 0x74873980 Void
 +0x020 SizeOfImage : 0xe0000
 +0x024 FullDllName : _UNICODE_STRING "C:\WINDOWS\SYSTEM32\KERNEL32.DLL"
 +0x02c BaseDllName : _UNICODE_STRING "KERNEL32.DLL"  (省略)

 これよりDllBaseは0x74860000である.

 

0:000> lm
start end module name
00400000 00402000 image00400000 (deferred)
71c30000 71cc2000 apphelp (deferred)
74860000 74940000 KERNEL32 (deferred)  (省略)

 

 lmコマンド(List Loaded Modules)で確認すると上記したDllBaseとkernel32.dllのアドレスが一致している.

 

 

 つまり最初のコードを以下のように解釈される(説明の都合上番号を振る).

(1) mov eax, large fs:30h
(2) mov eax, [eax+0Ch]
(3) mov eax, [eax+14h]
(4) mov eax, [eax]
(5) mov eax, [eax]
(6) mov eax, [eax+10h] 
(7) retn

 

(1) fs:30h -> PEB

(2) PEB -> Ldr

(3) Ldr -> InMemoryOrderModuleList.Flink

(4),(5)InMemoryOrderModuleList.Flink

(6) _LDR_DATA_TABLE_ENTRY -> DllBase

 

 Cで記述すると以下のようになる.

 

 

 なお最後にDllBaseではなくReserved2[0]を呼び出しているのは, FlinkによりLDR_DATA_TABLE_ENTRYが+0x8だけずれているからである.

 

 

 

f:id:kmdnet:20160912145121p:plain

 これはAPIのハッシュを計算している関数である. 引数としてIMAGE_EXPORT_DIRECTORYのAddressOfNamesをとる.

 

typedef struct _IMAGE_EXPORT_DIRECTORY {
 DWORD Characteristics;
 DWORD TimeDateStamp;
 WORD MajorVersion;
 WORD MinorVersion;
 DWORD Name;
 DWORD Base;
 DWORD NumberOfFunctions;
 DWORD NumberOfNames;
 DWORD AddressOfFunctions; // RVA from base of image
 DWORD AddressOfNames; // RVA from base of image
 DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

 

 APIハッシュの計算するスクリプトを以下に記す. IDAに読み込ませるために,列挙型を定義している.

 

  IDAにAPIハッシュを読み込ませる

 ・> python api_hash.py C:\Windows\System32\kernel32.dll > api_hash.h

 ・FIle -> Load file -> Parse C header file ... -> api_hash.h

 ・[Enum] -> Define a new enumeration type (Ins) -> Add standard enum by enum name -> ヘッダファイルを選択

 ・APIハッシュ値を選択 -> Symbolic constant -> hash_kernel32_***

 

f:id:kmdnet:20160915195555p:plain

 

 

3. 補足

 .cls : clear all of the text from the Debugger Command window

 

 

4. 参考

Harmony Security: Retrieving Kernel32's Base Address

PEB_LDR_DATA structure (Windows)

Windowsで電卓を起動するシェルコードを書いてみる - ももいろテクノロジー

リバースエンジニアリング入門(1):シェルコードから始めるマルウェア解析 (1/2) - @IT

 

kmdnet