欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]WannaCry深度详细分析报告(偏重策略)

[原创]WannaCry深度详细分析报告(偏重策略)

0x00. 前言

说明一下,本来应该一周前就发出来,由于某些自己的功利心作祟,导致晚了几天,惭愧!

最近,WannaCry是火了一把,到处都是分析文章,报告,解决方案等等。

趁着这个热度,我也来跟风一把。

前前后后把WannaCry详细分析了一遍。

从文件释放、启动加密器、文件加密策略、加密算法、到解密过程中所有细节进行了详尽深入的分析。

由于没有拿到初始样本,没有包含漏洞利用部分的分析。

样本信息:

MD5: 84C82835A5D21BBCF75A61706D8AB549

SHA1: 5FF465AFAABCBF0150D1A3AB2C2E74F3A4426467

CRC32: 4022FCAA

无壳 / Visual C++ 6.0

下面具体看分析内容。

0x01. 概述

  1. 样本首先通过资源释放各种文件,包括加密器、解密器、几个辅助程序、桌面背景图、说明文件、语言文件等等。
  2. 内存加载加密器模块,执行加密部分功能。
  3. 枚举目标文件(目标文件后缀列表后面给出),加密为.WNCRY文件(加密策略后面详述),删除原始文件。
  4. 复制自身为tasksche.exe,安装启动项
  5. 启动解密器

大致流程图如图:

[图片:00.png]

下面开始详细分析各个部分细节。

0x02. 释放文件

设置当前目录为工作目录,然后查找PE中资源(XIA)。

[图片:1_0.png]

直接用资源工具看一下,发现是PK开头的,多半是个压缩文件了,导出来试试。

[图片:1_1.png]

解压还要密码,看代码密码是WNcry@2ol7,解压成功。

[图片:1_3.png]

读取资源数据后,解压释放文件到当前目录。

//部分释放文件说明:

b.wnry      //桌面背景图片

c.wnry      //加密相关

