Slide 1

Slide 1 text

Playing Malware Injection with Exploit thoughts [email protected] !1

Slide 2

Slide 2 text

• Master degree at CSIE, NTUST • Security Researcher - chrO.ot, TDOHacker • Speaker - BlackHat, DEFCON, VXCON, HITCON >_cat ./Bio !2

Slide 3

Slide 3 text

• Introduction • Challenge When we meet Anti-Virus • Interesting Case - PowerLoader since 2013 • New Vulnerability - 3 idea inspired by PowerLoader • CFG Patch by MicroSoft • Summary >_ls ./agenda !3

Slide 4

Slide 4 text

[email protected] Quick Review: What's Malware Injection? !4

Slide 5

Slide 5 text

>_man inject (`_´)ゞ Used for bypassing whitelist checking, byassing anti-virus, privilege escalation, etc. e.g. • DLL Side-Loading + Digital Signature = Bypassing anti-virus • Remote Inject + whitelisted process = Bypassing whitelist • Inject explorer + DLL Side-Loading + Self-elevate Service
 = Bypassing Windows UAC (User Account Control) *Vista ~ Win8* !5

Slide 6

Slide 6 text

>_man inject There're serval well-known techniques • Shellcode Inject or DLL Inject - OpenProcess, VirtualAllocExRWX, WriteProcessMemory, CreateRemoteThread
 • Process Hollowing (aka RunPE) - OpenProcess, CreateProcessASuspended, Mapping PE FileVirtualAllocEx + WriteProcessMemory, GetThreadContext, and ResumeThread to Execute exe file from memory
 • Thread Hijack or AtomBombing - QueueUserAPC, Inline Hook, or IAT Hijack
 • Memory Exploit (PowerLoaderEX) - SetWindowLong, SendNotifyMessage !6

Slide 7

Slide 7 text

(ꐦ`•ω•´)!!! Here are the 4 primary challenges that you'll encounter during injection. >_man inject !7

Slide 8

Slide 8 text

There are 4 primary challenges in injection: 1. What's target - choose a target to inject, and it should be meaningful. e.g. explorer, svchost
 2. Where to place - find memory for us to place RWX memory or ROPChain payload. e.g. VirtualAllocEx
 3. How to inject payload - any way for us to write payload into remote process memory
 4. How to run it - create a new thread to execute or hijack current thread of that process? >_man inject !8

Slide 9

Slide 9 text

[email protected] Interesting Case: Powerloader since 2013 !9

Slide 10

Slide 10 text

Powerloader, aka Extra Window Vulnerability !10

Slide 11

Slide 11 text

Explorer Process Memory Shell_TrayWnd +0 - 0xcafe (vtable) +4 - window hwnd ... vtable @ 0xcafe +0 - Interlocked (inc) +4 - message callback +8 - Interlocked (inc) Operating System 1) Send Window Message 2) Send Window Message 3) Invoke s_wndProc function 4) Invoke several function from vtable >_how it works !11

Slide 12

Slide 12 text

Explorer Process Memory Shell_TrayWnd +0 - 0xcafe (vtable) +4 - window hwnd ... vtable @ 0xcafe +0 - Interlocked (inc) +4 - message callback +8 - Interlocked (inc) >_issue? GetWindowLong() !12

Slide 13

Slide 13 text

Explorer Process Memory Shell_TrayWnd +0 - 0xbeef 0xcafe +4 - window hwnd ... >_issue? GetWindowLong() vtable @ 0xcafe +0 - Interlocked (inc) +4 - message callback +8 - Interlocked (inc) fake vtable @ 0xbeef +0 - shellcode addr +4 - shellcode ... SetWindowLong() !13

Slide 14

Slide 14 text

Explorer Process Memory malicious Shell_TrayWnd >_issue? GetWindowLong() payload SetWindowLong() +0 - fake vtable ($+4) fake vtable +4 - shellcode addr ($+8) +8 - shellcode pwn! !14

Slide 15

Slide 15 text

>_abuse vtable !15

