宏Virus

前言:
 去年自学了部分关于宏病毒的知识,一直忙于学新知识,转眼又过了年,年前没能汇总、整理、分享宏病毒相关的笔记与心得,此次经过两个样本聊聊常见的宏病毒。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就能够弹出,以下图所示:
宏Virus
                     图片一:宏运行界面

你弹出的不是这种界面,而是一个密码框?说明宏被加密了,以下所示:
宏Virus
                     图片二:加密界面

这时候介绍一款工具VBA Password Bypasser,很实用的一款工具,你只须要把.doc在工具中打开,而后Alt+F11再次查看,就会发现密码自动被破解了,进入了图一的界面当中,这样你就见了所谓的宏代码。
宏Virus
                     图片三:VBA Password Bypasser

如何静态提取宏的源码呢?不运行文档能不能提取其中的宏代码?固然也能够,有一款开源的Python的插件,叫作oledump.py,连接:https://github.com/decalage2/oledump-contrib

如图一,发现打开后代码是混淆或加密,代码中根本就看不懂,只能看到几个关键字,这样得话给分析这个宏行为(代码行为)就带来一些干扰,可是不论怎样混淆,代码自身必须是能运行的,也就是必须能运行时识别,运行的方式有不少种,如Shell,Application.Run等关键函数,定位关键字,解密数据,以下所示:
补充:html

Function XXX()
            这种格式表示一个函数
End Function

Sub AutoOpen() 
            运行文档时候,自动运行宏
End Sub

宏Virus
                     图片四:入口点
有点OEP的感受,不过真的就是从这个地方开始,由于使用AutoOpen(),运行文档时候,调用宏代码,如何下断点与动态调试呢?以下所示:
宏Virus
                     图片五:动态调试

这样必要的时候能够动态调试以精准获取数据,下面就来分析KlsJVlijz函数,以下所示:
宏Virus
                     图片六:KlsJVlijzios


 利用关键字定位的手段,快速找到关键代码数据,如Shell关键字,Ctrl+F弹出搜索窗口,以下所示:
宏Virus
                     图片七:Shell关键字

 发现Shell后面的数据都是加密过的数据,把上面不少变量都使用+进行了拼接,这时候就要修改一下vb代码,来获取shell到底作了什么操做,以下所示:
宏Virus
                     图片八:修改源码

 如上述代码所示,这样就能够把指令拼接到变量Contenu中,而后保存到文件里,便于咱们分析,或者简单点,动态调试直接监视其中观察Contenu的数据粘贴复制出来也是没问题的。
 打开Data.txt看一看,被定向后的内容究竟是什么?稍微排版了一下,以下所示:
宏Virus
                     图片九:数据

 这时候就看到了一些关键字如Cmd /V /c Set等,说明要执行一条与cmd相关的指令,且发现拼接起来的变量十powershell,以下所示:
宏Virus
                     图片十:powershell
请看参数powershell的参数是-e ,加密数据你怎么知道是如何加密呢?字符串最后有符号=,像是Base64的特征,而-e是什么?接收Base64编码字符串命令,既然能接收Base64指令,应该没问题,对不对呢?尝试后就知道了,在上一篇博客Xbash中也对powershell的加密作了分析与介绍,解密后以下:
宏Virus
宏Virus
宏Virus
                     图片十一:Base64解密后数据
 是否是解密出错了?为何解密后仍是那么多不认识的数据,并且看上去有点中间居然还有加密,遇到这种状况必定仔细观察分析,不是靠猜就能够,计算机执行数据必定是由依据的,以下所示:
宏Virus
                     图片十二:数据规则

 这样就明白了,计算器在执行的这条指令的时候就是按照规则去分割,取正确的数据执行,也就是把Y&{m:}等乱七八糟的数据去掉,这些混淆的数据去掉以后应该就没问题了,以下所示:
宏Virus
                     图片十三:还原数据

那么如何编写取混淆的代码呢?压缩包中有别人写的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(发票收据),由于这些脚本病毒他们不能随便改图标来达到以假乱真,有时候经过文件名来假装本身,一不当心就上当了,仍是老样子,静态提取或者动态调试根据我的而定,以下所示:
宏Virus
                     图片十四:样本二

 看上去要比上一个复杂多了,那么多文件,可是咱们仍是要关键点分析,不要看函数是可能是少,最终会被执行的数据才是真正的恶意代码,因此找关键字,以下所示:
宏Virus
                     图片十五:Application.Run

 发现执行且调用了函数rGNvwJqoJ,点开其他的文件发现该函数实如今CTrjsVrF,这就好办了,以下所示:
宏Virus
                     图片十六:跟踪数据
补充:shell

On Error Resume Next 异常处理,若是出错了继续执行不中断
Dim 声明变量并分配存储空间
Set 将对象引用赋给变量或属性


一样发现文本CTrjsVrF中全被加密,仍是老方法定位关键执行点,看到Shell代码以后是否是很眼熟,Shell后面又个逗号分割开的vbHide符号,表示隐藏,不用拼接到Continue变量中。
 经过样本1中的方法,获取被真正执行的数据。你仔细观察,其余文件的函数都会被上面所加密的数据调用,因此须要确认被执行的数据便可。
以下图所示:
宏Virus
                     图片十七:获取数据

格式与下面的指令同样:
宏Virus
                     图片十八:指令格式编程

以上代码被识别的数据作了三件事:
  一、%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'')的含义,这个是什么?以下所示:
宏Virus
                     图片十九:IEX混淆

 Xbash中也介绍过IEX了,既然是IEX就好办了,直接删除掉这一段代码就好了,而后重定向到文件或者贴上删除后的代码运行,便可还原出源代码,以下所示:
宏Virus
                     图片二十:数据还原
上述代码中已经作了详细的注释,发现解密后的宏与样本一套路是同样的,不过样本二解密后的样本字符串处理的也很好,全部字符串都进行了拆分处理,解密思路以下所示:
宏Virus
                     图片二十一:思路
文章中的宏病毒并不难,并无涉及太多的数据与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安全

相关文章
相关标签/搜索