0x01 背景
分析了一个比较有意思的样本,通过分析,发现该样本具备较强的免杀能力,并且其制作者应该具备较强的免杀能力以及安全开发能力,分析下来收获不小;有段时间没有更新blog正好也就写篇文章记录下。
0x02 样本基础信息
利用微软应用的dll劫持漏洞,白加黑运行
1
2
3
4
5
6
7
8
9
10
黑dll
name:mpclient.dll
md5:3f88191d6325df64713af7ed06631787
others:无签名
白exe
name:MpCopyAccelerator.exe
md5:262002fac594250753bf94512d17f097
others:微软签名
0x03 分析
虚拟机直接运行,观察到操作非常规文件
查看该文件操作的堆栈调用找到调用点:MpUtilsExportFunctions
IDA分析该函数:(该函数和下面的NvPluginGetinfo同地址)
函数实现如下,shellcode分离并通过回调函数加载,加载位于C:\\Users\\Public\\Config.ini
的shellcode:
shellcode分析:其调用sub_42e1b
实现如下:
简单分析上图不难看出,sub_519AB
应该做了“还原操作“,下面的假循环里面调用了对应地址;
分析sub_519ab
其实现开头如下:
通过fs寄存器拿 ldr_InMemoryOrderLinks
,然后做了一些条件判断(while、if 等)
简单跟踪一遍,这对while、if逻辑,其实就是特征码计算逻辑,v5本质就是一个跳转条件,配合其大小的关系和if的大小条件判断,从而控制循环流;还原之后的特征码算法如下:
1
循环读取dllname每字节的值,判断是否>0x60;大于就先-0x20:转大写, 然后减(131*v3)结果赋值v3;如果小于直接减(131*v3)结果赋值v3
python还原:
1
获取到特征码对应dll的基址之后,调用了的如下函数(sub_2A51B
即下面的重命名为get_address_bytezhenma
),将其dll基址作为第一个参数,第二个参数应该是特征码,获取到到性格三个变量,这里不难看出大概率是通过特征码+dllbase获取函数地址的操作;
上面dll特征码0x1CCA9CE6
对应的dll对应的是kernel32.dll
第一次调用get_address_bytezhenma
是获取getprocaddress
,特征码:1AB9B854
第二次调用get_address_bytezhenma
是获取loadlibrary
,特征码:7F201F78
第三次调用get_address_bytezhenma
是获取VirtualProtect
,特码码:6c6ec404
接着又是一个看似复杂的大逻辑,主要操作代码是红框里面的;
我们先看逻辑:
其实整个这大块的逻辑和上面一样就是根据特征码找dll,没找到就自己调用刚刚拿到的loadlibrary加载,然后根据指定位置存储的特征码,循环获取对应特征码的函数地址,并加密存储到指定位置;
然后我们再来看主逻辑:
里面调用的get_address_bytezhema
通过动态调试,这里是获取memmove函数的地址,对应特码:0x26A39FE2
该地址加密存储到后面指定地址,加密方式:低8位取反 and 0XCAFECAFE,全位 and 0xFFFFFFFF35013501,然后两者做or;
继续获取memset地址,特征码:0x12F66A19
加密存储到后面指定地址,
循环遍历操作,获取如下函数地址并加密存储:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Kernel32.SetErrorMode 0x33522634
Kernel32.GetCurrentProcess 0X5D7B766E
advapi32.OpenProcessTokenv 0x7920A8C8
advapi32.LookupPrivilefgeValueA
advapi32.AdjustTokenPrivileges
Kernel32.VirtualProtect
...
ws2_32.bind、recv、gethostbyname、connect等
Winhttp.WinHttpConnect等
kernel32.CreateToolhep32Snapshot\Thread32First\GetCurrentThreadId\Thread32Next\OpenThread\GetThreadCOntext
\ResumeThread\CopyFile\CreatFile\FindNextFile\CreateDirectory\MoveFile
iphlpapi.GetIpForwardTable\GetIpAddrTable\DupicateTokenEx
advapi32.GetUserNameW\GetComputerNameW\LongonUserW
kernel32.OpenProcess\DuplicateHandle\CreatePipe\TerminateProcess\ConnectNamedPipe
ntdll.NtMapViewOfSection\
Kernel32.CreateService\
...
刚开始的特征码存储:(截图此时前六个已经找到对应特征码的函数地址并加密存储)
最后存储的加密地址:
sub_519ab大致操作就是这些,返回来到sub_42e1b
:
这里一个假循环调用了一个溢出区域的函数,该函数正式还原的SetErrorMode函数,参数为2;这里应该是为什么防止用户发现windows的ui报错,从而禁止windows报错,以免在运行不成功的时候windows报错引起用户警觉;
最后来到sub_41b2b
函数,如下,先是调用sub_423bb
地址,然后又是一个循环,调用了溢出内存的地址:
sub_423bb
中异是调用了一堆溢出的地址
动态调试的时候我们可用发现,其实就是获取到刚刚加密存储的函数地址并解密调用:
解密并调用WSAStartup()
:
然后调用 sub_4EC2B
该函数,因该是一个类似解密操作拿到一个字符串:
动态调试,这里我们拿到SeDebugPrivilege字符串:
接着作为参数传入:sub_13EEB
里面
sub_13EEB
函数:
第一个溢出地址调用,调用的是kernel32.GetCurrentProcess
这里我们可用发现一个细节,该样本的函数调用,都是动态解密拿到函数地址再调用的,并且其数组顺序就是调用顺序的规律:
第一次获取WSAStartup()的时候去获取加密地址:230A54EF43B
,第二次获取GetCurrentProcess的时候获取加密地址:230A54EF443
,顺延第二个;
sub_13EEB
其实就是复制token 提权到system操作(借助微软windowsdefender 进程的高权限token):
sub_423BB
里面
后续就是实现一些功能,其中逻辑还是使用了循环混淆,然后动态运行解密相关函数调用,去做的;
之后的分析:我们直接通过上面该shellcode获取过哪些函数可以大致看出其做了哪些操作,然后对应函数断点,开展分析即可;
如,看到ws3_32以及winhttp,肯定是调用来外联的,我们直接打断点拿到c2即可(这里有一个问题,样本其实是做了反调试的,所以我们先要把检查过去,然后在打断点,具体到这个样本,我们在调用sub_519AB
之前先不要打断点,获取到相关函数地址之后再打)
拿到c2:47.93.173.165
回连url:https://47.93.173.165/api/v1/pods
0x04 分析总结
1、该shellcod的全部循环代码都做过混淆,相关逻辑循环被混淆成随机数字的大小比较逻辑来控制,十分巧妙;(应该是有相关混淆工具)
2、shellcode的apihash的生成算法没有使用已知的c2框架,而是自定义生成;
3、shellcode中相关功能代码,所有函数调用都是通过动态解密调用:通过循环遍历内置的特征码资源段使用自制的特征码计算方法,挨个加载对应dll以及遍历相关函数名称计算,拿到的后面要使用的函数真实地址,获取到的函数地址也是加密才存储,运行时动态解密调用;
4、通过widnowsdefender的MpCopyAccelerator.exe来实现白加黑劫持,相较普通白加黑劫持对抗av的效果应该会好些,因为windows df作为原生的windows av,很多av可能会对其加白来减少一些误报之类的;
5、简单的shellcode作为文件分析加载,将shellcode文件放到的用户目录下伪装为ini配置文件,这也是一些黑会场喜欢使用的操作;
0x05 攻击者画像
1、攻击者具备shellcode自研开发能力,大概率,有一套自研的c2框架;
2、攻击者具备较强的shellcode免杀能力和对抗分析的能力,常见的样本中很少有攻击组织的样本能够考虑到条件逻辑的免杀,尤其是对于一些结合al的沙箱和wd之类的,其会对条件逻辑遍历从而对抗一些样本对沙箱的逻辑检测;更有甚者会将样本的逻辑图作为查杀项之一,通过该样本的混淆逻辑判断可以成功绕过这些,并且增大的分析难度;
3、攻击者可以将免杀思路落地并开发专门的混淆工具,处理二进制文件,较强的安全工具开发能力;
结合该样本是某次演习时拿到的,以及上述相关特性,笔者认为该攻击组织大概率是国内较强红队,并且的结合其具备自研c2框架和混淆工具,至少是成体系的,所以该红队规模应该不小;范围很小了;严格意义上来说的是黑产组织的概率也不小,这里我们结合其shellcode行为(如:没有去对抗杀软,我们这里指的对抗是指没有去检测杀软,然后干掉杀软。这也是红队和黑产不同的一个主要项;即场景不同,攻击队一般来说是能够拿到项目目标av的一些情报的,又或者是可以从一次攻击中拿到,所以可以不用做上面提到的对抗,相反黑产一般又两种情况,一些比较无脑的黑产,就是堆量,上来查av,看到av就通过一些手段干掉;因为不干掉其后续的载荷大概率是要被查杀的,要做一些非常明显的风险行为;还有一种黑产,就是主打的一个稳,检测杀软,发现过不去的杀软不会去杀,而是直接退出,从而使其样本和活动的存活周期能够稍微拉长些,扯得有点远了,有机会就这个话题写篇文章)以及c2基础设施的特征,是基本可以把黑产的可能排除的;