msg/*.wnry  //语言相关文件

r.wnry      //@Please_Read_Me@.txt

s.wnry      //是压缩文件,打包的是Tor相关组件

taskdl.exe  //删除回收站文件

taskse.exe  //用于启动其他session的@WanaDecryptor@.exe

u.wnry      //@WanaDecryptor@.exe 解密器 

t.wnry      //解密后是加密器

在三个比特币交易地址中随机选择一个,写入c.wnry

[图片:1_6.png]

然后设置当前目录为隐藏属性,且设置为everyone可访问

[图片:1_2.png]

然后初始化Crypt相关函数,用于后面的解密操作。

开始操作文件t.wnry,看看内容,应该是个加密文件。

[图片:1_4.png]

然后通过crypt API将t.wnry解密之后(解密后是个DLL模块,dump数据后可以用于分析),映射到内存(自己loaddll),然后找到导出接口函数TaskStart调用,开始加密工作。

[图片:1_5.png]

0x03. 加密部分

TaskStart一进来,通过MsWinZonesCacheCounterMutexA的Mutex进行单示例检查,有则退出,没有继续工作。

然后是设置工作目录,读取c.wnry信息。

检查是否是SYSTEM账户。

[图片:3_0.png]

初始化Crypt相关函数,以及文件操作函数(增加一点分析成本)。

[图片:3_1.png][图片:3_2.png]

检查Global\MsWinZonesCacheCounterMutexW,Global\MsWinZonesCacheCounterMutexA\0是否存在,

存在则表示加密相关准备工作已经完成,不在进行,没有则创建Global\MsWinZonesCacheCounterMutexA\0

检查00000000.dky和00000000.pky是否存在,存在是否配对的密钥,是则加密相关准备工作已经完成,不在进行,没有则进行后续工作。

[图片:3_6.png]

如果加密相关准备工作已经完成,创建一个线程,完成如下工作(记为工作A):

  1. 如果不是管理员权限,并且不是SYSTEM账户,通过taskse.exe提权启动@WanaDecryptor@.exe,是则普通方式启动@WanaDecryptor@.exe

        [图片:3_3.png]

  1. 安装tasksche.exe启动项(注册表Run),键名随机

       [图片:3_4.png]

如果加密准备未完成,初始化密钥,保存到00000000.pky, 00000000.eky。

由于时间关系,具体加密密钥产生过程不再详述,很多分析文章说的很清楚了,本文重点不在此。

然后是如果00000000.res不存在,通过CryptGenRandom产生8字节随机值,后续会写入00000000.res

接着创建5个工作线程,完成不同的工作。

  1. 线程1每隔25秒循环写入数据到00000000.res,包括前面CryptGenRandom生成的随机值,已经更新的当前时间,直到线程退出标记为真退出

       [图片:3_5.png]

  1. 线程2每5秒检查00000000.dky和00000000.pky是否存在,存在是否配对的密钥,是则设置全局标志,然后退出线程

      [图片:3_7.png]

  1. 线程3监测新增磁盘,加密新磁盘的文件(和其他磁盘加密相同)

       [图片:3_8.png]

  1. 线程4每30秒启动taskdl.exe清除所有磁盘的回收站文件

  2. 线程5完成的也是前面提到的工作A的内容,不再详述

然后就是重点了,加密文件部分了。

加密文件部分

拷贝u.wnry为@WanaDecryptor@.exe,通过写一个bat创建@WanaDecryptor@.exe.lnk快捷方式。

[图片:3_9.png]

[图片:2_11.png]

读取r.wnry内容,生成@Please_Read_Me@.txt文件。

枚举当前用户桌面和文档目录文件,进行加密(没有设置不复写标记,删除前会复写)。

枚举All Users\Desktop和All Users\Documents,找到非当前用户目录进行加密(没有设置不复写标记,删除前会复写)。

下面记为工作B:

通过taskkill强删Microsoft.Exchange、sql和mysql进程(加密其数据)

anhkgg_CreateProc_10001080(aTaskkill_exeFI, 0, 0);// taskkill.exe /f /im Microsoft.Exchange.*

anhkgg_CreateProc_10001080(aTaskkill_exe_0, 0, 0);// taskkill.exe /f /im MSExchange*

anhkgg_CreateProc_10001080(aTaskkill_exe_1, 0, 0);// 'taskkill.exe /f /im sqlserver.exe

anhkgg_CreateProc_10001080(aTaskkill_exe_2, 0, 0);// taskkill.exe /f /im sqlwriter.exe

anhkgg_CreateProc_10001080(aTaskkill_exe_3, 0, 0);// taskkill.exe /f /im mysqld.exe

加密磁盘中文件,每个分区重复两次(会设置不复写标记,删除前不会复写)。

枚举All Users\Desktop目录,复制b.wnry到目录中为@WanaDecryptor@.bmp,设置桌面背景为@WanaDecryptor@.bmp,

执行@WanaDecryptor@.exe co

更新00000000.res

cmd.exe /c start /b @WanaDecryptor@.exe vs

每个磁盘(fixed)创建x:/$Recycle/hibsys.WNCRYT(系统盘写在temp目录,x:/$Recycle被设置为系统隐藏属性),读取分区可用空间大小,大于0x40000000(1GB)的话,每10微秒循环写入0xa00000个字节的'U',写20次,然后删除该文件,并且设置了重启后删除。

每隔60s重复工作B,直到退出标志为真。

文件枚举

枚举文件采用方式为:

  1. 枚举当前目录中所有文件(排除文件看下文),加入文件链表,记录所有子目录(排除目录看下文)到目录链表。

  2. 本目录文件有加密操作(具体看下文)

  3. 分析目录层级,少于等于6层的,拷贝lease_Read_Me@.txt到目录,5-6层的拷贝@WanaDecryptor@.exe.lnk,1-4层拷贝@WanaDecryptor@.exe到目录。

  4. 然后遍历目录链表,枚举子目录,重复1操作。

  5. 子目录枚举完成,所有文件记录到链表,进行后续操作。

目录和文件采用相同的链表结果,总结如下:

struct FILE_LIST_CONTEXT{

    DWORD vtable;

    FILE_LIST *list;//

    DWORD file_count;//8

}

struct FILE_LIST{

    FILE_LIST* prev;

    FILE_LIST* next;

    FILE_INFO file;//

}

struct FILE_INFO{

    WCHAR path[0x168];//

    WCHAR name[0x104];//2d0

    DWORD nFileSizeLow;//4d8

    DWORD nFileSizeHigh;//4dc

    DWORD type;//4e0  FILE_TYP

}//0x4e4

排除目录

枚举子目录时,会跳过如下目录(保证系统正常工作):

\Intel 

\ProgramData

\WINDOWS

\Program Files

\Program Files (x86)

\AppData\Local\Temp

\Local Settings\Temp

This folder protects against ransomware. Modifying it will reduce protection

Temporary Internet Files

Content.IE5

文件分类

枚举文件时,首先跳过 @Please_Read_Me@.txt,@WanaDecryptor@.exe.lnk, @WanaDecryptor@.bmp

然后检查文件类型,跳过0,1,6类型文件,其他文件加入链表。

具体类型如下:

0 没有后缀以及其他类型后缀

1 .exe, .dll

4 .WNCRYT 

5 .WNCYR

6 .WNCRY

2.

".doc"".docx"".xls"".xlsx"".ppt"".pptx"".pst"".ost"".msg"".eml"".vsd"".vsdx"

".txt"".csv"".rtf"".123"".wks"".wk1"".pdf"".dwg"".onetoc2"".snt"".jpeg"".jpg"

3. 

".docb"".docm"".dot"".dotm"".dotx"".xlsm"".xlsb"".xlw"".xlt"".xlm"".xlc"".xltx"".xltm"".pptm"".pot"".pps"".ppsm"".ppsx"".ppam"".potx"".potm"

".edb"".hwp"".602"".sxi"".sti"".sldx"".sldm"".sldm"".vdi"".vmdk"".vmx"".gpg"".aes"".ARC"".PAQ"".bz2"".tbk"".bak"".tar"".tgz"".gz"".7z"".rar"

".zip"".backup"".iso"".vcd"".bmp"".png"".gif"".raw"".cgm"".tif"".tiff"".nef"".psd"".ai"".svg"".djvu"".m4u"".m3u"".mid"".wma"".flv"".3g2"".mkv"

".3gp"".mp4"".mov"".avi"".asf"".mpeg"".vob"".mpg"".wmv"".fla"".swf"".wav"".mp3"".sh"".class"".jar"".java"".rb"".asp"".php"".jsp"".brd"".sch"

".dch"".dip"".pl"".vb"".vbs"".ps1"".bat"".cmd"".js"".asm"".h"".pas"".cpp"".c"".cs"".suo"".sln"".ldf"".mdf"".ibd"".myi"".myd"".frm"".odb"".dbf"

".db"".mdb"".accdb"".sql"".sqlitedb"".sqlite3"".asc"".lay6"".lay"".mml"".sxm"".otg"".odg"".uop"".std"".sxd"".otp"".odp"".wb2"".slk"".dif"".stc"

".sxc"".ots"".ods"".3dm"".max"".3ds"".uot"".stw"".sxw"".ott"".odt"".pem"".p12"".csr"".crt"".key"".pfx"".der"

总结为下面的enum

enum FILE_TYPE

{

    FILE_TYPE_NULL = 0,

    FILE_TYPE_EXEDLL,

    FILE_TYPE_DOC,

    FILE_TYPE_DOCEX,

    FILE_TYPE_WNCRYT, //.wncryt

    FILE_TYPE_WNCYR, //.wncyr

    FILE_TYPE_WNCRY //.wncry

}

文件加密策略

加密文件函数中有个参数,我取做cmd(取值是1-4)。因为不同的值会有不同的操作方式。

根据cmd和文件类型和大小等等,函数sub_10002E70返回不同的操作方式。

1. cmd>=4, FOT_ENCRYPT_NORMAL_4

2. cmd<=3,FILE_TYPE_NULL,FOT_NULL_1 

3. cmd==3, 非FILE_TYPE_NULL,FOT_ENCRYPT_NORMAL_4

4. cmd<=2, .wncyr, FOT_NULL_1

5. cmd<=2, .wncryt, FOT_DELETE_FILE_2

//用于枚举中的操作,直接操作普通文件(不加入链表)和大文件.doc(加入链表),小文件.doc,.docex加入链表,其他文件不加入链表

//枚举中完成加密操作的文件不加入链表了

6. cmd==1, .doc, 大文件, FOT_ENCRYPT_WRITESRC_3 //也要加入链表

7. cmd==1, .doc, 普通文件, FOT_ENCRYPT_NORMAL_4

8. cmd==1, .doc, 小文件,FOT_NULL_1

9. cmd==1, .docex, FOT_NULL_1

10. cmd==2, .doc, FOT_NULL_1

11. cmd==2, .docex, 大文件, FOT_ENCRYPT_WRITESRC_3

12. cmd==2, .docex, 小文件,FOT_NULL_1

13. cmd==2, .docex, 普通文件,FOT_ENCRYPT_NORMAL_4

其他返回FOT_NULL_0

上面提到的大文件,普通文件,小文件定义如下:

小于0x400的是小文件,大于0xC800000的是大文件,中间的是普通文件

[图片:4_0.png]

上面提到的作方式具体定义如下:

//返回0表示未作处理,或者处理未完成,需要插入链表或者不从链表中删除

enum FILE_OP_TYPE{

    FOT_NULL_0 = 0,     //0 未操作,返回1

    FOT_NULL_1,         //1,default 未操作,返回0

    FOT_DELETE_FILE_2,    //2 //删除文件,返回1

    FOT_ENCRYPT_WRITESRC_3, //3 改源文件,返回0

    FOT_ENCRYPT_NORMAL_4, //4 只加密,返回1

}

代码如下:

[图片:4_1.png]

对加密策略做一下总结:

  1. 在枚举文件中,cmd=1,会对普通文件直接加密为.WNCRY,不再加入链表,大文件处理为.WNCYR,以及其他未作处理文件继续加入链表等待处理。

[图片:4_2.png]

  1. 枚举完成后,cmd从2-4,每个cmd遍历都遍历加密文件。
  • cmd=2,加密FILE_TYPE_DOCEX普通文件为.WNCRY(移出链表),以及FILE_TYPE_DOCEX大文件为.WNCYR。
  • cmd=2, 删除.WNCRYT
  • cmd=3, 加密链表中所有文件(移出链表)
  • cmd=4, 加密可能剩余链表中的文件

[图片:4_3.png]

文件内容加密过程

验证文件是否未加密,或者未加密完成。已完成加密,直接退出。

[图片:4_5.png]

对于FOT_ENCRYPT_WRITESRC_3,按写打开源文件,将文件头0x10000字节内容移动到尾部,头部内容清零,写入加密文件头部数据,然后源文件移动为.WNCYR,完成退出。

[图片:4_4.png]

对于FOT_ENCRYPT_NORMAL_4,按读打开源文件,对于普通文件进行随机值检查,满足100倍数,且文件数据小于10,那么换本次加密算法为免费解密的算法,标记,加密完成后调用回调函数写入f.wnry中。

[图片:4_6.png]

[图片:4_7.png]

加密前,将文件后缀加上T变成.WNCRYT,然后创建文件。

写入加密文件头部数据

[图片:4_8.png]

//加密文件头部数据结构

struct {   

 char magic[8];//WANACRY!'

    int size;//0x100

    char key[size];//

    int type;//加密文件类型3,4

    __int64 datasize;// <=0x6400000 源文件大小

    char data[1];//

    }

对于.WNCYR文件(FOT_ENCRYPT_WRITESRC_3处理过一次),读取尾部0x10000的数据加密写入文件。

[图片:4_9.png]

然后每0x1000读取加密,写入.WNCRYT文件,循环直到所有数据加密。移动.WNCRYT为.WNCRT。

[图片:4_10.png]

对于FOT_ENCRYPT_NORMAL_4,加密完成后会将源文件加入删除链表,在删除线程中文件会被复写删除。

复写通过生成随机值或者一片'U',循环写入文件,细节不再阐述(桌面我的文档目录文件目录会被复写,其他目录文件不会)。

总结

至此,wannacry大部分内容都分析完成,由于时间精力的关系,后续解密器就不再分析了。

博客原文: https://anhkgg.github.io/wannacry-analyze-report/


注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功