宏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安全

相關文章
相關標籤/搜索