记一次钓鱼样本分析下
sub_14000e778这个函数实现如下:
这个函数先是通过K32GetModuleInformation这个函数获取到ntdll的基址,然后遍历区块表,找到.text节,然后从文件系统中获取C:\Windows\System32\ntdll.dll文件的映射值,用这个text节的值覆盖进程中text节的值;非常经典的反监测;很多杀软都会通过在r3层hook一些关键api(一般都是inlinehook,在原始api调用的地方来个jmp),对一些关键api的调用进行监控,这里为了绕过这种类型的监控,选择将r3层的ntdll给重置,从而unhook掉杀软做的inlinehook;
待动态分析确认:sub_14000E71F 里面第三个参数是多少,srand的参数是这个;目前静态看是adaptername里面的第一个字节+111;
3、sub_14000A4CC
函数伪代码实现如下:
可以看到前面的逻辑里面都是调用sub_1400d7ed这个函数,该函数传入的参数是一个winapi的名称;
该函数的实现如下:
上图,可以看到上来就是眼熟的0x3c和0x88,从某个基址找pe头找导出表;然后就是根据函数名称表,函数地址表,函数序号表,获取到传入参数名称的函数地址,这里返回的是进程空间的绝对地址;
这里的基址是v2,v2是从sub_140018F10 这里来的,所以这里我们看下这个函数,如下图,可以看到就是peb拿ldr,再拿InMemoryOrderModuleList,再拿基址那套,获取当前进程内存加载顺序的内存加载模块列表,这里跳过了第一个模块,因为第一个模块是自己;
所以sub_14000d7ed这个函数其实就是get_apiaddressbyname;
再回过来看sub_14000A4CC,注释之后,如下图,我们可以分析出来,这里就是一个利用纤程实现的shellcodeloader,还算是比较少见的,shellcode就是从上面分析的sub1400d8a3来的,结合刚刚sub_14000d8a3分析的逻辑,是从资源段取出来了一段数据,进行了一堆操作,最后还原出的shellcode;
4、sub_14000A2FC
该函数伪代码逻辑如下,如果sub_14000a4cc没有报错或者出问题,这里显示创建了一个互斥变量,防止多实例,然后就是afx ui的一堆函数和逻辑,这里我们暂时不做关注;
三、上dbg
1、找到函数调用点
上面我们分析的这些代码,静态分析是没有直接的主函数调用的,但我们能看到的是,调用地址是在rdata段有对应记录的;这里我们先给sub_1400a2fc一个断点,从堆栈返回调用链
断点如下,(dbg里面的基址:0x7FF7C3D80000,这里正确的分析顺序一般先是用dbg打开样本,拿到基址之后,再去ida分析,ida分析rebase下基址,两边基址对齐,看起来方便点)
断下来的时候堆栈如下,
找到调用点,7FF7C3F393C9, 减基址得到偏移为:1B93c9
回到IDA,我们看下这个地址在哪,如下两图,winmain里面动态获取地址转指针调用的,afx相关编程(这里笔者对这个也不是很熟悉,不知道是编译器生成就是这里调用用户代码,还是攻击者这里是通过篡改编译器生成的代码造成,但是不管怎么样,是这里调用过去的)
2、过反虚拟机代码
断点打在dda0偏移处(上面分析的反虚拟化函数地址,最好是打在调用该函数处,因为进来之后,你还要管堆栈)
调试,断住,然后把rip置为return的值来跳过对vm的检测;
3、获取shellcode
获取网卡的guid,但是这里只了第一个字节{,加0x313131,得到0x3131ac,所以后面随机种子其实都是这个,由这个随机种子生成的随机数,就是密钥(严格意义上说是第二个密钥,由于异或解密;上面资源段拿出来后还有一个aes解密);
资源段拿出来第一次解密前:
第二次解密前:
第二次解密后,此时就是最后的shellcode;
dump下shellcode,继续调试;
这里我们这篇文章不对该攻击者shellcode做剖解分析;有机会之后再写个文章分析;(对shellcode分析是非常有必要的,有时候我们可以通过shellcode定位攻击者,不管是攻击者自己研发的远控,或者是通用远控;从其中使用的技术,我们都可以提取特征,这个特征可以是一种新型的shellcode写法,也可以是一种通用远控的新型配置,可以抽象的理解为攻击者的指纹)
4、获取c2
不对shellcode做详细分析,这里我们直接使用快速分析的方法,可以直接跑,然后上procmon监控下进程动作,注意这里把断点都清了,里面可能会有反调试操作,如下是该进程的加载的模块;我们都知道shellcode肯定是要外联的,不管你里面做了多少花里胡哨的操作,通过加载的模块,可以大致看出,外联使用的是winInet实现的和cobaltstrike类似;
接下来就直接上断点,wininet里面的关键函数:
InternetConnect
HttpOpenRequest
HttpSendRequest
然后拿到外联详情:
InternetConnect 这里可以直接看到目的域名是:static.aliyuncs.com.dsa.dnsv1.com,目的端口443;
HttpOpenRequest 里面看到,这里是get请求,请求资源是:/link/Members/C90RDRN279YK.js
从HttpSendRequest这里,我们可以看到请求头相关信息,如下和下图,其中我们可以看到此时http请求内容里面的请求头中,hos置值为了:static.aliyuncs.com;其中cookie里面的SESSIONID_P9041TWNDWNT53JA4LTXGEJNZNE3字段疑似为相关心跳源数据;
Accept: image/\*, application/json, text/html
Accept-Language: pt-br
Accept-Encoding: compress, \*
Cookie: SESSIONID\_P9041TWNDWNT53JA4LTXGEJNZNE3=BLJAEAGAHACNDJOJEDMEACFDJKJCCMNBMCEPHJLEIOHBPMACFOMELJNHLENBNOIEINLEBKFLFFNHBMCIJEMEFEGHJPHGGHHFOFGAFBMGJHBKFPOJKECMOOAPAFLDLCICOGCAANAOPELMOIBMCJJGCGFAMCBEKCJOBIBDGNMAPBKFNPPMPFHPEIPOHMFLIGBGMICLDONFGIKJGKKAMHEPJKLFBGFKFADNLLEHNOKFOLMCEMKLMLKBBDGEPHEMBDMLBHIDMMEN
Host: static.aliyuncs.com
再有就是这里用了域名前置的技术:
前置域名使用的是:static.aliyuncs.com.dsa.dnsv1.com
后置域名使用的:static.aliyuncs.com
如下是后置域名的访问量,看上去像是阿里的正规网址,其实不然,全网google、百度、搜狗、都找不到其存在的痕迹;
对域前置的对抗技术,可以参见笔者blog中的另一篇关于对于样本分析的文章
0x04 思考:
这里笔者想借助这个样本的分析,表达对于几个问题的思考
一、制作样本和样本分析的对抗
1、从样本制作的角度(攻击者):
想要对抗样本分析,很多时候是有一个短板效应的;好比这样一个问题:制造样本的时候,是否可以为了对抗分析,有什么对抗手段就都上,这样就可以层层对抗,别人更不好分析了
这个问题笔者之前的看法是,给分析者的分析阻力越大,对抗越足,这样的样本就越好;但是其实不然这个问题是有一个前提的,前提是你给的这些阻力,每个阻力之间是叠加了,并且这些阻力的力度至少是相当的,就好比一个人向着浪拍来的方向游泳,他的前方有很多层浪,他在没有穿过第一个浪的时候其实他并不知道第二个浪的样貌;当时样本对抗技术并不是这样的,样本对抗过程中,很多时候你的这些对抗技术就是一个浪,而浪也有高点和低点,而你使用的技术的对抗强度就是这个浪不同位置的高度,此时这个人想要穿过这个浪,并不需要从最高点穿越,可以直接找个最低点穿越(如果你对密码学有过了解的话,这里可以理解为后向安全性,样本中的对抗技术之间大多数并不具备前后的位置性质,更不具备后向安全性);并且有的时候,做的越多,破绽就越多;好比一句老话说的,言多必失;
你可以使用多种对抗技术,但是不要良莠不齐,最终搞成吕布骑马这种操作;所以笔者认为所有的红队,但凡你需要上样本的,最好是都能深入的学习和了解样本的免杀和对抗技术,你可以不会实现,但是你要明白你用的东西他的效果,以及他对抗的点在哪,如果只会用一些所谓的免杀工具,就非常容易搞吕布骑狗的操作;
2、从样本分析(防守者)的角度:
样本分析其实和数据分析类似,就是一个穿针引线的过程;一个**“好的”**样本(这里指有较完善的免杀和反分析手段的样本),不会轻易的让分析者,找到所谓的短板;如:笔者之前看某个apt样本,利用编译器做一些文章,将恶意代码嵌入编译器生成的代码,从而实现对抗;如果分析方法不对,很有可能就会找不到入口;所以笔者认为一个优秀样本分析工程师,需要对数据以及代码有很强的敏感度,以及胆大心细推敲,找到样本中的短板,将整个样本连根拔起;
二、相同的操作为什么要变着花样做
分析的时候我们会发现上面的样本里面,sub_14000dda0同样一个获取路径的操作,使用了不同方法去获取,甚至使用的都是一些远古系统里面使用的方法,后面的系统因为要向前兼容,所以相关方法还是可以生效;从分析的角度看,这里之所以要这么做主要是为了对抗一些杀软和沙箱,杀软、沙箱一般会对一些敏感行为、函数进行监测,但是这些监测点可能并不全,攻击者可以使用一些偏门、冷门的方法去绕过这个监测,从而使样本免于被查杀;最简单的例子就是比如杀软监控的memcpy函数,我们可以使用RtlCopyMemory来绕过检测;
0x05 狩猎
一直以来狩猎都是一个防守方的热点话题,从样本的维度看,样本是可以为狩猎提供非常丰富的素材,样本中所有使用的对抗手段,都象征着这个攻击者的特征,虽然每个对抗手段有可能是通用的,被各个攻击者都使用,但是对于这些对抗手段的组合以及一些特有的编程习惯和技术搭配却是独一无二的;例如上面这个样本我们可以拿到的特征是:
1、通过检查注册表HKCU\Software\Tencent\bugreport\WechatWindows来判断微信安装情况,反虚拟话
2、通过检查“最近”、“桌面”目录下的文件项数目来判断是否为真实环境
3、通过检查注册表HKCR\Applications\VMwareHostOpen和HKLM\SOFTWARE\Oracle\VirtualBox Guest Additions来判断当前环境是否为Vmware或VirtualBox虚拟机环境,
4、绕过r3层杀软对ntdll的监控,是通过卸载该进程ntdll里面inlinehook,还原ntdll text段内容;
5、创建互斥变量风格:类似guid格式{xxxxxxxx-xxxx-xxxxxx-xxxx-xxxxxxxxxxxx},第三部分占位6位,这里可能是攻击者自拟的某种标识符
6、通过比较古老和久远的第系统版本方法获取相关路径:SHGetFolderPathW方法和SHGetKnewFolderPath方法;(xp之前的系统使用)
7、利用随机数生成依赖随机种子,使用固定随机种子,控制随机数,从而在样本中动态获取密钥;
8、随机种子的获取的时候做了一些花里胡哨操作,获取网卡guid,但是没有使用,只使用了里面第一个字符{,这里大概率攻击者在其实现的其他样本中还有一堆其他的花里胡哨操作来获取{;
9、资源段存储shellcode,双层解密,aes+异或
10、监测到虚拟机退出,使用的结束方法是弹messagebox,内容是:“错误”
11、MFC编程,动态调用函数(这里笔者不是很确定,这里貌似是篡改了mfc编程,编译器生成的代码)
12、样本回连c2使用域前置技术,并且做了一个非常有意思的前置域和后置域的关联,看上去比较像;前置:static.aliyuncs.com.dsa.dnsv1.com ,后置:static.aliyuncs.com
13、远控心跳 url:/link/Members/C90RDRN279YK.js
14、远控元数据使用cookies里面的特殊形式的session字段承载;
还是那句话,其中的某个特征可能是很多人都用的,但是下一次如果再次出现相同的组合搭配大概率就是同一个攻击者或者同一伙攻击组织;并且里面有些项其实是富有比较特殊的“个人特征”,比如mute变量的命名,再比如利用guid首字符生成随机数,这些操作都是具备非常强的攻击者专有特征;进一步我们分析shellcode同样也可以拿到一批特征,比如shellcode里面的apicall特征码怎么计算的等,这种都是比较特殊的“个人特征”;如果我们手上有一些端侧数据,比如360安全卫士上云的数据,我们就可以去落地做一些狩猎动作;又或是我们具有很多客户,客户被打请求协助分析,我们利用这些特征可以帮助客户做一些溯源的工作,对攻击定性,对攻击者定性等;对攻击者进行深入挖掘,每个事件从都提取部分攻击者信息,最后组成一个全方面的塑形;
笔者才疏学浅,若文中存在错误观点,欢迎斧正。
参考:
样本对抗-反虚拟机
一次域前置样本分析
- 点赞
- 收藏
- 关注作者
评论(0)