欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

WinRAR目录穿越漏洞浅析及复现(CVE-2018-20250)

来源:本站整理 作者:ERFZE 时间:2019-03-15 TAG: 我要投稿

我是于2月21号看见各大安全网站都发布了”WINRAR曝出严重漏洞,影响全球5亿用户”的文章,才了解到这个漏洞。等到真正去研究它,是backlion师傅已经将exp发出来之后了。这是本菜研究及复现的第一个漏洞,其中若有分析不到位或者错误的地方烦请各位师傅指正,谢谢。
0×02 漏洞描述
该漏洞由Check Point团队爆出,是一个关于WinRAR存在了19年的漏洞,用它来可以获得受害者计算机的控制。攻击者只需利用此漏洞构造恶意的压缩文件,当受害者使用WinRAR解压该恶意文件时便会触发漏洞。
其实不只是WinRAR,凡是使用了UNACE2.dll动态链接库的解压软件就会受影响,具体可参考0×03中受该漏洞影响的解压软件及版本号。
该漏洞是由 WinRAR 所使用的一个陈旧的动态链接库UNACEV2.dll所造成的,该动态链接库在 2006 年被编译,没有任何的基础保护机制(ASLR, DEP 等)。动态链接库的作用是处理 ACE 格式文件。而WinRAR解压ACE文件时,由于没有对文件名进行充分过滤,导致其可实现目录穿越,将恶意文件写入任意目录,甚至可以写入文件至开机启动项,导致代码执行。
0×03 漏洞影响
WinRAR
Bandizip
好压(2345压缩)
360压缩
0×04 漏洞危害
通过该漏洞攻击者可以向用户的开机启动项中植入恶意程序,实现监控受害者主机的目的。
DLL劫持
0×05 漏洞原理浅析
0×05-1 CleanPath
先来看看Check Point团队发布的文章中给出的CleanPath的伪代码:
Bool CleanPath(PCHAR Path)
{
 char *PathTraversalPos=NULL;
 if(Path[1]==':' && Path[2]=='\\')
  strcpy(Path,&Path[3]);
 if(Path[1]==':' && Path[2]!='\\')
  strcpy(Path,&Path[2]);
 PathTraversalPos=strstr(Path,"..\\");
 while(PathTraversalPos)
 {
  if(PathTraversalPos==Path || *(PathTraversalPos-1)=='\\')
  {
   strcpy(Path,&Path[3]);
   PathTraversalPos=strstr(Path,"..\\");
  }
  else
  {
   PathTraversalPos=strstr(Path+1,"..\\");
  }
 }
 return Path;
}
在执行GetDevicePathLen这个函数之前,CleanPath会清除path中的一些简单的目录遍历序列,比如:
\..\
盘符名:\
盘符名:
盘符名:\盘符名:
..\(只有它在path的开始处才会被清除)
这段伪代码的大概流程描述如下:
1.如果Path的第2、3个字符为”:”、”\”,那么将Path第4个字符之前的部分清除。
2.如果Path的第2个字符为”:”,第3个字符不为”\”,那么将Path第3个字符之前的部分清除。
3.在Path中寻找”..\”出现的位置,PathTraversalPos将指向此位置。若找到,执行4;否则执行7。
4.如果PathTraversalPos指向的位置正是Path开始的位置(e.g...\some_folder\some_file.ext)或者PathTraversalPos指向位置的前一个字符是”\”,执行5;否则,执行6。
5.将Path第4个字符之前的部分清除,继续在Path中寻找”..\”出现的位置,若找到,执行4;否则,执行7。
6.在Path+1处向后寻找”..\”出现的位置,若找到,执行4;否则,执行7。
7.返回Path。
通过上述分析我们可以看出盘符名:\是在步骤1被清除掉的,盘符名:是在步骤2被清除掉的;盘符名:\盘符名:是通过步骤1和步骤2两个步骤清除掉的;而\..\是在步骤5被清除掉的。
0×05-2 GetDevicePathLen
GetDevicePathLen的伪代码:
 INT GetDevicePathLen(PCHAR Path)
 {
  PCHAR SlashPos;
  INT Result;
  Result=0;
  if(Path[0]=="\\")
  {
   if(Path[1]=="\\")
   {
    if(!(SlashPos=strchr(&Path[2],"\\")))
    {
     return 0;
    }
    if(!(SlashPos=strchr(SlashPos+1,"\\")))
    {
     return 0;
    }
    Result=(UINT)SlashPos-(UINT)Path+1;
   }
   else
   {
    Result=1;
   }
  }
  else
  {
   if(Path[1]=":";
   {
    Result=2;
    if(Path[2]="\\")
    {
     Result++;
    }
   }
  }
  return Result;
 }
GetDevicePathLen会返回一个Result,Result取值有两种情况:非0和0。可以看看Check Point团队给出的例子:
C:\folder\file.extreturn:3
\folder\file.extreturn:1
\\LOCALHOST\C$\folder\file.extreturn:15
\\?\Harddisk0Volume1\folder\file.extreturn:21
folder\file.extreturn:0
这段伪代码的大概流程描述如下:
1.如果Path中第1个字符为”\”,执行2;否则,执行7。
2.如果Path中第2个字符为”\”,执行3;否则,执行6。
3.如果在Path第3个字符之后没有找到”\”,返回0;否则将SlashPos指向此位置。
4.如果在SlashPos+1之后没有找到”\”,返回0;否则将SlashPos指向此位置。
5.将SlashPos指向位置减去Path指向位置再加1赋值给Result(e.g.\\?\Harddisk0Volume1\folder\file.ext),然后执行9。
6.Result赋值为1,然后执行9。
7.如果Path第2个字符为”:”,Result赋值为2。
8.如果Path第3个字符为”\”,Result值加1。

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载