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

【原文由coolq发表,文章转载自他的博客 VMware的后门】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
vmcall.s 为 vm.c 提供 vmcall(uint32_t out[4],int cmd,uint32_t param) 函数 , 实现调用后门功能
.text
.align 2
.globl vmcall
.type vmcall,@function
vmcall:
pushl 雙
movl %esp, 雙
movl 0x8(雙),陎
push 韎
push 離
push 靫
push 韝
mov 陎,韎
mov $0x564d5868,韝
mov 韝,陎
mov 0xc(雙),韝
mov 0x10(雙),離
mov 韝,靫
mov $0x5658,韝
in (%dx),陎
mov 陎,0x0(韎)
mov 離,0x4(韎)
mov 靫,0x8(韎)
pop 韝
奇怪 , 被截断了 。
pop 靫
pop 離
pop 韎
leave
ret
vm.c
vm.c 为主程序 。命令行参数为后门功能号
#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;
}
举例
编译: 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 4.0.0.4460 立刻崩溃 。原因Vmware 试图去读 0x14 的内存地址 , 不过因为没有用户输入 , 无法利用 。
附录:分析工具和环境

推荐阅读