首页
社区
课程
招聘
[翻译]RTF恶意软件如何躲避基于特征的静态检测
2018-1-21 16:15 14982

[翻译]RTF恶意软件如何躲避基于特征的静态检测

2018-1-21 16:15
14982

原文链接:https://www.fireeye.com/blog/threat-research/2016/05/how_rtf_malware_evad.html


译者注:这篇文章是FireEye研究员Junfeng Yang在2016年写的关于RTF混淆技巧的一个总结,这是我看过的关于这方面的最好的一篇文章,由于我在国内没有看到过这方面的好文章,因此决定把它翻译一下。


RTF恶意软件如何躲避基于特征的静态检测

Junfeng Yang写于2016年3月20号

历史

富文本格式(RTF)是微软开发的一种文档格式,它被广泛地用在各种平台超过29年。RTF格式非常灵活,因此也非常复杂。这使得开发一个安全的RTF解析器很有挑战性。一些臭名昭著的漏洞,如CVE-2010-3333和CVE-2014-1761都是由于RTF解析逻辑实现部分的错误导致。


事实上,RTF恶意软件并不局限于利用RTF解析漏洞。恶意RTF文档可以嵌入其他与RTF解析器不相关的漏洞,因为RTF支持嵌入对象,例如OLE对象和图像(译者补充:还有链接对象,例如CVE-2017-0199和CVE-2017-8759)。CVE-2012-0158和CVE-2015-1641是两个典型的这种漏洞——它们的根本原因并不位于RTF解析器,但攻击者可以通过其他文件格式利用这些漏洞,例如DOC和DOCX。


另一种RTF恶意软件并不使用任何漏洞。它简单地包含嵌入的恶意可执行文件,并且诱使用户去触发这些恶意文件。这允许攻击者通过电子邮件去传播恶意软件,因为电子邮件显然不是一个可以直接发送可执行文件的好载体(译者注:exe等文件类型会被电子邮件客户端(如outlook)直接锁住)。


大量的恶意软件作者更喜欢用RTF作为一个攻击载体,因为RTF是一种混淆友好型格式。因此,他们的恶意软件可以简单躲避基于如YARA或Snort的静态特征检测。这也是为什么在一个脚本化利用的时代,我们仍然看到大量这类基于RTF攻击的一个很大的原因。

在这篇博客里面,我们呈现了一些被恶意RTF使用的通用逃逸技巧。

通用的混淆

让我们来讨论一些不同的RTF混淆策略。

1. CVE-2010-3333

这个漏洞被Team509在2009年报告,是一个典型的栈溢出漏洞。利用这个漏洞是如此稳定和可靠,以至于在今天它仍在野外被使用,距离它被发现已经7年了!最近,攻击者利用这个漏洞针对了印度大使馆。


这个漏洞的根本原因是微软RTF解析器在处理pFragments图形属性时存在一处栈溢出。精心构造一个恶意RTF来利用这个漏洞允许攻击者执行容易代码。微软自漏洞披露就修复了这个漏洞,但是许多老版本的Microsoft Office仍受影响。所以它的威胁评级仍然非常高。



Microsoft Office RTF解析器在拷贝源数据到一个有限的栈缓冲区时缺少合适的边界检查。针对这个漏洞利用可以被简化如下:

{\rtf1{\shp{\sp{\sn pFragments}{\sv A;B;[word1][word2][word3][hex value array]}}}}



因为pFragments在正常RTF文档中相当罕见,许多厂商只使用YARA或Snort简单地检测这个关键字和紧随\sv的超长数字来捕获利用。这个方法对于没有混淆的样本是有用的,包括Metasploit生成的样本。然而,在对抗在野样本时,这类基于特征的检测就显得不足了。举个例子,针对印度大使馆的恶意RTF文档就是一个用来揭示这类基于特征的检测的不利一面的好例子。图1显示了这个RTF文件在16进制编辑器中的样子。我们简化了图1,因为空格限制——在原始文档中有大量重复的符号,例如{}。


图1. 混淆过的CVE-2010-3333样本


正如我们所看到的那样,pFragments关键字被分割成许多部分,这可以绕过大多数基于特征的检测。举个例子,大多数反病毒产品在这个样本第一次提交到VirusTotal都检测失败。事实上,不仅是\sn的分割片段被结合在一起,\sv的片段也被结合在一起。下面的例子证明了这种混淆:

  Obfuscated {\rtf1{\shp{\sp{\sn2 pF}{\sn44 ragments}{\sv 1;28}{\sv ;fffffffffffff….}}}}
  Clear {\rtf1{\shp{\sp{\sn pFragments}{\sv 1;28 ;fffffffffffff….}}}}




