VMware's back door (original text is published by Coolq, the article is reproduced from his blog)
Back door profile
The VMware latte is an interface for VMware and VMware Tools communication. For example, the VMware-Checkvm program uses this back door to detect whether you run in VMware.
This rear door is opened in the IO port 0x5658. Using this back door, you must:
l EAX = 0x564d5868 ("VMXH")
l EBX is parameter, generally not.
l ECX low 16 bit is function number. It is actually an index of a function array. VMware calls the corresponding function to process the rear door request. This group of functions have a total of
l 36 elements, but some are not defined. ECX high 16-bit is functional parameters.
l Edx = 0x5658 ("vx"), for the IO port number.
The back door is called by the read port (in) command.
Back door detailed description
0 undefined
1 getMHz gets the CPU rate
2 APM function
3 getDiskgeo
4 getptrlocation
5 setptrlocation
6 Get the length of the host clipboard data length
7 Reading host clipboard data
8 Set the versatile clipboard data length
9 write data to the host clipboard
10 get the VMware version
11 take equipment information
12 Connection or disconnection equipment
13 Take GUI configuration information
14 Setting the GUI configuration information
15 Positioning host screen resolution
16 undefined
17 undefined
18 OsNOTFOUND, VMware Tips Insert Boot Tray
19 getBiosuID
20 Take the virtual machine memory size
21 undefined
22 OS2 system for a function
23 GetTime, take the host time
24 stopcatchup
25 undefined
26 undefined
27 undefined
28 INITSCIIOPROM
29 undefined
30 Message, channel function
31 RSVD0
32 RSVD1
33 rsvd2
34 ACPID function
35 undefined
application
Vmcall.s
VmCall.s provides VMCall (uint32_t out [4], int cmd, uint32_t param) function for VM.C, implementing call back door function
.Text
.align 2
.globl vmcall
.Type vmcall, @ function
VmCall:
Pushl% EBP
MOVL% ESP,% EBP
MOVL 0x8 (% EBP),% EAX
PUSH% EDI
PUSH% EBX
PUSH% ECX
PUSH% EDX
MOV% EAX,% EDI
MOV $ 0x564d5868,% EDX
MOV% EDX,% EAX
MOV 0xc (% EBP),% EDX
MOV 0x10 (% EBP),% EBX
MOV% EDX,% ECX
MOV $ 0x5658,% EDX
In (% dx),% EAX
MOV% EAX, 0x0 (% EDI)
MOV% EBX, 0x4 (% EDI)
MOV% ECX, 0x8 (% EDI)
POP% EDX
Strange, it is truncated.
POP% ECX
POP% EBX
POP% EDI
Leave
RET
VM.C
Vm.c is the main program. Command line parameter is the back door function number
#include
#include
#include
Extern uint32_t vmcall (uint32_t buf [4], int func, uint32_t arg); void segfault (int SEG)
{
FPRINTF (stderr, "vmcall failed / n");
_exit (1);
}
INT main (int Argc, char ** argv)
{
INT I;
UINT32_T BUF [4];
INT CMD;
IF (argc == 1)
{
PUTS ("arg .......");
Return 1;
}
CMD = ATOI (Argv [1]);
Signal (SIGSEGV, Segfault);
MEMSET (BUF, 0, SIZEOF (BUF));
Vmcall (buf, cmd, 0);
Printf ("% x:% x% x-% x% x / n", cmd, buf [0], buf [1], buf [2], buf [3]);
Return 0;
}
Example
Compilation: gcc -g -o vm vm.c vmcall.s
1. No CPU rate
$ ./vm 1
1: 69F-0-1-0
69F decimal 1695, CPU rate is 1695MHz
2. No. 10 calls the VMware version and is used to determine if it is running in VMware.
$ ./vm 10
A: 6-564D5868-4-0
6 is the VMware version number. Note that this is different from the About. 4 indicates that VMware Workstation, and other might take advantage of:
2 ESX Server
1 Express
3 GSX Server
3. No. 15 Calling the home screen resolution
$ ./vm 15
F: 4000300-0-F-0
The resolution is 0x400 * 0x300, that is, 1024 * 768
4. The implementation of the VMware in the 28th is a problem, causing my VMware Workstation 4.0.0.4460 immediately crashed. The cause of VMware attempts to read the memory address of 0x14, but because there is no user input, it cannot be utilized.
Appendix: Analysis Tools and Environment
VMware 4.0.0.4460 and VMware 4.0.5.6030. Host Windows 2003 Standard.
GuestOS Redhat 8 (kernel 2.6.2, GCC 3.2).
IDapro is used for static analysis, OLLYDBG is used to dynamically debug.
Static Analysis The VMware-Checkvm program discovers this back door.
Static analysis dynamic debug gets each functional information.
How To Detect VMM Using (Almost) One CPU Instruction
Added by: a ^ c ^ e
Date: 18.11.04
Time: 08:52:13
Category: Article
Source:
http://www.securiteam.com/securityreviews/6z00h20bqs.html
Summary
The attached short (4 lines of code, that generate almost a single CPU instruction) exploit code can be used to detect whether the code is executed under a VMM or under a real environment. In addition to the exploit code, a detailed explanation of how THIS WAS Found and why it works area also provided.details
Swallowing the red pill is more or less equivalent to the following code (Returns Non Zero When in Matrix):
Int swallow_redpill () {
Unsigned char m [2 4], rpill [] = "/ x0f / x01 / x0d / x00 / x00 / x00 / x00 / xc3";
* ((unsigned *) & rpill [3]) = (unsigned) m;
((Void (*) ()) & rpill) ();
RETURN (M [5]> 0xD0)? 1: 0;
}
The heart of this code is actually the SIDT instruction (encoded as 0F010D [addr]), which stores the contents of the interrupt descriptor table register (IDTR) in the destination operand, which is actually a memory location. What is special and interesting about SIDT ISTRUCTION IS THAT, IT CAN BE EXECUTED IN NON Privileged Mode (Ring3) But it Returns the Contents of The Sensitive Register, Used INTERNALY BY OPERATING SYSTEM.
Because there is only one IDTR register, but there are at least two OS running concurrently (ie the host and the guest OS), VMM needs to relocate the guest's IDTR in a safe place, so that it will not conflict with a host's one. Unfortunately, VMM can not know if (and when) the process running in guest OS executes SIDT instruction, since it is not privileged (and it does not generate exception). Thus the process gets the relocated address of IDT table. It was observed that on VMWare, the relocated address of IDT is at address 0xffXXXXXX, whereas on Virtual PC it is 0xe8XXXXXX. This was tested on VMWare Workstation 4 and Virtual PC 2004, both running on Windows XP host OS.Joanna Rutkowska came across this strange behavior of SIDT instruction a few years ago, when Joanna Rutkowska was testing Suckit rootkit on VMWare. Joanna Rutkowska noticed that it failed to load on VMWare whereas it seemed to work fine on the same distribution ran outside VM. After spending many hours Joanna Rutkowska Figured Out That The Problematic Instruction Was Actually Sidt, Which Was Used by suckit to get the address of the IDt table, and to hook its 0x80 entry through / dev / kmem device.
However, Joanna Rutkowska was not the first one who discovered this trick. Shortly after her adventure with Suckit Joanna Rutkowska found a very good USENIX paper about problems when implementing Virtual Machines on Intel processors, discussing of course SIDT problem, as well as many others.
So Now, Here Is The Simple Code, Written In C, Which SHOULD Compile on Any All Intel based Os. Just In Case You Don't Have The C Compiler for Windows, There IS Also a Binary Version Attached.
NOTE:. This program will fail on systems with PAX / X ^ W / grsecurity, protection (as it was pointed out by Brad Spengler) since the rpill variable is not marked as executable To make it run in such systems, mprotect () should be used to mark rpill with PROT_EXEC attribute. Another solution would be to just use asm () keyword instead of shellcode-like buffer. However, this program should be rather considered as a skeleton to build into your own shellcode, rather then standalone production class tool. In addition, Joanna's goal was to make it as simple and portable as possible. That's why Joanna did not use asm () nor mprotect () since they are system or compiler dependent.Joanna is also aware of another implementation of this technique , AS Well As Some Other Tricks to Fingerprint VMware, Which Can Be Found AT
http://www.trapkit.de/.