less is more

Report
less is more
Exploring code/process-less techniques and other weird-machine methods to hide
code (and how to detect them).
Slide URL: http://1drv.ms/1dJX2HI
09.09.99
Major References
Win32 Buffer Overflows
(p55, 09.09.99)
dark spyrit / Barnaby Jack
One of the greatest ever
RIP
Major References
• Exploitation and state machines
• Thomas Dullien / Halvar Flake
• Sergey Bratus, TAOSSA (http://www.azimuthsecurity.com/)
• Windows Kernel-mode Payload Fundamentals & A Catalog of Windows Local
Kernel-mode Backdoor Techniques
• Skape ([email protected]) (both) & Bugcheck ([email protected]) & Skywing
([email protected])
• The page-fault weird machine: lessons in instruction-less computation
• Julian Bangert, Sergey Bratus, Rebecca Shapiro, Sean W. Smith from WOOT'13 Proceedings of
the 7th USENIX conference on Offensive Technologies
• Volatility Framework
• AAron Walters and open source contributors.
Windows hardening
• Windows XP does not memset(0) driver .text sections
• Random slack can be executed
• Updated 2k3+
• KINTERRUPT no longer has huge code templates/glue included as part of it’s structure
• KINTERRUPT.DispatchCode is now 4 bytes (and always just points to a registered handler in the
module) instead of up too 106 bytes of arbitrary code
• Updated Vista+
• Page table entries secured
• Win8 no longer has executable page table entries
• Kernel 9200+ (8/2012) Kernel Pool (heap) is no longer default executable
• This is a MAJOR win!!!!!!
• No more huge degree’s of unknown executable memory to inspect
Our target
• Rootkit can shadow/move itself during dump’s
• Issues from dumping memory from a live/physical system is problematic
and has lead to an interesting arms race;
• Using cold-boot attacks
• Purpose built dumping hardware or commodity FireWire type inputs
• Cause kernel panic to induce a dump
• Windows Kernel 9600 (Windows 8.1/2012R2)
• A snapshot from VMWare or Hyper-V
• We will ignore dump acquisition issues for now and focus on VM snapshots
X64 Kernel Virtual Address Space
http://www.codemachine.com/article_x64kvas.html
Start
End
Size
Description
Notes
FFFF0800`00000000
FFFFF67F`FFFFFFFF
238TB
Unused System Space
WIN9600 NOW USE & CAN
CONTAIN +X AREAS
FFFFF680`00000000
FFFFF6FF`FFFFFFFF
512GB
PTE Space
-X used to be executable Win7
FFFFF700`00000000
FFFFF77F`FFFFFFFF
512GB
HyperSpace
8.1 seems to have cleaned up
here, 9200 had 1 +X page
FFFFF780`00000000
FFFFF780`00000FFF
4K
Shared System Page
FFFFF780`00001000
FFFFF7FF`FFFFFFFF
512GB-4K
System Cache Working Set
FFFFF800`00000000
FFFFF87F`FFFFFFFF
512GB
Initial Loader Mappings
FFFFF880`00000000
FFFFF89F`FFFFFFFF
128GB
Sys PTEs
FFFFF8a0`00000000
FFFFF8bF`FFFFFFFF
128GB
Paged Pool Area
FFFFF900`00000000
FFFFF97F`FFFFFFFF
512GB
Session Space
FFFFF980`00000000
FFFFFa70`FFFFFFFF
1TB
Dynamic Kernel VA Space
FFFFFa80`00000000
*nt!MmNonPagedPoolStart-1
6TB Max
PFN Database
*nt!MmNonPagedPoolStart
*nt!MmNonPagedPoolEnd
512GB Max
Non-Paged Pool
FFFFFFFF`FFc00000
FFFFFFFF`FFFFFFFF
4MB
HAL and Loader Mappings
Large Page (2MB) allocations
DEFAULT NO EXECUTE
Page Table Shellcode weird-machine
• Win7 and earlier
• Can we emit intended shellcode into PTE area?
• Perform some VirtualAlloc from user space => executable memory in kernel
• Just reserving memory writes PTE
PXE at FFFFF6FB7DBEDF68 PPE at FFFFF6FB7DBEDF88 PDE at FFFFF6FB7DBF1008 PTE at FFFFF6FB7E201EA0
contains 0000000000187063 contains 0000000134C04863 contains 0000000100512863 contains 000000002DC3B863
pfn 187
---DA--KWEV pfn 134c04 ---DA--KWEV pfn 100512 ---DA--KWEV pfn 2dc3b ---DA--KWEV
• Page Table shell-code is non-trivial
• Lots of gadgets!
fffff6fb`7e201ea0
fffff6fb`7e201eb0
fffff6fb`7e201ec0
fffff6fb`7e201ed0
fffff6fb`7e201ee0
63
63
63
63
63
b8
98
78
58
38
c3
e3
63
53
c3
2d
2d
30
30
2e
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
63
63
63
63
63
a8
88
68
48
28
13
13
d3
a3
83
2f
2f
2e
2e
2e
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
c..-....c../....
c..-....c../....
cxc0....ch......
cXS0....cH......
c8......c(......
Win8 PT Shellcode attempting to run
• Seemingly cleanly return
• No double fault or bug check
• We keep entering KiPageFault after returning from KiPageFault…
Child-SP
ffffd000`2b34ecf8
ffffd000`2b34ed00
ffffd000`2b34eda0
ffffd000`2b34eee0
ffffd000`2b34f078
ffffd000`2b34f080
ffffd000`2b34f9b0
ffffd000`2b34fb60
ffffd000`2b34fbd0
0000003a`ba9bf8f8
RetAddr
fffff800`16066ee1
fffff800`1603f5ad
fffff800`1615af2f
fffff6fb`77fde37a
fffff800`01e423fe
fffff800`163ae3e5
fffff800`163aed7a
fffff800`1615c4b3
00007ff9`c1b265ea
00007ff9`bef92c83
Call Site
nt!LOCK_WORKING_SET
nt!MiSystemFault+0x911
nt!MmAccessFault+0x7ed
nt!KiPageFault+0x12f
0xfffff6fb`77fde37a
SIoctl!SioctlDeviceControl+0x27e
nt!IopXxxControlFile+0x845
nt!NtDeviceIoControlFile+0x56
nt!KiSystemServiceCopyEnd+0x13
ntdll!NtDeviceIoControlFile+0xa
Defense: Rootkit revealing
• Default non-execute pool space helps tremendously
• Detect the presence of a rootkit by comparing results from multiple
sources/abstraction layers
• Physical (page tables)
• Logical
• Driver LIST_ENTRY
• VAD
• SECTION’s, …
Tool evaluation
• Implemented in .NET
• Operates on direct physical memory dumps from VM snapshots
• Demo script that identifies KVAS physical/logical sections
• Transforms/Dumps memory / Generates hashes
• Future
• More well known blocks (local optimization)?
• There’s some weird looking fill patterns often sitting around as exec;
More page table checks, CR0.WP etc…
Example VMWare ~8GB
BlockWatch Folder: t:\BW_DEMO
Dumping data from : Clone of Clone of Current Win 8.1 - PRO (2)-66bb942e.vmss
Found probable kernel @ fffff800b508c000
Debug symbol being loaded for ntkrnlmp.pdb
Kernel build number 9600
Root PT Entries: 16, SubTable Entries: 778263
Unlinked entry count: 1544
UnLinked Section: System Space @: 0xffffd00020180000L, Size: 0x1000L
UnLinked Section: Loader Mappings @: 0xfffff800021d0000L, Size: 0x1000L
UnLinked Section: HAL and Loader Mappings @: 0xffffffffffd02000L, Size: 0x1000L
UnLinked Section: hal @: 0xfffff800b5000000L, Size: 0x200000L
UnLinked Section: Loader Mappings @: 0xfffff800b5800000L, Size: 0x200000L
…moving on; Attack! To the Unknown!
• ffffd000201a0000 appears across Hyper-V & VMWare, reboots
• Provides RoP gadgets
• Fixed writeable executable memory location
kd> !pte ffffd000`201a0000
VA ffffd000201a0000
PXE at FFFFF6FB7DBEDD00
contains 0000000000523863
pfn 523
---DA--KWEV
PPE at FFFFF6FB7DBA0000
contains 0000000000522863
pfn 522
---DA--KWEV
PDE at FFFFF6FB74000800
contains 0000000000527863
pfn 527
---DA--KWEV
PTE at FFFFF6E800100D00
contains 0000000000555963
pfn 555
-G-DA—KWEV
!pool ffffd000`201a0000
Pool page ffffd000201a0000 region is Unknown
ffffd000201a0000 is not a valid large pool allocation, checking large session pool...
Unable to read large session pool table (Session data is not present in mini and kernel-only dumps)
ffffd000201a0000 is not valid pool. Checking for freed (or corrupt) pool
• Writable/Executable at a fixed address
Can you guess what it is?
• ??
ffffd000`201a0000 21 01 a0 00 00 00 00 80 42 47 49 4b 00 00 00 80
!.......BGIK....
ffffd000`201a01d0 00 19 00 23 00 01 2e 4c 00 00 00 10 67 6c 79 66
...#...L....glyf
ffffd000`201b2fb0 00 6e 00 74 00 65 00 6e 00 74 00 2e 00 53 00 65
.n.t.e.n.t...S.e
ffffd000`201b2fc0 00 67 00 6f 00 65 00 20 00 55 00 49 00 03 00 00
.g.o.e. .U.I....
• Segoe_slboot.ttf
• Starts at offset 0x1d0
• Initial bytes some sort of heap tag ? BG*
• System boot/load time artifact
A little more (past end of font)
• Seems to have some basic heap structure pointer’s/allocation sizes
• Unfortunately it’s all default executable/writable at a fixed address across
systems/rebooting
ffffd000`201b3000 ffffd000201b3020 0000000100002000 ffffd000201b3020 8000000000300121
…
ffffd000`201b3020 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
ffffd000`201b3070 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is program canno
…
ffffd000`201b46b2 49 00 6e 00 74 00 65 00 72 00 6e 00 61 00 6c 00 4e 00 61 00
ffffd000`201b46c6 6d 00 65 00 00 00 62 00 6f 00 6f 00 74 00 72 00 65 00 73 00
I.n.t.e.r.n.a.l.N.a.
m.e...b.o.o.t.r.e.s.
…
• This leaves a lot of room for RoP gadgets (MZ is only .rsrc, why +x?)
BIOS Ranges
• Platform specific (vmware in this case)
• 2012R2 0xffffd00020500000, 8.1 0xffffd00020600000
• Fixed address across reboots (size is 241,664 - 0x3B000)
• Physical system dumps
ffffd000`206c5a50
ffffd000`206c5a60
ffffd000`206c5a70
ffffd000`206c5a80
ffffd000`206c5a90
c3
75
72
2c
72
32
61
65
20
74
2e
6c
2c
49
20
30
20
20
6e
32
00
6d
49
63
2e
56
61
6e
2e
30
4d
63
63
20
00
77
68
00
56
90
61
69
56
42
c8
72
6e
20
45
02
65
65
4d
20
00
20
00
20
73
00
76
56
77
75
c4
69
4d
61
70
5e
72
77
72
70
04
74
61
65
6f
33
.2.0.VMware virt
ual machine.VMwa
re, Inc.V M ware
, Inc. VBE suppo
rt 2.0.......^.3
3: kd> !pte ffffd000`206c5a50
PXE at FFFFF6FB7DBEDD00
contains 0000000000B22863
pfn b22
---DA--KWEV
VA ffffd000206c5a50
PPE at FFFFF6FB7DBA0000
PDE at FFFFF6FB74000818
contains 0000000000B21863 contains 0000000000852863
pfn b21
---DA--KWEV pfn 852
---DA--KWEV
PTE at FFFFF6E800103628
contains 00000000000C5963
pfn c5
-G-DA--KWEV
Other/More dynamic/Misc Areas
• Slack
• Audit MDL structures
• Session Space
• ACPI FACS -- exec
• Firmware ACPI Control Structure
• Verify ACPI with wite list
0: kd> !pool ffffe00000420000
Pool page ffffe00000420000 region is Nonpaged pool
*ffffe00000420000 size:
90 previous size:
0 (Allocated) *VM3D
Pooltag VM3D : Volume Manager, Binary : volmgr.sys
0: kd> !pool ffffe000`00418000
Pool page ffffe00000418000 region is Nonpaged pool
*ffffe00000418000 size:
90 previous size:
0 (Allocated) *VM3D
Pooltag VM3D : Volume Manager, Binary : volmgr.sys
• Shim Engine (i.e. handling for drvmain.sdb)
• Bootloader artifacts
• Volume manager heap
Related topics
• White list extracted bootmgr.exe
• Well-known pages
• NULL, all set, GUARD
• Interesting/weird fill patterns
• 2007, ######
• Iiiiii (0x69;)
• Make sure their not gadget’able…
Other Gadget Areas
• There are other +X areas, in the region, but have small variability in
their allocation
• Windows Boot manager, network boot support code, more font areas
Defense: RoP Detection
• Spurious Saved Return Addresses
• Sometimes RoP Gadget is just random data present in an executable
section!!!
• All existing RoP Databases or techniques target arbitrary saved return
addresses
• https://www.corelan.be/index.php/security/corelanropdb/#advapi32dll_8211_5126005755
• 0x77e25c1f, # POP EAX # RETN
• Saved Return should be
• Simple/Effective/Very reliable reducing gadget surface area
Spurious Saved Return Addresses Validation
• Conceptually similar to heap back-checking logical links except we
walk the stack
• Think Heap/Pool verification
• Verify op-code preceding saved return address
• Adding into BlockWatch
• Our operation is static so performance is no big deal and we like to be current! 
• Some performance impact if implemented at run time
• May not reduce the gadget surface area sufficiently
Attack: RoP Compiler
• Gadget surface area is reduced by SSRAV
•
•
•
Use a gadget compiler from verifiable gadgets only
Work done from Codeless Pagefaulting;
… a “A one Instruction Computer” with
A move-branch-if-zero-or-decrement instruction,
short movdbz.
...
It has been proven that … is Turing-complete…
Defense: Finally
• RoP compiler’s are neat, but with adequate surface area reduction of
dependable RoP gadgets
• Remove EXECUTE from unneeded areas
• Decommit/wipe unused
• RoP chain will be really huge and will have fairly obvious looking
characteristics
• Even on AMD64 max stack is 4GB; “the maximum size of a segment (ss).”
• Detecting codeless-pagefaulting
• Specifically; Scan/Verify GDT and TSS
• Generally; Performance drain, counters, clock skew, context switches, accounting, …
So What?
• Page table verifier identifies hidden areas
• White list as much as possible
• High 99%
• Defend RoP attacks with SSRA checking
Comprehensive verification
• Forensics
• Reduction / Analysis aid
• APT Detection
• Diffing
• White list
Dependencies?
• Require NX
• SMEP Reccomended
What about script hosts?
• Instrument / Profile scripts to generate white lists
• Doable for .NET
• More difficult for PHP and company?
Demo

similar documents