标题 | 简介 | 类型 | 公开时间 | ||||||||||
|
|||||||||||||
|
|||||||||||||
详情 | |||||||||||||
[SAFE-ID: JIWO-2024-30] 作者: ecawen 发表于: [2017-07-09] [2017-07-09]被用户:ecawen 修改过
本文共 [1237] 位读者顶过
0x0 写在前面[出自:jiwo.org]
下面就是详细的分析流程:
0x2、相关文件
0x3、行为预览
0x4、报告正文
分析过程: (1)首先需要写个dllload加载该样本并且调用1号导出函数:
(2)提升进程权限,如果提升成功则保存到一个全局变量作为标记:
(3)遍历当期进程列表,判断是否有预期的3个进程在运行,该样本通过自定义的算法将进程字符串计算后得出一个DWORD数值,
经过分析这3个DWORD数值分别对应杀软:
(4)读取自身数据到堆buffer,并且保存buffer首地址以及文件大小到全局变量:
2、拷贝自身pe数据到堆buffer中,并且修复重定位,然后流程转移到堆中执行代码,接着卸载掉样本自身的主模块,
(1)申请堆空间,拷贝自身代码,修复重定位,流程转移:
(2)卸载自身主模块,删除自身文件然后调用导出函数1:
3、调用WSAStartUp初始化,检查c:\\windows目录是否存在自身样本文件,如果存在则退出进程:
(2)检查c:\\windows目录下是否有样本自身的文件,如果存在则结束进程,不存在则创建文件:
4、篡改硬盘mbr代码: (1)如果debug权限提升成功,则进行篡改mbr:
(2)打开c盘驱动设备,获取磁盘信息得到扇区大小,然后根据该大小乘以10申请buffer,将buffer写入到第二个扇区中:
(3)判断卡巴斯基进程是否存在 如果存在则不执行mbr篡改: (4)获取系统所在的盘符,然后查询该盘符对应的物理磁盘驱动器编号: 4.1)获取系统路径:
4.2)覆盖后得到系统所在盘符的符号链接:
4.3)打开系统盘符号链接,获取该盘所在的物理磁盘编号,然后将该编号数值转为字符串:
4.4)拼接出完整的物理磁盘符号链接。拷贝到参数指向的buffer内,作为传出数据:
(5)检查\\.\PhysicalDrive0磁盘设备的分区类型是否为MBR,如果不是则不执行篡改代码: 磁盘分区类型:
(6)生成60个字节的随机数,然后按字节取余0x3A,得出的值作为一个全局数组的下标,用该下标访问,拼接出一个疑似序列号的字符串:
最终生成的序列号:
(7)读取PhysicalDrive起始扇区的mbr引导代码进行异或加密:
加密前的起始扇区数据:
异或加密后的数据:
接着将一个大小为0x200的栈buffer全部初始化为0x7:
然后分别生成了两个32个字节和8字节的随机数,这两个随机数分别是salsa20算法的key以及iv,在MBR代码里面会运用到Key和iv来进行MFT加密:
接着拷贝了一串字符串到栈buffer里,这段字符串为比特币钱包地址:
(8)申请分别申请两块内存,大小分别是0x200和0x22B1,然后分别拷贝样本自身的mbr代码到这两个buffer内:
(9)循环写入样本的mbr代码,长度为19个扇区:
篡改前的代码:
篡改后的代码:
(10)然后将之前通过60字节随机数当做下标生成的序列号字符串、以及用来加密MFT的32字节的key和8字节的iv、 还有样本内置的字符串数据(经后面的分析得知该串为比特币钱包)写入第32个扇区:
(11)将之前初始化全是0x7的buffer写入第33个扇区:
(12)将加密后的起始扇区mbr引导代码写入第34个扇区:
5、创建重启的任务计划: 该任务计划是在样本运行之后一个小时进行重启:
6、样本自身的传播与远程执行 首先该样本通过三种途径传播自身:
(1)创建线程,进行可攻击ip的勘测,首先样本首先会调用同一个函数初始化两个0x34大小的结构,接下来会对该结构进行分析说明:
结构初始化函数:
经过分析还原出如下结构体:
调用该函数初始化的结构体,作用是用来保存一些信息,这些信息用来后续的自身传播以及远程执行,接下来经过实例来说明该结构的作用:
1.1) 首先样本拿到了之前初始化好的结构,然后调用函数,参数分别是一个ip地址、然后是一个常量值、接下来就是结构的首地址,
1.2)10006FC7函数分析:该函数将参数1的字符串拷贝到栈内,然后调用函数10007298, 参数分别是结构首地址、拷贝到栈内的字符串、以及外面参数2的常量值:
1.3)10007298函数分析,由于该结构内有临界区对象,造成idaF5错乱,所以下面贴出反汇编代码
接下来判断m_pppPointerArray数组的当前下标是否已经超出最大值(m_IndexRange) 如果超出则不添加:
然后申请8字节大小的堆内存,如果申请成功,则将该内存首地址根据m_CurrentIndex下标保存在m_pppPointerArray数组中,并且这个堆内存是算是个二级指针:
然后再次申请堆内存,大小为结构中的m_remote_buffer_size成员,这次申请的堆内存是用来保存参数2的字符串,
然后将参数3的常量值,这里暂时看作为flag,将这个常量值保存在第一次申请的8个字节堆内存首地址+4处:
接着拷贝参数2的字符串到第二次申请的堆buffer中:
到此一个新的信息就添加完毕了,接下来用od调试一下上述的过程,
参数:
接下来在内存中查看该结构的分布情况:
根据上面静态分析添加远程传播执行所需信息的过程,首先m_pppPointerArray中保存了一个8字节大小的堆buffer地址:
然后继续查看这个8字节大小的buffer:
继续查看第二次申请的buffer:
可以看出该buffer保存了参数中传进来的ip地址信息。
tag_remote_penetration_info结构分析总结:该样本中大量运用了这个结构,该结构用来保存各种样本后续传播感染所需要的信息,
(2)获取本机NetBios名称,以及回环地址、loaclhost等字符串信息拷贝到tag_remote_penetration_info结构中:
(3)获取本机网络适配器信息链表,遍历该链表将所有适配器对应的ip地址以及dhcp服务器地址保存在tag_remote_penetration_info结构中: (4)检查当前系统是否是域控制器或者是Server,如果是则枚举dhcp内网池中的ip地址,保存在tag_remote_penetration_info结构中:
(5)计算出本机ip的ip段范围,例如本机ip为192.168.1.111,则计算的范围就是192.168.1.0 - 192.168.1.255:,计算出这个范围后创建线程,
(6)接着死循环分别调用函数来进一步获取可攻击的目标:
上述的各步骤勘测出的一些ip全部都加到tag_remote_penetration_info结构中, 该结构也就充当了一个可感染的ip列表,之后的远程传播以及执行代码则会用到这个ip列表。
(7)加载1号资源,解密资源数据为一个pe文件,接着释放并执行该pe文件,这个程序是类似mimikatz的系统密码抓取工具,并且该工具的输出进行了管道重定向, 创建进程: 创建线程:
(8)加载3号资源,解密资源数据,3号资源保存的pe数据为psexec远程命令执行工具:
(9)新申请一个局部tag_remote_penetration_info结构:
(10)枚举系统凭据,并且将TERMSRV类型,也就是远程桌面登录的凭据过滤出来,保存其TargetName以及远程登录的系统账户密码,
(11)接下来程序将利用远程桌面的登录凭据尝试远程连接主机,进行传播自身,并且通过wmic或psecex进行远程执行,
可以看出,将自身文件传播到远程主机以后,构造两种远程执行的命令,同样利用rundll32去加载自身样本。 远程执行:
Psexec命令:Dllhost.dat \\TargetName -accepteula -s -d C:\\Windows\\System32\\rundll32.exe \"C:\\Windows\\petya.dll\",#1
(12)利用之前获取到的攻击ip列表(可以连接上445、139端口的ip)进行永恒之蓝漏洞传播:
7、文件加密 (1)首先样本会获取系统所有的盘符,然后进行循环遍历盘符,判断盘符类型是否是非移动存储设备时,则开启线程进行加密:
(2)文件加密过程
2.2)通过密钥容器句柄获取AES128密钥,保存在回调参数的buffer+0x14偏移处:
2.3)开始递归遍历文件,递归层数为0xF,如果文件夹深度大于0xF则退出递归,然后判断文件是否是要加密的文件格式,如果是则进行加密:
(3)加密流程:样本针对每个盘符申请一个AES128密钥 ---> 用该密钥加密文件 ---> 接着用样本内置的RSA公钥去加密AES128密钥 --->将加密后的AES128密钥保存在文件中
3.2)利用RSA公钥加密AES密钥:
8、保存说明信息到加密盘符的根目录
9、样本篡改的MBR代码分析:
(2)调用int 10中断,设置一些屏幕显示模式等信息:
(3)调用int 13中断 42h功能号,读取0x20扇区:
经过之前的分析,该扇区存放着salsa算法的key和iv,以及比特币钱包,随机生成的用户序列号等:
(4)通过检查0x20扇区首字节,判断加密标记,如果为1,则代表已经完成加密,直接显示勒索信息,如果为0,则执行加密流程:
(5)调用int 10中断,显示病毒伪装的磁盘检查界面:
(6)将加密标记设置为1,然后拷贝0x20扇区buffer的salsa key到栈buffer内,然后抹掉原buffer内的salsa key,防止用户使用该key解密MFT:
(7)将已经设置加密标记以及抹掉了salsa_key的扇区buffer数据,在写回0x20扇区:
(8)读取0x21扇区数据,然后调用salsa加密该扇区数据,加密完成后写回磁盘:
数据buffer:
加密函数调用:
参数: 加密后的Buffer:
然后写回0x21扇区:
(9)读取0x22扇区的数据,该扇区保存了mbr引导扇区加密后的数据,然后在循环单字节异或0x7解密mbr引导扇区代码:
解密mbr引导扇区:
(10)遍历MBR引导扇区内的分区表结构,进行判断分区类型、以及保存引导扇区起始到磁盘扇区起始的相对偏移量、以及每个分区的扇区总数:
(11)通过扇区起始的相对偏移量0x3F,也就是c盘分区的起始扇区号,读取该扇区号的数据,该扇区保存了c盘分区的NTFS结构:
Buffer数据:
(12)通过(11)步骤得到的NTFS结构,取出DBR结构中的MTF起始簇号*每个簇单位的扇区数 得到一个扇区号,然后用该扇区号+0x3F定位到MFT表所在的扇区位置:
(13)读取MFT扇区表:
(14)调用int10中断显示磁盘检查进度:
(15)循环遍历读取MFT表,通过检查MFT的FILE标记判断该表是否有效:
(16)如果15步骤的检查通过,则开始遍历MFT表中的属性结构,遍历每个属性结构的属性类型,如果具有属性类型为0x30,
(17)一个MFT结构加密完成后,则读取下一个MFT表,在重复执行(13)--(16)步骤:
|