我们可以想出大量与前面提到的样本不同的方法来击败基于特征的静态检测。


注意‘\x0D’和‘\x0A’的混合——它们是‘\r’和‘\n’,RTF解析器会简单地忽略它们。


2.嵌入的对象

用户可以在RTF中嵌入多种对象,例如OLE(对象嵌入与链接)控制对象。这使得与OLE相关的漏洞,例如CVE-2012-0158和CVE-2015-1641,在RTF中进行利用成为可能。除了这些利用,在RTF文档中嵌入PE,CPL,VBS和JS这类可执行文件也是不常见的。这些文档要求一些社会工程的形式去诱导用户启动嵌入的对象。我们看到一些数据丢失防护(DLP)解决方案在RTF文档中嵌入PE文件。这是个坏实践,因为它增长了用户的不良习惯。


让我们首先来看一下嵌入对象的语法:



<objtype>指明了对象类型。\objocx是RTF恶意软件中最常见的类型;因此,让我们以它为例。紧随\objdata的数据是OLE1 native数据,定义如下:

  <data>   (\binN #BDATA) | #SDATA
  #BDATA   Binary data(二进制数据)
  #SDATA   Hexadecimal data(十六进制数据)




攻击者会尝试插入多种元素到<data>以躲避静态特征检测。让我们看一些例子来理解这些技巧:


a.  举个例子,\binN可以被#SDATA替换。紧随\binN的数据是原生二进制数据。在下面的例子里,数字123会被当作二进制数据,因此在内存中被转换位十六进制值313233。

  Obfuscated  {\object\objocx\objdata \bin3 123}
  Clear  {\object\objocx\objdata 313233}



让我们看一下另一个例子:

  Obfuscated  {\object\objocx\objdata \bin41541544011100001100000000000000000000000000000000000000000003  123}(红色高亮部分即为 415...003)
  Clear  {\object\objocx\objdata 313233}





如果我们尝试去以上表中标记为红色的数字参数字符串作为参数调用atoi或atol,我们会得到0x7fffffff,然而它的真实值应当是3。这会发生是因为\bin会获取一个32位有符号整型值作为参数。你也许会认为RTF解析器调用atoi或atol来转换数字字符串到一个整数;然而,实际情况并不是这样的。Microsoft Word的RTF解析器并不使用这些标准的C运行时函数。相反,Microsoft Word的RTF解析器中的atoi函数实现如下:



b.  \ucN和\uN

这两个都会被忽略,但紧随\uN的字符不会被跳过。


c. 空格字符(回车,换行和制表符):0x0D (\n), 0x0A (\r), 0x09 (\t)都会被忽略。


c.  转义字符

RTF有一些特殊的被保留的符号。正常使用时,用户需要转移这些符号。这里是一个不完全的列表:

\} 

