wondeekun 安全的矛与盾 2023-09-04 17:13 发表于浙江
前言在说正事之前,我还需要再补充点基础知识,为什么伪装了文件类型会有助于免杀呢?这就需要说一下杀毒引擎的工作过程了,一般一个杀软收到一个文件之后会进行如下几个步骤:
如果文件格式都识别错误了,那么后续的格式解析特征提取肯定是错的,所以就直接免杀了。 文件分析拿到文件后,先file一下,可以看到file识别的文件格式确实是pdf: - PDF document, version 1.7, 1 pages (zip deflate encoded)
复制代码但是与普通文件不同的是这里多了一个 1 pages (zip deflate encoded)接下来用文本编辑器打开:
看起来pdf该有的东西也是有的,只不过pdf格式是不合法的,我用010editor 和 pdf阅读器都不能正常打开此文件。
文章中说 olevba可以识别到此文件中的ole,那我们就试一下:
可以直接获取到启动的vba代码,仔细看输出的日志,可以发现其实olevba是把此文件当做mhtml处理了:
这个mhtml牛的地方在于,他是个文本文件,还可以执行宏代码,那我也按照帖子的方法制作一个。
看到文件头是: 但是我在样本中并没有搜到这个头呀?既然没有那olevba是怎么识别的呢? 读一下olevba的源代码: 原来只需要mime这个字符串就可以,找一下源样本文件。
样本为了防止被识别这里故意对文件头进行了混淆,还能被word软件识别大概率是因为mhtml文件的容错率是比较高的,这点改动不影响 接下来问题来了,恶意的VBA存储在这个文件的什么位置呢?既然olevba可以识别,那我们可以直接看源码:- try:
- if PYTHON2:
- mhtml = email.message_from_string(stripped_data)
- else:
- # on Python 3, need to use message_from_bytes instead:
- mhtml = email.message_from_bytes(stripped_data)
- finally:
- email.feedparser.headerRE = oldHeaderRE
- # find all the attached files:
- for part in mhtml.walk():
- content_type = part.get_content_type() # always returns a value
- fname = part.get_filename(None) # returns None if it fails
- # TODO: get content-location if no filename
- log.debug('MHTML part: filename=%r, content-type=%r' % (fname, content_type))
- part_data = part.get_payload(decode=True)
- # VBA macros are stored in a binary file named "editdata.mso".
- # the data content is an OLE container for the VBA project, compressed
- # using the ActiveMime/MSO format (zlib-compressed), and Base64 encoded.
- # decompress the zlib data starting at offset 0x32, which is the OLE container:
- # check ActiveMime header:
- if isinstance(part_data, bytes) and is_mso_file(part_data):
- log.debug('Found ActiveMime header, decompressing MSO container')
- try:
- ole_data = mso_file_extract(part_data)
复制代码可以看到这里使用 email 库来解析文件内容,如果解码出来的内容是 mso_file文件,就进入到解析ole格式的解析流程。 is_mso_file函数是判断解码出来的内容是否是ActiveMime开头的: 我们找到文件对应的位置,发现是一片狼藉: 里面包含很多空格和换行,显然是无法被base64解码的,那是怎么回事呢?继续跟踪 email库的get_payload代码: 发现在解码之前会经过很多的容错处理,其中就包括删除空格和换行,所以可以明确了,样本就是利用这里的容错机制进行混淆以绕过检测。手工去除换行和空格,发现对应的字符刚好就是 QWN0aXZlTWltZQAA 自己构造一个样本我最简单的想法是直接在一个pdf文件后面填充一个 mhtml文件,然后把后缀修改为pdf,看看可以不。
结果证明不行...也就是说他这个pdf肯定是特殊构造的,刚才输出的 1 pages (zip deflate encoded)可能是有用的,那我把原样本的pdf部分直接复制到我的mhtml文件中,发现可以了。
对PDF文件格式不是太了解,并不清楚pdf是怎么构造的,相关的样本可以在星球下载,也欢迎大家加入星球参与讨论。
|