VMware漏洞实例分析之共享文件夹目录遍历

安全 漏洞
目录遍历##远程攻击##立即处理[msg]当Guest位于\\.host\Shared Folders\Share目录下时,Guest执行命令“dir”,就相当于要求Host机执行“dir E:\Debug\Share”,那再让Guest执行命令“dir ..”,会发生什么情况呢?VMware漏洞由此产生。

  一、名词定义

  Host机:运行VMware软件的真实主机;

  Guest机:装在VMware软件中的虚拟系统;

  后门:VMware有一套自己专有的“Backdoor I/O Port”指令,Host和Guest之间的所有数据都是通过一个固定的IO端口,使用in和out指令来进行传递,Guest就是通过这个端口发命令让Host帮助它完成某些自身不能完成的工作。

  二、漏洞背景

  理论上来说,可以认为Host机和Guest机是两台不同的电脑,只不过它们是共享同一套真实的物理硬件,这样就带来一个问题,即如何在Host和Guest之间传输数据, VMware的共享文件夹就是解决该问题的一个很实用功能,不需要设置任何网络,就可以在Host和Guest机器间互相传输文件。至于怎么设置共享文件夹,不是本文的重点,就不多说了,不熟悉的建议Google一下先。

  在安装完VMware Tools后,会在Guest机上看到一个名为Hgfs.sys的文件,这个驱动文件实现了一个虚拟的文件系统,这个虚拟文件系统的根目录就 是\\.host,当你在Guest机上进入任何共享文件夹的目录时,可以看到路径都是以\\.host开始的,在这个目录下的所有操作都将通过后门传递 给运行在Host上的VMware主程序。

举例来说:在Host机上有个目录是:E:\Debug\Share,把这个目录设置为Guest系统的共享目 录后,VMware会记录下这个目录所对应的Host路径是E:\Debug\Share,当在Guest机的“运行”对话框中输入:\\.host \Shared Folders\Share,就会在Guest上打开E:\Debug\Share这个目录。

这个过程是通过后门完成的,Guest把“遍历目录“命令传 递给Host,Host上的VMware主程序找到该目录对应关系,通过API函数遍历E:\Debug\Share目录,把得到的数据通过后门返回给 Guest,***Guest上就列出了Share目录下的所有文件。

  三、漏洞描述

  现在就到了本文所要说的重点了。我们知道,当Guest位于\\.host\Shared Folders\Share目录下时,Guest执行命令“dir”,就相当于要求Host机执行“dir E:\Debug\Share”,没有问题。那再让Guest执行命令“dir ..”,会发生什么情况呢?

如果是Host本身在执行这条命令,没有问题,自然会列出E:\Debug下的所有文件;但现在要求执行命令的是 Guest,Host只设置了E:\Debug\Share这个目录给Guest,自然是希望Guest只能看到这个目录,而没有权限看到它的父目录,因此VMware会对含有“..”的路径名作特别处理,处理的结果就是Guest上执行这条命令无效。

  那么它的处理方法是什么呢?简单说来是这样的,VMware会对共享文件夹的路径名进行验证,确认它不含有0×2e0×2e(翻译为ASCII子字符就是 “..”)字符串后,就会将其从多字节字符串转换为宽字符字符串,然后将所生成的宽字符字符串传送给Host上的系统文件API。这个转换使用 Windows API中的MultiByteToWideChar函数完成。该函数的原型如下:

      int MultiByteToWideChar (
  UINT CodePage,
  DWORD dwFlags,
  LPCSTR lpMultiByteStr,
  int cbMultiByte,
  LPWSTR lpWideCharStr,
  int cchWideChar
  );

  这里只对dwFlags做简单解释。

  dwFlags:指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。其中:

  MB_ERR_INVALID_CHARS:设置此选项,则函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符。

  正是由于对MultiByteToWideChar函数中dwFlags参数的错误使用,导致VMware共享文件夹先后出现了两个漏洞,按时间顺序是 CVE-2007-1744和CVE-2008-0923。

不过严格说起来,这并非是因为VMware开发人员在使用 MultiByteToWideChar函数时的编码错误,而是由于这套验证机制本身在逻辑上就存在一个漏洞。

