Lei Shi & Mei Wang, Qihoo 360
Virtualization is one of the most complicated software in the world. The VMware workstation is very popular in many fields. The windows 10 has a lot of mitigation technology to get avoid of exploitation. It's a great challenge to make a vm escape in VMware workstation under Win 10. Especially when the guest and host are both win 10 and the guest user are NO-ADMIN. This talk will present how to make a vm escape and execute arbitrary code in the host from a NO-ADMIN guest user under Win 10(both the guest and host are Win 10). They have developed three different exploitation. This talk will introduce them and show a very elegant exploitation technology of vm escape. Besides the vm escape technology, this talk will also show the exploitation technology in Win 10. It is quite attractive because there's a process continuation, saying that the guest can execute the exploitation without crashing/disturbing the host process(VMware workstation virtual machine process). The exploitation is very reliable, it reaches nearly 100% successful rate.
How to Troubleshoot Apps for the Modern Connected Worker
BlueHat v17 || Out of the Truman Show: VM Escape in VMware Gracefully
1. Out of The Truman Show:
VM escape in VMware gracefully
Lei Shi && Mei Wang
2. Lei Shi is a security researcher of 360-CERT, mainly focus on cryptography security and vulnerability
discovery. He has discovered 100+ bugs and gained 20+ CVEs(E.g: OpenSSL Death Alert) from OpenSSL,
OpenSSH, VMware. He obsesses with math and computer security, and currently is working on
Windows Search protocol security, Linux kernel security and development of vulnerability discovery
tools.
Mei Wang is a security researcher of the Gear Team of Qihoo 360 Inc., mainly focus on vulnerability
discovery and fuzz technology. In the last year, she already gained 10+ CVEs from Firefox, Safari, Solr,
Libtiff. She has made a talk in CanSecWest 2017, Syscan360. She is currently working on browser
security and fuzz tools development using math and machine learning.
About Us
3. a. Attack surface of VMware Workstation
b. VMware RPCI and backdoor
c. VMware Fuzz Framework
d. CVE-2017-4901
e. Exploit
f. Demo
g. Conclusion
Agenda
4. History vulnerabilities
Attack surface
① Attack surface of VMware Workstation
Attack surface of
VMware Workstation
6. ① Attack surface of VMware Workstation
VMCI (CVE-2017-4901)
VMCI (VMware Virtual Machine Communication Interface), a high-speed interface that
virtual machines on the same host use to communicate with each other and the host
kernel modules. It’s an optional function, if enabled, Guest could execute command
use vmware-vmx.exe process in the Host machine. When VMware Tools were
installed in the Guest, VMCI was enabled to communication.
IOCTL(CVE-2014-2384)
A device input and output control interface to allow application in the user space to
communicate with Vmkernel in the kernel space.
COM port (CVE-2017-4908 ~ 4913)
Features like printer are implemented basic on com port 。
There are many vulnerabilities discovered in COM port, especially True Type Font parser
and JPEG2000 parser in the TPView.dll.
Device Drivers (sound card, network card, graphics card, USB…)
(CVE-2017-4900)
8. ② RPCI and Backdoor
Backdoor: a communication mechanism between VMware Host and Guest.
Send message through the VMware special I/O port
Support multiple commands.
RPCI: Remote Procedure Call Interface
Based on Backdoor
Guest can send request to Host: Drag and Drop, copy paste…
Format: <command><parameters>
vmware-vmx.exe handles every RPCI commands.
17. ③ Fuzz Framework
Guest
Run a backdoor command fuzz
Host
a) Pageheap must be opened
b) Injecting a memory monitor to recode memory use and capture out-of-bounds read/write and heap use-
before-init vulnerabilities. Memory monitor delayed free object to capture double-free and UAF
vulnerabilities.
c) Out-of-bounds of stack variabilities is difficult to capture, so we used pin to handle command processing
functions specially
d) A stack scanner introduced to capture stack use-before-init vulnerabilities.
e) Vsock was used to feedback paths of some interested functions to help Guest fuzz constraint variable
range better.
18. ③ Fuzz Framework
UAF
“tools.capability.dnd_version”
When dnd_version is set 2, an arbitrary 0x100 bytes data can be filled in memory, then call command
copypaste.transport and control RIP and R8.
Continuous Out-of-bounds Write
“copypaste.transport”
Further detail will be discussed later.
20. ④ CVE-2017-4901
The Drag-and-Drop (DnD) function in VMware Workstation and Fusion has an out-of-bounds memory access
vulnerability. This may allow a Guest to execute code on the operation system that runs Workstation or
Fusion.
VMware Workstation Pro before 12.5.4
Exists in DnD version 3
We can control the overflow size.
Multi out-of-bounds write
Combing with some commands, out-of-bounds Read
Information leak and arbitrary code execute if we put the out-of-bounds
Write/Read before an appropriate object.
22. ④ CVE-2017-4901
packetSize == packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE
packetSize <= DND_MAX_TRANSPORT_PACKET_SIZE
Packet->payloadSize + packet->offset <= packet->totalSize
Packet->totalSize <= DNDMSG_MAX_ARGSZ
The totalSize of first packet specifies the size of buffer allocated on the heap.
For the first packet, the member packet->offset must be 0.
All the packets in the same message must have same seqNum.
26. ⑤ Exploit
If we want to gain code execute, we need to coverage a function
pointer on the heap or overwrite a vtable of a C++ object
Ideally, if we put the OOB-Write/Read before an appropriate
object, we can achieve both information disclosure (defeat ASLR )
and arbitrary code execution.
vul trans block
info-set/get buffer
DnD/CP object
overflow
overflow
27. ⑤ Exploit
LFH ( Windows Low Fragmented Heap)
LFH is used for allocations with size 1 to 16368(0x3FF0) bytes,
prevents fragmentation by using a bucketing scheme which causes
similarly-sized blocks to be allocated from larger pre-allocated blocks of
memory.
The LFH buckets are only activated if their corresponding allocation
size are detected to be popular.
It would be better to choose a least used suitable block.
28. ⑤ Exploit
LFH
If we want to allocate three contiguous memory blocks (vul trans block , info-set/get block , DnD/CP
object) , we can follow the steps below.
Notes, the LFH size of X0, X1, Y0, Y1, Y2 is not activated before.
29. ⑤ Exploit
LFH
An suitable and precise heap spray can form three contiguous memory buckets. Ideally, we can gain
three buckets as follows.
bucket bucket n bucket (n+1) bucket (n+2)
Memory Growth Direction
30. ⑤ Exploit
A full bucket Free obj X alloc obj Y
LFH
Free and reuse a full buckets.
Under normal circumstances, because of LFH, free a memory and allocate the same size memory again, we
may not occupy the memory freed previous, but it is an exception for a full buckets.
41. ⑤ Exploit
Layout
unity.window.contents.start
unity.window.contents.chunk
Dnd/CP object [X]fixed address jop
jop
jop
jop
…
Global variable
[X+0x08]window_id
[X+0x0C]counter
[X+0x10]window_width
[X+0x14]window_height
[X+0x28]contents_base
Low 32 bits of JOP
High 32 bits of JOP
Low 32 bits of original address
High 32 bits of original
address
Address of string calc.exe
[JOP]
42. ⑤ Exploit
1. Close the vmtoolsd process
In order to reduce interference, search VMwareDragDetWndClass and send message
WM_CLOSE.
2. Fill memory fragmentation;
Loop 0x4A80 times
Use vmx.capability.unified_loop instead of info-set for heap spray
Size 0xA0+0x10
Keep the first two bytes unique.
43. ⑤ Exploit
3. Generate three full bucket
A suitable and precise heap spray can form three continuous memory buckets.
But, in practical application. Info-set/get is unreliable and cause memory allocate multiple times and form
memory hole.
Using guest.upgrader_send_cmd_line_args, ToolsAutoInstallGetParams to replace info-set and info-get.
44. ⑤ Exploit
3. Generate three full bucket
For the first bucket, using tools.capability.guest_temp_directory to occupy position
For the Second bucket, insert a readable string BeaconStr using “guest.upgrader_send_cmd_line_args”
For the third bucket, set a DnD/CP version 3 object
tools.capability.dnd_version 3
tools.capability.copypaste_version 3
vmx.capability.dnd_version
vmx.capability.copypaste_version
Call “tools.capability.guest_temp_directory”again, remove the first placeholder and use vulnerable
transport block to reoccupy the first buckets.
45. ⑤ Exploit
4. Find BeaconStr
Call “copypaste.transport”to continuous overwrite the memory behind, 0xB0 bytes each time.
Use ToolsAutoInstallGetParams to read the BeaconStr in the second buckets until found its contents was
changed.
5. Find Dnd/CP version 3 object
Call copypaste.transport to continuous overwrite the memory behind, 0xB0 bytes each time.
Use ToolsAutoInstallGetParams to read the BeaconStr in the second buckets until found its contents was
the desired address(ASLR will not change the lowest tow bytes of address).
6. Calculate base address and verify validate
Calculate base address
46. ⑤ Exploit
7. Layout
Now, we got the base address, and then calculated the needed address.
Call unity.window.contents.start and layout the low 32 bits of JOP address and original call address to
global variable area.
Call unity.window.contents.chunk and use its counter object to push the high 32s bit of JOP address,
moreover, put the string address“C:windowssystem32calc.exe”to contents_base.
Finally Layout : If the fixed address is X:
window_id = X+8; //Low 32 bit of JOP address
counter = X+0x0C; //High 32 bit of JOP address
window_width = X+0x10; //Low 32 bit of original call address
window_height = X+0x14; //High 32 bit of original call address
contents_base = X + 0x28; // Address of string C:windowssystem32calc.exe
47. ⑤ Exploit
8. Overwrite DnD/CP version 3 object
Call copypaste.transport again and overwrite 8 bytes with
address X.
9. JOP
We can control R8 when call “copypaste.transport”
unsigned long long jop[] = { j0, d0, 0, j1, 0, j2, 0, 0, j3, 0, 0, 0,
j4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, j5, 0, 0, d1 };
Message_Send(channel, jop, sizeof(jop));
Start = JOP_base (in step 7):
mov rcx, r8
call qword ptr [r8+60h] // to j4
j4:
mov rdx, [r8+8] // d0
call qword ptr [r8] // to j0
j0:
mov rax, rdx
mov rdx, [rcx+170h] // d1
mov r8, rcx
mov rcx, rax
jmp qword ptr [r8+158h] // to j5
j5:
mov [rdx+28h], rax
jmp qword ptr [r8+18h] // to j1
j1:
pop rdi
jmp qword ptr [r8+28h] // to j2
j2:
pop rdi
jmp qword ptr [r8+40h] // to j3
j3:
xxx