倾旋的博客

倾旋的博客

现阶段在进行有效性验证/攻击模拟相关的安全研究工作,我的博客会记录一些我的学习过程和部分安全技术研究成果。

02 Mar 2020

通过反射DLL注入来构建后渗透模块(第一课)

Aggressor Script

Aggressor Script是Cobalt Strike 3.0版本以上的一个内置脚本语言,由Sleep语言解析,Cobalt Strike 3.0以上版本的菜单、选项、事件都由default.cna构建。红队人员可以通过它来调用一些IRC、Webhook接口去对接机器人,实现自动化渗透与监控,Aggressor Script是Cobalt Strike这款C2平台的画龙点睛之笔。

对于Python、C/C++爱好者来说,Sleep语言一开始接触的时候感觉很奇怪,会有很多想吐槽的点,但久而久之,就会发现它的便捷之处。

反射 DLL注入

Aggressor Script脚本提供了一些关于反射DLL的接口:https://cobaltstrike.com/aggressor-script/functions.html#bdllspawn

话不多说,先上代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved ) {
	BOOL bReturnValue = TRUE;
	switch( dwReason ) {
		case DLL_QUERY_HMODULE:
			if( lpReserved != NULL )
				*(HMODULE *)lpReserved = hAppInstance;
			break;
		case DLL_PROCESS_ATTACH:
			hAppInstance = hinstDLL;
	
			/* print some output to the operator */
			if (lpReserved != NULL) {
				printf("Hello from test.dll. Parameter is '%s'\n", (char *)lpReserved);
			}
			else {
				printf("Hello from test.dll. There is no parameter\n");
			}

			/* flush STDOUT */
			fflush(stdout);

			/* we're done, so let's exit */
			ExitProcess(0);
			break;
		case DLL_PROCESS_DETACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
			break;
	}
	return bReturnValue;
}

很明显,这是一个DLL的主函数,在经过DLL_PROCESS_ATTACH的时候,开始执行代码。程序通过DLLMain函数的lpReserved来当做参数传递。

但光看一个DLLMain是看不出后面的奇妙的,我们把目光转向反射DLL注入技术的作者:

2020-03-01-11-25-55

这里有一个完整示例。

通过跟踪代码:https://github.com/stephenfewer/ReflectiveDLLInjection/blob/master/inject/src/LoadLibraryR.c

2020-03-01-11-26-06

发现该函数会寻找ReflectiveLoader这个导出函数的地址,然后直接创建一个远程线程执行这个函数,这个函数本身又会自动模拟整个LoadLibrary API,从而执行DLLMain,最终完成代码执行。

开发自己的反射DLL

首先,可以直接将反射DLL注入作者的项目拿过来使用:

2020-03-01-11-26-50

接着就要编写cna脚本了。

2020-03-01-11-27-00

文件目录:

2020-03-01-11-27-08

通过Cobaltstrike加载后,可以执行reflective_dll在客户端弹出一个信息框。

2020-03-01-11-27-21

整个过程是拥有极少的敏感行为特征,因此可以非常容易的绕过一些反病毒查杀。