简单来说就是可以直接加载可读内存中的加密 ShellCode,不需要解密,不需要申请新的内存,也不需要改可执行权限。应用不仅仅在上线,上线后的各种功能都可以通过 ShellCode 实现
1.查杀点
现状
在加载 ShellCode、使用 BOF 等时候,经常需要将机器码密文解密写入可写权限的内存,再改为可执行权限来运行
弊端
需要经常进行内存属性修改的敏感行为,并且机器码明文处于可执行权限的内存中,迟早会被查杀
2.规避查杀点
目标
不使用 RWX、不修改内存属性、不解密 ShellCode,就可以加载 ShellCode
解决方案
代码编写 -> 提取 ShellCode -> 机器码转汇编 -> 汇编转换自定义语言 -> 通过解释器运行
3.解释器实现
解释器和编译器的区别
编译器就类似常规的 ShellCode 加载方式,去运行机器码
解释器是去解析你自定义的语言来进行对应的操作
实现原理
一步一步讲
获取 ShellCode 汇编
ShellCode.c:
代码语言:javascript复制#include <windows.h>
// 设置入口点#pragma comment(linker, "/entry:Shell")
/** 1.C/C * 常规: SDL检查(否)* 代码生成: 运行库(多线程)、安全检查(禁用安全检查)* 2.链接器* 清单文件: 生成清单(否)* 调试: 生成调试信息(否)* 高级: 入口点(Shell)*/
typedef int(WINAPI* pMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
// 入口函数置顶#pragma code_seg(".text")
void Shell(pMessageBoxA funcMessageBoxA) {char a[] = { '