Slide 16

Slide 16 text

Slide 17

Slide 17 text

[email protected] 3 more vulnerability: From Exploit to Inject !17

Slide 18

Slide 18 text

[email protected] #1 Ole32 DropEnter Event !18

Slide 19

Slide 19 text

>_cat ./ole32_init !19

Slide 20

Slide 20 text

>_cat ./reg_dropevent !20

Slide 21

Slide 21 text

>_man LPDROPTARGET IDropTarget actually is a virtual method table :) !21

Slide 22

Slide 22 text

>_issue? vtable addr is determined by GetProp() so... it's really easy for us to hijack vtable just by SetProp() This callback function is used to deal with dropping file to Start Button of Explorer.exe !22

Slide 23

Slide 23 text

explorer Process Memory DropTarget @ 0xc0fee Prop Name Value OleDropTargetInterface 0xbeef payload @ 0xbeef +0 - 0xbeef (this) +4 - don't care ... +8 - don't care +0C- shellcode addr it's easy for us to change the return value of GetPropW("OleDropTargetInterface") from 0xc0fee to 0xbeef (malicious payload). >_issue !23

Slide 24

Slide 24 text

explorer Process Memory Operating System 1) Send Window Message (Drag & Drop) 2) GetPropW("OleDropTargetInterface") 3) Invoke drop file function from vtable, invoke shellcode addr = *(beef+0c) DropTarget @ 0xc0fee payload @ 0xbeef +0 - 0xbeef (this) +4 - don't care ... +8 - don't care +0C- shellcode addr Prop Name Value OleDropTargetInterface 0xbeef >_issue !24

Slide 25

Slide 25 text

>_abuse vtable !25

Slide 26

Slide 26 text

Slide 27

Slide 27 text

[email protected] #2 Comctl32 SubClass Event !27

Slide 28

Slide 28 text

>_cat FastGetSubclsHdr !28

Slide 29

Slide 29 text

>_cat MstSubclsProc !29

Slide 30

Slide 30 text

>_cat EnterSubclsFram !30

Slide 31

Slide 31 text

>_cat EntrSubclsCallbk !31

Slide 32

Slide 32 text

>_cat CallNxtSubclsProc !32

Slide 33

Slide 33 text

>_abuse vtable !33

Slide 34

Slide 34 text

>_abuse vtable !34

Slide 35

Slide 35 text

Slide 36

Slide 36 text

[email protected] #3 Thread Hijacking (win10+) !36

Slide 37

Slide 37 text

3) create first thread of this process, point register eax to AddressOfEntry, point ebx+8 (TIB base + 8) to image base, and point eip to ntdll!LdrInitializeThunk Process >_Process? Kernel (ring0) Application (ring3) 1) create process via CreateProcess() 2) mapping file into memory iexplorer.exe .data section .text section AddressOfEntry ntdll.dll kernel32.dll ... !37

Slide 38

Slide 38 text

>_Process? Process iexplorer.exe ntdll.dll kernel32.dll ... Call Stack -------------- _LdrpSnapModule _LdrpMapAndSnapDependency _LdrpMapDllWithSectionHandle _LdrpLoadKnownDll _LdrpFindOrPrepareLoadingModule _LdrpLoadDllInternal _LdrpLoadDll _LdrLoadDll _LdrpInitializeProcess __LdrpInitialize _LdrInitializeThunk fix import address table, fix export directory, apply relocation, etc .text section ntdll!LdrInitializeThunk !38

Slide 39

Slide 39 text

>_Process? ntdll!LdrInitializeThunk [email protected] Process iexplorer.exe .text section ntdll.dll kernel32.dll ... ntdll!RtlUserThreadStart RtlUserThreadStart is entry-point of every thread. We can hijack thread via write shellcode address into global variable ‘LdrDelegatedRtlUserThreadStart'. !39 *Pseudocode *Pseudocode

Slide 40

Slide 40 text

