前言
NotPetya是源自类似Petya的全新形式勒索病毒,可以将硬盘整个加密和锁死,从内存或者本地文件系统里提取密码。[源自于百度百科]
一、目录
- 1.目录
- 2.样本信息
- 3.行为分析
- 4.样本分析
- 5.技术总结
二、样本信息
- 1.样本名称:efegfeisjwi.exe
- 2.样本md5:71b6a493388e7d0b40c83ce903bc6b04
- 3.是否加壳:无壳
- 4.编译语言:vc++
- 5.样本来源:来自于网络收集
三、行为分析
行为分析:
四、样本分析
模块1:感染初始化
- 概括
- 提升权限,需要将进程权限提高到关机权限,调试权限,操作系统级权限
- 排除指定的安全软件进程
- 将装载器读入进程堆空间
模块2:隐匿自身
- 将自身复制到进程空间
- 设置堆的保护属性
- 卸载自身dll,删除dll文件,达到隐藏自身的目的
模块3:恶意破坏
- 使用调试权限,破坏MBR
- 搜索之前的文件是否存在,如果存在退出进程,否则重新创建新的
- 修改C盘前10个扇区内存
- 修改MBR设备文件
- 产生随机码并写入MBR
- 加密MBR数据,对MBR0x200字节进行xor 0x7操作
- 产生随机码并写入MBR
模块4:设置定时任务
- 获取shutdown.exe的路径,利用system权限创建定时任务,任务为重启,时间为在当前时间后1hour
模块5:获取IP表
- 复制本地计算机IP到IP地址表
- 将获取到的适配器和IP地址以及DHCP地址对应起来
- 判断系统是否是DHCP服务器
- 获取子网中的IP地址,并将IP放在IP表中
- 利用枚举出来的IP表,暴力链接目标IP的445和139端口,将可以利用IP保存起来
- 利用TCP节点表获取目标的IP
模块6:释放密码抓取程序
- 释放资源文件到临时目录
- 将CLSID作为管道名称创建管道,利用之前释放的资源文件获取用户密码,然后通过管道,交给后续远程登录机器。
- 创建刚刚释放的文件GetPasswd.exe进程。获取用户密码,然后与远程登录进程共享。
- 删除刚刚释放的文件,保证不被查杀
模块7:释放远程执行程序
- 释放PsExec文件
模块8:远程加载恶意dll
- 枚举网络资源,获取用户登陆凭证,收入密码表。创建网络连接,利用Psexec和wmic远程执行命令
- 枚举网络资源。
- 获取用户的登录凭证,排除TERMSRV,后面的字符就是允许保存计算机远程终端凭证
- 将IP表和登录凭据表对应
- 创建网络连接,检查之前释放的Psexec文件是否存在,不存在重新写入文件
- 利用Psexec远程执行恶意dll
- 利用wmic远程执行恶意dll
- 创建上传命令的进程
模块9:永恒之蓝漏洞传播
- 利用永恒之蓝和永恒浪漫传播
模块10:加密文件
- 理论上判断所有硬盘,使用RSA和AES加密。
- 遍历目录,除了C://windows目录不加密,加密后缀为如下:
<3ds.7z.accdb.ai.asp.aspx.avhd.back.bak.c.cfg.conf.cpp.cs>
<.ctl.dbf.disk.djvu.doc.docx.dwg.eml.fdb.gz.h.hdd.kdbx.mai>
<l.mdb.msg.nrg.ora.ost.ova.ovf.pdf.php.pmf.ppt.pptx.pst.pv>
<i.py.pyc.rar.rtf.sln.sql.tar.vbox.vbs.vcb.vdi.vfd.vmc.vmd> <k.vmsd.vmx.vsdx.vsv.work.xls.xlsx.xvd.zip.>
- 根据文件大小,使用不同的加密策略
- 利用文件映射的方式使用AES加密方式进行文件加密
- 创建勒索提示信息README
加密过程
- 生成AES加密秘钥对
- 利用AES加密文件
- 导入内置的RSA公钥
- 利用RSA公钥加密AES秘钥,并导出
- 写入AES秘钥
模块11:清除日志
- 利用cmd调用wevtutil清除相关日志信息
模块12:诱发蓝屏
- 调用NtRaiseHardError诱发蓝屏
五、技术总结
隐匿自身
这一类勒索病毒(GrandCrab,NotPetya)都有着很强的隐匿手段,而且采用的并不是普通的隐匿手段(DLL注入),而是将PE文件直接写入内存,然后修正导入表实现的。这样可以实现文件不落地,避免被查杀。
- 获取文件MZ头,并读取到进程空间
- 搜索重定位表
- 根据PE结构的相关知识,可得知
SectionHeader = *(_WORD *)(this + 20) + this + 24;// NtHeader
其实是获取节区头。 - 然后获取了节区的数目,
NumberOfSection = *(_WORD *)(this + 6); // NumberOfSection=NtHeader+6
- 接着遍历节区,目的是为了获取reloc节区
- 根据PE结构的相关知识,可得知
- 卸载自身,将源文件写入全零,然后删除自身文件(此时代码在进程中执行)
- 接着修复导入函数地址表
- 最后跳转到新的函数入口点