前言:
去年自学了部分关于宏病毒的知识,一直忙于学新知识,转眼又过了年,年前没能汇总、整理、分享宏病毒相关的笔记与心得,此次经过两个样本聊聊常见的宏病毒。php
样本一 | 样本二 |
---|---|
加密混淆(附C++去混淆代码) | 加密混淆 |
宏病毒:最多见的就是微软的office(Word宏),欺骗受害者点击文档(假装),运行宏代码,从而感染了Word宏病毒,一般宏病毒是做为下载器来传播的。
我的感受最好的办法是禁用宏呗,一旦打开Word,有宏运行,那么就会提示禁止了宏没法运行(选项中的安全级别能够设置宏的安全等级)。
宏编程语言(WORD):VBA 就是嵌入应用程序(WORD)中的VB 语法与vb同样,只是它有特定对象、方法、属性,写出的代码不能脱离word环境。
宏的爱好::宏病毒为了不杀毒软件的查杀,一般不会利用敏感API,特别喜欢混淆与加密,也特别喜欢利用powershell来执行命令,有意思的是大多数,如挂马网页,XML,vbs等等,都喜欢利用powershell来进行恶意代码的执行,powershell安全让人汗颜。
WPS我的版没有宏功能......当初自学的时候确实有点小白,不事后缀.docx并不必定没有宏病毒,好像看过一篇过于APT28。经过嵌入在.docx中的settings.xml.rels组件下载了恶意代码(包含宏组件及vb好像),收集系统信息和运行进程,并使用http,发送到指定的服务器,最后会给你们推荐一些比较好的相关学习的博客与资料。
✃
样本一分析:
到底宏病毒是什么样?其实就是代码,因此双击是看不到宏病毒的,先Word打开看一看,打开后会提示“安全警告”,启用宏的话就运行了宏,首先你要知道如何去看宏代码:Alt + F11就能够弹出,以下图所示:
图片一:宏运行界面
你弹出的不是这种界面,而是一个密码框?说明宏被加密了,以下所示:
图片二:加密界面
这时候介绍一款工具VBA Password Bypasser,很实用的一款工具,你只须要把.doc在工具中打开,而后Alt+F11再次查看,就会发现密码自动被破解了,进入了图一的界面当中,这样你就见了所谓的宏代码。
图片三:VBA Password Bypasser
如何静态提取宏的源码呢?不运行文档能不能提取其中的宏代码?固然也能够,有一款开源的Python的插件,叫作oledump.py,连接:https://github.com/decalage2/oledump-contrib
如图一,发现打开后代码是混淆或加密,代码中根本就看不懂,只能看到几个关键字,这样得话给分析这个宏行为(代码行为)就带来一些干扰,可是不论怎样混淆,代码自身必须是能运行的,也就是必须能运行时识别,运行的方式有不少种,如Shell,Application.Run等关键函数,定位关键字,解密数据,以下所示:
补充:html
Function XXX() 这种格式表示一个函数 End Function Sub AutoOpen() 运行文档时候,自动运行宏 End Sub
图片四:入口点
有点OEP的感受,不过真的就是从这个地方开始,由于使用AutoOpen(),运行文档时候,调用宏代码,如何下断点与动态调试呢?以下所示:
图片五:动态调试
这样必要的时候能够动态调试以精准获取数据,下面就来分析KlsJVlijz函数,以下所示:
图片六:KlsJVlijzios
利用关键字定位的手段,快速找到关键代码数据,如Shell关键字,Ctrl+F弹出搜索窗口,以下所示:
图片七:Shell关键字
发现Shell后面的数据都是加密过的数据,把上面不少变量都使用+进行了拼接,这时候就要修改一下vb代码,来获取shell到底作了什么操做,以下所示:
图片八:修改源码
如上述代码所示,这样就能够把指令拼接到变量Contenu中,而后保存到文件里,便于咱们分析,或者简单点,动态调试直接监视其中观察Contenu的数据粘贴复制出来也是没问题的。
打开Data.txt看一看,被定向后的内容究竟是什么?稍微排版了一下,以下所示:
图片九:数据
这时候就看到了一些关键字如Cmd /V /c Set等,说明要执行一条与cmd相关的指令,且发现拼接起来的变量十powershell,以下所示:
图片十:powershell
请看参数powershell的参数是-e ,加密数据你怎么知道是如何加密呢?字符串最后有符号=,像是Base64的特征,而-e是什么?接收Base64编码字符串命令,既然能接收Base64指令,应该没问题,对不对呢?尝试后就知道了,在上一篇博客Xbash中也对powershell的加密作了分析与介绍,解密后以下:
图片十一:Base64解密后数据
是否是解密出错了?为何解密后仍是那么多不认识的数据,并且看上去有点中间居然还有加密,遇到这种状况必定仔细观察分析,不是靠猜就能够,计算机执行数据必定是由依据的,以下所示:
图片十二:数据规则
这样就明白了,计算器在执行的这条指令的时候就是按照规则去分割,取正确的数据执行,也就是把Y&{m:}等乱七八糟的数据去掉,这些混淆的数据去掉以后应该就没问题了,以下所示:
图片十三:还原数据
那么如何编写取混淆的代码呢?压缩包中有别人写的Python写的脚本去混淆代码,10来多行
我的用的C++写的,第一个版本去混淆代码量与Python差很少,可是规范整理后,写了些注释,并且考虑了不少状况,代码量就上去了,单纯针对去写应该很简单的,C++代码以下:git
#include "pch.h" #include <iostream> #include <vector> #include <string> #include <sstream> using namespace std; /* 转换Ascii码 */ // 保存转换后的数据 vector<char> vNewData; // 保存获取数字 string nSaveStr; void FilterNumberOfAscii(const char* str,int & nSize); int ToAsciiOfchar(int temp); int main() { // 须要转换的数据 char Data[] = { "xxxxxxxxx" }; // 注意不能sizeof求数组大小,会把最后的'\0'也看成数据来比对的 int nDataSize = strlen(Data); FilterNumberOfAscii(Data, nDataSize); // 遍历输出转换后的数据 for (auto iter = vNewData.begin(); iter != vNewData.end(); ++iter) { cout << (*iter); } putchar('\n'); system("pause"); return 0; } // Ascii判断及转换 int ToAsciiOfchar(int temp) { // 保存转换后的Ascii char cSaveAscii; istringstream is(nSaveStr.c_str()); is >> temp; // 2. 将数字判断是不是ascii码 if (isascii(temp)) { // 3. 转换成ascii码保存到 cSaveAscii = toascii(temp); vNewData.push_back(cSaveAscii); nSaveStr.clear(); return 1; } return 0; } // 条件过滤 void FilterNumberOfAscii(const char* str, int & nSize) { int temp; nSaveStr.clear(); for (int i = 0; i < nSize; i++) { temp = 0; /*36!78asd99*/ // 1. 连续的数字就有多是Ascii if (('0' <= str[i]) && ('9' >= str[i])) nSaveStr += str[i]; else { if (nSaveStr.size() != 0) if (!ToAsciiOfchar(temp)) { // 若是是连续数字且不是Ascii码怎么办?解决思路以下: // 一、注意顺序是最后一个在最前面,调用reverse 反转 // nSaveStr.reserve(); // // for (int i = 0; i < nSaveStr.size(); ++i) // { // // 二、把数据入栈便可 // vNewData.push_back(); // } // 由于该样本加密规律 因此上面就用不到了 cout << "发现了连续数字非Ascii码: " << temp << endl; } // vNewData.push_back(str[i]); } } // 注意:由于按照strlen长度来for,最后一次容器中内容也要转换 if (nSaveStr.size() != 0) ToAsciiOfchar(temp); }
样本一的分析就到这结束,经过上面的分析应该对宏有必定的认知与解密去混淆的思路,下面一块儿来看第二个样本。github
✃
样本二分析:
样本二文件名是Invoice_receipt(发票收据),由于这些脚本病毒他们不能随便改图标来达到以假乱真,有时候经过文件名来假装本身,一不当心就上当了,仍是老样子,静态提取或者动态调试根据我的而定,以下所示:
图片十四:样本二
看上去要比上一个复杂多了,那么多文件,可是咱们仍是要关键点分析,不要看函数是可能是少,最终会被执行的数据才是真正的恶意代码,因此找关键字,以下所示:
图片十五:Application.Run
发现执行且调用了函数rGNvwJqoJ,点开其他的文件发现该函数实如今CTrjsVrF,这就好办了,以下所示:
图片十六:跟踪数据
补充:shell
On Error Resume Next 异常处理,若是出错了继续执行不中断 Dim 声明变量并分配存储空间 Set 将对象引用赋给变量或属性
一样发现文本CTrjsVrF中全被加密,仍是老方法定位关键执行点,看到Shell代码以后是否是很眼熟,Shell后面又个逗号分割开的vbHide符号,表示隐藏,不用拼接到Continue变量中。
经过样本1中的方法,获取被真正执行的数据。你仔细观察,其余文件的函数都会被上面所加密的数据调用,因此须要确认被执行的数据便可。以下图所示:
图片十七:获取数据
格式与下面的指令同样:
图片十八:指令格式编程
以上代码被识别的数据作了三件事:
一、%ComSpEc% C:\Windows\system32\cmd.exe
二、cmd参数 /c的含义是执行指定字符串而后停止
三、混淆powershellb变量数组
最初分析的时候因为自学,耗费了很长一段时间,缘由很简单,我没看到iex,也没太注意最后的数据,而分析的思路以下:
一、分析解密
Runtime.interOpservices.marSHAl
ptrostringingUnI([runtime.interOpservices.marshaL]
securestring to globalaloc unicode
covertto-securestring -ke (3..34)
二、确认加密方式convertto-securestring
三、微软官方关于convertto-securestrin介绍:https://docs.microsoft.com/zh-CN/previous-versions//dd347656(v=technet.10)
四、解密开始
而后根据微软的参考写脚本解密,结果一直不尽人意,最后又完整分析,才明白字符串 ( $ENV:coMSpeC[4,15,25]-joiN'')的含义,这个是什么?以下所示:
图片十九:IEX混淆
Xbash中也介绍过IEX了,既然是IEX就好办了,直接删除掉这一段代码就好了,而后重定向到文件或者贴上删除后的代码运行,便可还原出源代码,以下所示:
图片二十:数据还原
上述代码中已经作了详细的注释,发现解密后的宏与样本一套路是同样的,不过样本二解密后的样本字符串处理的也很好,全部字符串都进行了拆分处理,解密思路以下所示:
图片二十一:思路
文章中的宏病毒并不难,并无涉及太多的数据与API的使用,只是增长了分析的难度与干扰。好比APT宏利用漏洞释放大量的代码,且对屏幕按键进行捕获,利用释放的程序进行网络传输,那些分析起来应该就会困难不少。
连接:https://pan.baidu.com/s/1tI4JFnKVz81zf05rzMgwKg
提取码:dezj
推荐:关于复合文档的研究:http://www.javashuo.com/article/p-exwkmzqb-eq.html
推荐:关于宏专辑:https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=133安全