因为:验证“..”字符串是在转换输入字符 串之前执行的,因此只要Guest系统上的恶意程序或用户提供的路径名可以通过验证,则在调用MultiByteToWideChar之后仍可能映射为包 含有Unicode UTF-16版本的“..”字符串。

  3.1 CVE-2007-1744

  受影响版本:

  VMWare VMWare Workstation 5.5.3 build 34685

  不受影响版本:

  VMWare VMWare Workstation 5.5.4 build 44386

  这个漏洞的起因是dwFlags使用了默认值0,这意味着在转换过程中会忽略输入的无效字符,因此可以很容易地构造出一个多字节字符串,轻松地绕过验证,成为Unicode UTF-16版本的“..”。示例程序如下:

      #include 
  int main(int argc, char* argv[])
  {
  unsigned int ans;
  char utf8[] = { 0xc0,0×2e,0xc0,0×2e }; //0xc0是无效字符
  wchar_t utf16[100] = { 0 };
  UINT CodePage = CP_UTF8;
  ans = MultiByteToWideChar(CodePage,
  0,
  (LPCSTR)&utf8,
  4,
  (LPWSTR)utf16,
  100);
  printf(”utf16: %S\n”, utf16);
  return 0;
  }

  尽管0xc0是无效字符,但因为使用的的dwFlags值是0,所以MultiByteToWideChar函数会忽略它,而继续转换有效的字符 0×2e,所以执行这个程序的输出结果是:utf16: ..可见,只要我们在输入的路径名中包含“0xc00×2e0xc00×2e”,那么就能够通过VMware对0×2e0×2e的验证,因此Host会去访问上层目录,从而让Guest看到不应该看到的东西。

  3.2 CVE-2008-0923

  受影响版本

      VMWare Workstation 6.0.2
  VMWare Workstation 5.5.4
  VMWare Player 2.0.2
  VMWare Player 1.0.4
  VMWare ACE 2.0.2
  VMWare ACE 1.0.2

  不受影响版本:

      VMWare Workstation 6.0.3
  VMWare Workstation 5.5.6
  VMWare Player 2.0.3
  VMWare Player 1.0.5
  VMWare ACE 2.0.3
  VMWare ACE 1.0.5
  VMWare ESX
  VMWare Server

  由于上个漏洞中dwFlags参数简单使用了默认值0,导致无效字符也能够顺利通过转换,因此VMware的更新版本中将dwFlags参数的值修 改为 MB_ERR_INVALID_CHARS,这个宏的整数值是8。这样一来,像上面使用过的“0xc00×2e0xc00×2e”字符串,由于包含了无效 字符,就会导致MultiByteToWideChar函数调用失败了。那么,我们有没有办法构造出一个有效的多字节字符序列,而又能成功转换为 Unicode UTF-16版本的“..”呢?试一试就知道了,还是让程序来帮忙吧。测试程序如下:

      #include 
  #include 
  #include 
  int main(int argc, char* argv[])
  {
  unsigned int i, ans;
  unsigned char buf[200];
  UINT CodePage = CP_UTF8;
  for (i=1; i; i++)
  {
  memset(buf, 0, 200);
  ans = MultiByteToWideChar(CodePage,
  MB_ERR_INVALID_CHARS, //8
  (LPCSTR)&i,
  4,
  (LPWSTR)buf,
  100);
  if (ans && (buf[0] == ‘.’) && (buf[1] == 0) && ((i & 0xff) != ‘.’))
  {
  printf(”%d %04x: %02x %02x %02x %02x\n”, ans, i,
  buf[0], buf[1], buf[2], buf[3]);
  getchar(); // 找到后让程序暂停一下
  }
  }
  return 0;
  }

  很快就能找到第1个字符序列是“0xc20×2e0xc20×2e”,也就是说它能够通过验证,并且成功地转换为Unicode UTF-16版本的“..”。

责任编辑:王文文 来源: IT专家网论坛
相关推荐

2010-07-14 21:10:09

VirtualBox

2022-12-06 08:29:01

2011-08-02 09:38:58

ActiveDirec域控制器共享文件夹

2011-09-15 14:23:43

ubuntusmb

2022-11-16 16:28:21

2011-08-02 09:22:15

ActiveDirec域控制器共享文件夹

2022-07-21 11:31:28

UbuntuWindowsLinux

2009-08-15 21:22:19

2018-02-05 09:15:17

Linux命令文件数量

2022-01-01 19:00:17

LinuxLinux命令文件夹

2013-04-03 12:57:01

Android开发读写assets目录下

2014-05-04 13:22:28

Windows Ser故障转移

2015-06-01 12:19:03

FedoraCentOSSamba

2009-08-31 12:31:45

C#创建文件夹

2010-01-03 21:15:47

linux安全centos

2012-12-13 13:38:22

nginx目录遍历漏洞

2013-04-26 10:59:54

目录遍历漏洞

2010-12-31 13:35:25

文件夹重定向

2019-04-01 19:00:40

Linuxshell内置命令

2013-08-23 09:19:57

Cryptkeeper加密
点赞
收藏

51CTO技术栈公众号