\{

\%

\+

\-

\\

\'hh


所有这些转移符号都会被忽略,但有个有趣的情况,\’hh除外。让我们先来看一个例子:

  Obfuscated  {\object\objocx\objdata 341\’112345 }
  Clear  {\object\objocx\objdata 342345}



当解析\’11时,解析器会将11当作一个被编码过的十六进制字节。这个十六进制字节然后被丢弃,接着继续解析objdata剩下部分。\’11前面的1也会被忽略。一旦RTF解析器解析\’11前的1时,这是一个8位字节的高4位,然后它们马上遇到\’11,高4位将会被丢弃。那是因为用来解码16进制字符串到二进制字节的内部状态被重设了。

  \'hh A hexadecimal value, based on the specified character set

(may be used to identify 8-bit values).





下表显示了处理过程,黄色行的两个1来自\’11。显然这个混合的\’11扰乱了状态变量,这导致第二个字节的高4位被丢弃。



e.  超长的控制字和数字参数

RTF格式规范规定控制字长度不能超过32个字母,并且控制字相关的数字参数必须是16位有符号整数或是32位有符号整数,但微软office的RTF解析器并没有严格遵循这一规范,它的实现中只保留了一块大小为0xFF的缓冲区用来存储控制字字符串和数字参数字符串,这两者都是以null结尾的,长度大于0xFF之后的所有字符都不会被作为控制字或者参数字符串的一部分。相反,控制字和数字参数会被强制结束。



在第一个混淆例子中,超长控制字的长度是0xFE。通过添加一个null终止符,控制字字符串将会到达0xFF的最大长度,接下来的数据属于objdata。

在第二个混淆例子中,“bin”控制字和它的参数的整个长度是0xFD。通过添加它们的null终止符,长度等于0xFF。


f.  额外的技术

Word程序会使用列表中的最后一个\objdata控制字,如下所示:

  Obfuscated {\object\objocx\objdata 554564{\*\objdata 4444}54545}

 OR

{\object\objocx\objdata 554445\objdata 444454545} 


OR


{\object\objocx{{\objdata 554445}{\objdata 444454545}}}

  Clear  {\object\objocx\objdata 444454545}














正如我们在这里看到的,除了\binN,另外控制字会被忽略:

  Obfuscated  {\object\objocx\objdata 44444444{\par2211 5555}6666}
  
OR

{\object\objocx\objdata 44444444{\datastore2211 5555}6666}  


OR


{\object\objocx\objdata 44444444\datastore2211 55556666} 


OR


{\object\objocx\objdata 44444444{\unknown2211 5555}6666}   


OR


{\object\objocx\objdata 44444444\unknown2211 55556666}

  Clear {\object\objocx\objdata 4444444455556666}






















存在一个特殊的例子,使得情况变得更复杂一点。那就是\*符号。从RTF格式规范中,我们可以获得关于这个控制符号的描述:

在1987版的RTF格式规范后增加的描述中,控制字前可能会先被添加一个\*(反斜杠星号)控制符。这个符号指明的控制字具有如下特点:如果RTF解析器不认识当前控制字,它相关的文本域应当被忽略。


让我们来看一些它是如何被用在混淆中的:

1.      

  Obfuscated {\object\objocx\objdata 44444444{\*\par314 5555}6666}
  Clear {\object\objocx\objdata 4444444455556666}




\par是一个已知的控制字,它不接受任何数据。RTF解析器会跳过这个控制字,并且只接受紧随其后的部分。


2.

  Obfuscated {\object\objocx\objdata 44444444{\*\datastore314 5555}6666}
  Clear {\object\objocx\objdata 444444446666}




RTF解析器也可以识别\datastore,并且理解它可以接受数据,因此接下来的数据会被\datastore消耗。


3.

  Obfuscated {\object\objocx\objdata 44444444{\*\unknown314 5555}6666}  
  Clear {\object\objocx\objdata 444444446666}





对于一个分析人士,从被混淆的RTF文档中手动提取嵌入对象是困难的,而且没有公开的工具可以处理混淆过的RTF。然而,winword.exe使用OleConvertOLESTREAMToIStorage函数去转换OLE1 native数据到OLE2结构化存储对象。这是这个函数的声明:



lpolestream指向的对象指针包含一个指向OLE1 native二进制数据的指针。我们可以在OleConvertOLESTREAMToIStorage函数首部下一个断点,然后转储已经被RTF解析器去混淆的对象数据:



译者注:上图的命令存在错误

db 0e170020 L831b6 应改为 db poi(0e170020) L831b6, 否则数据出现的数据不是上图中的01 05 00 00...

下图为windbg文档对dc命令的解释:



最后一个命令,.writemem将一部分内存写入d:\evil_objdata.bin。你可以指定你想要的另外路径;poi(0e170020)是内存范围的起始地址,831b6为大小。


大部分\objdata的混淆技巧也可以应用到嵌的入图片,但对于图片,似乎没有像OleConvertOLESTREAMToIStorage这类明显的技术。为了抽取一张混淆过的图片,使用数据断点锁定RTF解析代码,那会揭示转储整个数据的最佳位置。

结论

我们的对手是经验老道的,并且熟悉RTF格式规范和Microsoft Word的内部工作原理。他们能够设计出这些混淆技巧去躲避传统基于特征的检测。理解我们的对手如何进行混淆可以反过来帮助我们改善对这类恶意软件的检测。

致谢

感谢inhong Chang, Jonell Baltazar和Daniel Regalado对这篇博客的贡献。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (3)
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
虚影x 2018-8-15 13:26
2
0
感谢~
雪    币: 3937
活跃值: (5559)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
badboyl 2 2019-12-5 21:28
3
0
厉害了。
雪    币: 68
活跃值: (3035)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
不懂就不懂 2 2019-12-10 18:15
4
0
哇 谢谢银雁冰大哥!
游客
登录 | 注册 方可回帖
返回