Vmware 的后门 (原文由coolq发表,文章转载自他的博客)

原创 2004年12月29日 10:51:00
Vmware 的后门 (原文由coolq发表,文章转载自他的博客)


       Vmware 后门是 vmware 和 vmware tools 通信的一个接口。例如,vmware-checkvm 程序就是利用这个后门检测自己是否运行在 vmware 里。

       这个后门开在 IO 端口 0x5658。利用这个后门时,必需:

l        EAX = 0x564D5868 ( “VMXh” )
l        EBX 为参数,一般不用。
l        ECX 低 16 位为功能号。其实是一个函数数组的索引。Vmware 调用对应的函数处理后门请求。 这个函数数组共有
l       36 个元素,但某些没有定义。ECX 的高 16 位为功能参数。
l        EDX = 0x5658 ( “VX” ),为 IO 端口号。

       通过读端口 (in) 命令调用后门。


0    未定义
1    getMhz 得到 CPU 速率
2    APM 函数族
3    getDiskGeo
4    getPtrLocation
5    setPtrLocation
6    得到宿主机剪贴板数据长度
7    读宿主机剪贴板数据
8    设置宿主机剪贴板数据长度
9    向宿主机剪贴板写数据
10    得到 vmware 版本
11    取设备信息
12    连接或断开设备
13    取 GUI 配置信息
14    设置 GUI 配置信息
15    取宿主机屏幕分辨率
16    未定义
17    未定义
18    osNotFound, vmware 提示插入引导盘
19    GetBiosUUID
20    取虚拟机内存大小
21    未定义
22    OS2 系统用到的一个函数
23    getTime,取宿主机时间
24    stopCatchup
25    未定义
26    未定义
27    未定义
28    initScsiIoprom
29    未定义
30    Message,通道函数族
31    rsvd0
32    rsvd1
33    rsvd2
34    ACPID 函数
35    未定义


       vmcall.s 为 vm.c 提供 vmcall(uint32_t out[4],int cmd,uint32_t param) 函数,实现调用后门功能

        .align 2
.globl vmcall
        .type   vmcall,@function
        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


        pop %ecx
        pop %ebx
        pop %edi

       vm.c 为主程序。命令行参数为后门功能号

#include <stdio.h>
#include <signal.h>
#include <stdint.h>

extern uint32_t vmcall(uint32_t buf[4],int func,uint32_t arg);

void segfault(int seg)
        fprintf(stderr,"vmcall failed/n");

int main(int argc,char **argv)
        int i;
        uint32_t buf[4];
        int cmd;

        if (argc == 1)
                return 1;

        cmd = atoi(argv[1]);

        printf("%x: %x-%x-%x-%x/n",cmd,buf[0],buf[1],buf[2],buf[3]);

         return 0;

       编译: gcc –g –o vm vm.c vmcall.s
1.        1 号调用取 CPU 速率

$ ./vm 1
1: 69f-0-1-0
69f 十进制 1695,CPU 速率为 1695Mhz

2.        10 号调用取 vmware 版本,也用来判断是否运行在 vmware 里。
$ ./vm 10
a: 6-564d5868-4-0
6 是 vmware 版本号。注意这和 about 里看到的不同。4 表示是 vmware workstation,其它可能取值有:
2     ESX Server
1     Express
3     GSX Server

3.        15 号调用取宿主机屏幕分辨率
$ ./vm 15
f: 4000300-0-f-0
分辨率是 0x400 * 0x300,即 1024 * 768

4.  28 号调用 vmware 的实现有问题,导致我的 vmware workstation 立刻崩溃。原因Vmware 试图去读 0x14 的内存地址,不过因为没有用户输入,无法利用。

      Vmware 和 vmware。宿主机 Windows 2003 Standard。
      GuestOS RedHat 8 (Kernel 2.6.2, gcc 3.2)。

       IDApro 用于静态分析,OllyDBG 用于动态调试。

       静态分析 vmware-checkvm 程序发现这个后门。
       静态分析 + 动态调试得到各功能信息。

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

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 are also provided.

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;
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 instruction is that, it can be executed in non privileged mode (ring3) but it returns the contents of the sensitive register, used internally by operating system.

Because there is only one IDTR register, but there are at least two OS running concurrently (i.e. 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 cannot know if (and when) the process running in guest OS executes SIDT instruction, since it is not privileged (and it doesn't 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 didn't 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/.

Vmware 的后门 (原文由coolq发表,文章转载自他的博客)

Vmware 的后门 (原文由coolq发表,文章转载自他的博客)后门简介       Vmware 后门是 vmware 和 vmware tools 通信的一个接口。例如,vmware-check...
  • freexploit
  • freexploit
  • 2004年12月29日 10:51
  • 1654


  • D_R_L_T
  • D_R_L_T
  • 2018年01月28日 19:57
  • 33


  • u010383937
  • u010383937
  • 2017年04月28日 17:54
  • 628


本文分析数据来自于Web of Science, Google trend. 这篇文章准备从论文发表的角度分析,“大数据”为主题的论文有什么样的特征,这些内容对于特别是希望在这个领域发表论文...
  • wxdsdtc831
  • wxdsdtc831
  • 2013年02月04日 14:19
  • 7575


  • flyforfreedom2008
  • flyforfreedom2008
  • 2015年04月18日 15:23
  • 8886


  • qq_32400847
  • qq_32400847
  • 2016年10月21日 11:29
  • 4568


存储长篇文章:text 类型 text类型说明:  服务器代码页中的可变长度非   Unicode   数据的最大长度为 2,147,483,647 个字符。 当服务器代码页使用双字节字符时...
  • zhanzkw
  • zhanzkw
  • 2011年08月18日 15:06
  • 611


今天是我第一次在csdn上开通博客,以后我会把我在开发中的一点经验体会写出来,供大学分享. ...
  • yygyogfny
  • yygyogfny
  • 2007年05月30日 11:32
  • 386

1. 基于IntelVt技术的Linux内核调试器- 引言与IntelVT-x 技术简介

  • LinuxKerneltravel
  • LinuxKerneltravel
  • 2012年09月20日 13:32
  • 4632


  • x_i_y_u_e
  • x_i_y_u_e
  • 2016年03月11日 11:26
  • 1375
您举报文章:Vmware 的后门 (原文由coolq发表,文章转载自他的博客)