3) point 'LdrDelegatedRtlUserThreadStart' to shellcode address Process >_Abuse Malware 1) get privilege of target process via OpenProcess() 2) mapping shellcode into target process chrome.exe .data section .text section shellcode ... ntdll.dll LdrDelegatedRtlUserThreadStart 4) every new thread of target process can be hijack to invoke shellcode !40

Slide 41

Slide 41 text

Slide 42

Slide 42 text

However, if you try to use this PoC, you'll find it doesn't work at all. plz... don't look at me like this :( !42

Slide 43

Slide 43 text

[email protected] #3 Thread Hijacking (win10+) Sorry bro. We've patched CFG (Control-Flow-Guard) protection on ntdll.dll in August ;) So... What Happened? !43

Slide 44

Slide 44 text

The interesting thing is, actually I don't know where's the patch MicroSoft updated (ntdll.dll file, patched version) You guys will say: It's located at C:\windows\system32. yah, it should be right there, but it's not. Moreover, if you try any tools or windows system API to fetch the ntdll.dll path loaded in active process. You'll still see the path point to C:\windows\system32. >_Ntdll.dll's Patch? !44

Slide 45

Slide 45 text

Thus, I decide to use x64dbg to launch a debug mode process (and it should be protected by CFG), and dump the ntdll.dll module from process memory via Scylla. A blessing in disguise, ntdll.dll is designed to be loaded first, so there's no IAT (Import Address Table) we need to repair for the dump file. >_Dump Patch yah, we got the original ntdll.dll module & the patch now. !45

Slide 46

Slide 46 text

>_Recall ntdll!LdrInitializeThunk [email protected] Process iexplorer.exe .text section ntdll.dll kernel32.dll ... ntdll!RtlUserThreadStart RtlUserThreadStart is entry-point of every thread. We can hijack thread via write shellcode address into global variable ‘LdrDelegatedRtlUserThreadStart'. !46 *Pseudocode *Pseudocode

Slide 47

Slide 47 text

Orginal Patch !47 *Pseudocode *Pseudocode *Pseudocode

Slide 48

Slide 48 text

>_guard_dispatch_icall_fptr !48 *Pseudocode

Slide 49

Slide 49 text

>_how CFG works? • CFG protects all indirect call/jump during compiling, and bitmap memory is allocated dynamically. • ntdll!guard_dispatch_icall_fptr verifies every dest addresses by bitmap. With dest address >> 9 as index, fetch uint64_t as hash from bitmap, and check it. • CFG will directly jump into
 the dest address, if the hash
 matches. Process anyApp.exe ntdll.dll kernel32.dll .text section CFG Bitmap bitmap[0] 08 00 00 00 48 00 08 00 bitmap[1] 00 00 00 00 00 00 00 00 bitmap[2] 28 00 00 01 00 00 00 00 ... !49

Slide 50

Slide 50 text

>_By & far (1/3) • A cool idea is modifying the CFG bitmap base address. However, the bitmap base buffer sadly is read-only. 
 
 It's necessary for you to use VirtualProtectEx(), but this API is too conspicuous for anti-virus to catch-up. !50

Slide 51

Slide 51 text

>_By & far (2/3) • CFG bitmap memory is allocated dynamically, and this address is randomized. • If we don't change the CFG bitmap base address, we must leak the CFG bitmap base address by ReadProcessMemory. • Fortunately, the CFG bitmap is predictable. There're 2 processes created simultaneously, and they have the same CFG bitmap memory address. !51

Slide 52

Slide 52 text

>_By & far (3/3) • Correct hash should be stored on following formula:
 p = cfgBitmap[dest >> 9] • if _bittest(p, dest >> 3) != null, $rip is hijacked • anothor cool idea is allocating a fake CFG field where stores a correct hash to cheat the CFG function, If we could predict the remote CFG bitmap address. • VirtualAllocEx doesn't allow you get a higher address than current CFG bitmap address, so ... !52

Slide 53

Slide 53 text

Well done, CFG! !53

Slide 54

Slide 54 text

Thanks for listening [email protected] Slide Github @aaaddress1 Facebook !54