工具列表
Detect It Eas2.04:是一个多功能的PE-DIY工具,主要用于壳侦测.
IDA pro
Hash值校验工具
Resource Hacker
PEid
010Edit
Windows7
WannaCry
WannaCry(又叫Wanna Decryptor),一种“蠕虫式”勒索病毒软件,大小3.3MB,由不法分子利用NSA(National Security Agency,美国国家安全局)泄露的危险漏洞“EternalBlue”(永恒之蓝)进行传播 。勒索病毒肆虐,俨然是一场全球性互联网灾难,给广大电脑用户造成了巨大损失。最新统计数据显示,100多个国家和地区超过10万台电脑遭到了勒索病毒攻击、感染。 勒索病毒是自熊猫烧香以来影响力最大的病毒之一。
攻击特点
WannaCry利用Windows操作系统445端口存在的漏洞进行传播,并具有自我复制、主动传播的特性。
被该勒索软件入侵后,用户主机系统内的照片、图片、文档、音频、视频等几乎所有类型的文件都将被加密,加密文件的后缀名被统一修改为.WNCRY,并会在桌面弹出勒索对话框,要求受害者支付价值数百美元的比特币到攻击者的比特币钱包,且赎金金额还会随着时间的推移而增加。
常用的Office文件(扩展名为.ppt、.doc、.docx、.xlsx、.sxi)
并不常用,但是某些特定国家使用的office文件格式(.sxw、.odt、.hwp)
压缩文档和媒体文件(.zip、.rar、.tar、.mp4、.mkv)
电子邮件和邮件数据库(.eml、.msg、.ost、.pst、.deb)
数据库文件(.sql、.accdb、.mdb、.dbf、.odb、.myd)
开发者使用的源代码和项目文件(.php、.java、.cpp、.asp、.asm)
密匙和证书(.key、.pfx、.pem、.p12、.csr、.gpg、.aes)
美术设计人员、艺术家和摄影师使用的文件(.vsd、.odg、.raw、.nef、.svg、.psd)
虚拟机文件(.vmx、.vmdk、.vdi)
样本概况
文件:WannaCry.exe
大小:3.55MB
修改时间:2017年5月13日
MD5:DB349B97C37D22F5EA1D1841E3C89EB4
SHA1:E889544AFF85FFAF8B0D0DA705105DEE7C97FE26
CRC32:9FBB1227
SHA256: 24D004A104D4D54034DBCFFC2A4B19A11F39008A575AA614EA04703480B1022C
查壳
Detect it Easy 3.01
PE文件格式:PE文件是Windows操作系统下使用的可执行文件格式,它是微软在UNIX平台的COFF基础上制作而成的。
病毒使用VC6++无壳
常见壳:
1、加密壳--最常见壳,通过多种措施对源程序进行加密。
2、压缩壳--常见UPX,主要为了压缩程序的体积。
3、伪装壳--直译进行壳与壳的模拟、进行混淆。
4、虚拟机壳--使用虚拟机执行代码(a隐藏加解密过程,b执行自定义字节)
加壳无非为了保护内部的软件代码被篡改、破解,使用方法就是混淆程序的入口点。
查看字符串信息
从中能够看到调用的函数信息,了解大致功能,能够看到文件操作,和资源载入等操作,创建互斥体,载入的dll文件,识别加密的文件后缀名,执行的cmd命令attrib -h设置了隐藏文件
识别加密算法
字符串中识别到了用于加密的标准库函数 那么在这里我使用PEID的Kyrpto ANALyzer插件扫描病毒程序 来识别加密算法 扫描结果如图所示
ADLER32:Adler-32是Mark Adler发明的校验和算法,和32位CRC校验算法一样,都是保护数据防止意外更改的算法,但是这个算法较容易被伪造,所以是不安全的保护措施。但是比CRC好点的是,它计算的很快。这个算法那是从Fletcher校验和算法中修改过来的,原始的算法形式略快,但是可依赖性并不高。
Rijndael是由比利时密码学家设计的分组密码算法,于2000年被选为新一代的标准密码算法——AES。
由上图可知 病毒使用了CRC32和AES加密算法 其中CryptDecrypt和CryptDecrypt是微软提供的用于一个用于加密的类库 而ZIP2和ZLIB是压缩算法.
查看导入表
KERNEL32.DLL:内核相关
WS2_32.dll:网络相关
Iphlpapi.dll:网卡相关
WININET.dll:HTTP相关
在Kernel32的导入函数里发现了 LoadResource LockResourse FindResourceA 等函数 说明资源段里可能会大有文章,还有创建互斥体运行单一实例的常见病毒行为操作。
kernel32.dll功能介绍
kernel32.dll是Windows中非常重要的32位动态链接库文件,属于内核级文件。它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
使用火绒剑观察行为
查看进程树
首先使用火绒剑对进程进行监控,然后运行病毒程序(先对虚拟机进行快照)
注册表监控
关于注册表 这里我使用regshot对运行病毒前后做一个快照进行比对 直接查看结果。
文件监控
释放了tasksche.exe可执行文件,通过此处的路径可以提取到taskeche.exe文件,是后期分析的重要文件之一
在每个目录之下创建@WanaDecryptor@.exe,@Please_Read_Me@.txt以及一个bat批处理文件,对文件进行了感染
分析监控到的日志,主要观察的点:
①文件操作,主要看文件创建、修改、删除等操作FILE_truncate:文件截断
FILE_write:文件写入
FILE_modified:文件修改
FILE_read:文件读取
FILE_open:文件打开
FILE_touch:创建文件
FILE_readdir 遍历目录
②注册表操作,主要看注册表设置、创建等操作REG_openkey:打开注册表键
REG_getval:获取注册表值
REG_setval:设置注册表值
REG_RAVAL:删除注册表信息
REG_mkkey:创建注册表键
③进程操作,主要看创建进程、写入内存等操作EXEC_destory:进程退出
PROC_exec:创建进程
EXEC_create:进程启动
④网络操作,主要看网络连接地址、IP等信息
⑤其他行为,以及观察病毒样本运行后的反应BA_extract_hidden:释放隐藏文件
BA_exec_extractfile:启动自释放文件
l网络监控
从网络监控可以看到 病毒尝试连接一些ip发送信息,企图向局域网扩散
分析情况总结:
分析监控的日志以及自行观察操作之后,可以分析出样本的恶意行为:
- 自我复制样本到C盘:C:\ProgramData目录下,启动C:\ProgramData\@WanaDecryptor@.exe(即病毒程序)
- 释放了并运行了taskeche.exe程序
3.在程序目录下创建@Please_Read_Me@.txt、@WanaDecryptor@.exe以及
.WNCRY文件
4.在C:\ProgramData目录下创建xxx文件夹(文件名随机)
5.设置注册表启动项为"C:\ProgramData\znemvazsnwpqy217\tasksche.exe"
6.自己创建了一些注册表的项,在其中写入了很多信息
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Tracing\WannaCry_RASAPI32
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Tracing\WannaCry_RASMANCS
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows NT\CurrentVersion\Network\Location Awareness
7.随机向局域网内的445端口发起网络连接,尝试进行传播
使用IDA对病毒主程序WannaCry.exe文件进行静态分析
由于静态分析以后所有函数名称全部丧失,对于具体函数作用的判断,需要结合能够解析出函数名的windows函数进行判断;(Fn+F5)
WinMain
InternetOpenA:初始化应用程序对 WinINet 函数的使用。
InternetOpenUrlA:打开由完整的 FTP 或 HTTP URL 指定的资源。
InternetCloseHandle:关闭Internet句柄
本函数主要操作就是从上述url中尝试获得资源,如果执行失败,则执行Sub_408090
Sub_408090-》ProgramBegin
GetModuleFileNameA:检索包含指定模块的文件的完全限定路径
DWORD GetModuleFileNameA( [in, optional] HMODULE hModule, [out] LPSTR lpFilename, [in] DWORD nSize ); 如果HMODULE hModule参数为 NULL, GetModuleFileName 将检索当前进程的可执行文件的路径。
OpenSCManager:函数建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库,如果指针为 NULL 或指向空字符串,则该函数将连接到本地计算机上的服务控制管理器。如果为 NULL,则默认打开SERVICES_ACTIVE_DATABASE数据库。即打开本地计算机服务控制管理器,开启SERVICES_ACTIVE_DATABASE数据库隐式,指定SC_MANAGER_CONNECT访问权限
OpenServiceA:打开现有服务。
CloseServiceHandle:关闭服务控制管理器或服务对象的句柄。
startServiceCtrlDispatcherA:将服务进程的主线程连接到服务控制管理器,这会导致线程成为调用进程的服务控制调度程序线程。
1、检索当前进程的可执行文件的路径
2、判断参数个数,个数小于2执行sub_407F20
3、建立本地计算机上服务控制管理器的链接,如果建立成功则开启服务,服务名为ServiceName
4、开启服务成功则执行Sub_407FA0,关闭服务句柄,失败则直接关闭句柄
5、建立指定服务,服务名称为ServiceName,入口函数为sub_408000
目标:判定服务是否存在,如果不存在则创建指定服务,将服务信息加入到SERVICE_TABLE_ENTRYA中
Sub_407F20-》ConnectFunc
该函数没有操作,仅仅调用了sub_407C40和sub_407CE0
sub_407C40->ChangeProcessconfig
函数功能为以服务的方式启动自身,且函数内部将参数变为3个,使得判断信息改变,下一次由于函数参数的改变,会进入到sub_407FA0判断条件中去
sub_407CE0->
其函数功能为加载资源并在系统目录C:\WINDOWS\下创建tasksche.exe程序启动,且将其移动到C:\WINDOWS\qeriuwjhrf中
sub_407FA0->ChangeServiceConfig
ChangeServiceConfig2A:更改服务的可选配置参数。
此函数功能比较简单,就是更改服务的可选配置参数。
sub_408000->SpreadToInternet
函数功能为实现病毒网络传播,其中主要利用445端口,获取局域网网IP地址,攻击局域网;构造随机的外网地址,测试是否能连接外网445端口,如果连接成功,则进行攻击
RegisterServiceCtrlHandlerA:注册用于处理服务控制请求的函数。
SetServiceStatus:汇报调用服务的服务控制管理器的状态信息。
sub_407BD0()-》GetAttack
此函数内拥有三个函数,sub_407B90函数功能为获取一个密钥容器 CSP,将PE文件加载到内存中;sub_407720函数为开启局域网漏洞攻击;sub_407840函数为随即攻击外网服务IP地址。
sub_407B90->InitInternet
在初始化网络环境后会判断返回值,如果成功则返回0,关键的执行函数为sub_407620函数与sub_407A20函数
sub_407620->getKeyContenter
获取一个密钥容器:
CryptAcquireContext :
这个函数用来请求一个给定密钥容器的句柄,这个容器属于给定的CSP的。我们可以用这个句柄来调用这个CSP。这个函数可以执行两项功能:一是可以用来寻找一个由参数dwProvType和参数pszProvider所指定的CSP,如果这个CSP被找到,我们希望能从这个CSP中找到一个由参数pszContainer所指定的密钥密钥容器;二是在标志位dwFlags的配合下,创建或者销毁一个密钥容器。
InitializeCriticalSection:初始化关键节对象。
sub_407A20->loadPEfile
函数其功能主要为将PE文件加载到内存中,此处将40B020、40F080两个位置的内容拷贝出来并保存
Sub_407720->BeginLocalattack
其功能为开启局域网漏洞攻击,主要的两个函数为sub_409160函数,通过网卡设备获取IP地址列表,以及sub_4076B0函数开启一个线程,连接测试这个IP的445端口。
InterlockedIncrement:将 (作为原子操作的指定 32 位变量的值增加一) 递增。
Sub_409160->getAdaptesInfo
获取网卡上的IP地址
GetAdaptersInfo( [out] PIP_ADAPTER_INFO AdapterInfo, [in, out] PULONG SizePointer );
函数检索本地计算机的适配器信息
sub_407480->Connecto445
连接局域网IP 445端口
0x1BDu=445
Sub_401980->sendtoLocal
传播病毒,利用漏洞进行攻击
sub_407540->startAddress
Sub_407840->getRandomTarget
获取随机IP地址进行攻击,将随机数组合为IP后尝试连接,直至连接成功跳出循环,否则会一直尝试连接,直至成功。
之后会不断尝试修改IP子网段第四段的值,尝试连接,若连接失败后会跳转到LABLE_20
Sub_407660->GetRandom
获取随机数
总结
- 打开病毒服务程序,修改注册表
- 加载资源,释放病毒程序
- 搜索局域网和外网可能存在的攻击目标,传播病毒
tasksche.exe的分析
该文件是病毒运行过程中释放的文件,处于隐藏状态,直接通过电脑文件无法显示,可以通过火绒剑在监控的过程中找到该文件的具体位置
WinMain
该函数的主函数,由于函数名丢失,通过反汇编难以直接看出函数的作用
GetFileAttributesA:检索指定文件或目录的文件系统属性如果函数成功,则返回值包含指定文件或目录的属性。
SetCurrentDirectoryA:更改当前进程的当前目录。
Sub_4010FD-->ModifyRegedit
RegCreateKeyW:创建指定的注册表项。如果注册表中已存在该项,则该函数将打开它。
HKEY_CURRENT_USER:保存了本地计算机中存放的当前登录的用户信息,包括用户登录用户名和暂存的密码。
HKEY_LOCAL_MACHINE:保存了注册表里的所有与这台计算机有关的配置信息,只是一个公共配置信息单元
RegSetValueExA:设置注册表项下指定值的数据和类型。
RegQueryValueExA:检索与开放注册表项关联的指定值名称的类型和数据。
1、在HKEY_CURRENT_USER注册表项和HKEY_LOCAL_MACHINE中创建值WanaCry0r
2、将当前目录设为上述注册表项的键值
Sub_401DAB->Releasefiles
该函数主要是加载资源文件,首先用ResHacker资源编辑工具查看wcry.exe的资源,发现一个资源类型为XIA,名称为2058的资源数据,可以看到16进制是 50 4B开头说明这个一个ZIP压缩包。对应病毒运行时释放出来的t.wnry,b.wnry,r.wnry等文件
Sub_401E9E->BiteAccount
列举了三个比特币账号,在执行的时候随机选取一个,写入到指定文件中,通过查找资料得知,该文件是c.wnry并且在病毒桌面程序运行的时候会显示该账户,推断c.wnry是比特币账户信息文件
Sub_401000->ReadwRiteFile
该函数是按照操作进行文件读取写入操作,1为读取,0为写入
Sub_401064->Command
CreateProcessA:创建新进程及其主线程。新进程在调用进程的安全上下文中运行。
WaitForSingleObject:等待,直到指定的对象处于信号状态或超时间隔过去。
该函是对指定命令行参数进行执行,其中第一次参数是 attrib +h该参数意为隐藏属性,即对目录进行了隐藏,对应运行病毒后指定的文件夹处于隐藏状态,第二次运行它命令行参数是"icacls . /grant Everyone:F /T /C /Q",意为创建一个名为Everyone的账户,授予/T /C /Q的访问权限
该命令其实在之前字符串的查看中就出现过
Sub_40170A->FindApi
该函数就是获取一些加密解密和文件操作的API地址
Sub_401225->GetRandom
GetComputerNameW检索本地计算机的 NetBIOS 名称。此名称在系统启动时建立,当系统从注册表中读取它时。
1、获取主机名
2、随机生成字符串
3、随机生成服务名
Sub_401B5F->Create_server_dir
MultiByteToWideChar:将字符串映射到 UTF-16(宽字符)字符串。字符串不一定来自多字节字符集。
GetWindowsDirectoryW:检索 窗口目录的路径。
GetFileAttributesW:检索指定文件或目录的文件系统属性。
GetTempPathW:检索为临时文件指定的目录的路径。
1、多字节转宽字节
2、获取Windows目录,C:\Windows\ProgramData,创建一个目录
3、获取临时目录,在临时目录下创建服务目录
Sub_401AF6->Create_Dir
CreateDirectoryW:创建新目录
SetCurrentDirectoryW:更改当前进程的当前目录
SetFileAttributesW:设置文件或目录的属性
创建新目录,并将新目录的属性设置为隐藏
Sub_401CE8->create_server
OpenSCManagerA:建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库
OpenServiceA:打开现有服务。
StartServiceA:开启现有服务
功能为创建服务
sub_401EFF->cerate_mutex
OpenMutexA:打开现有的命名互斥对象。
创建一个互斥体
Sub_4014A6->DecryptFile
该函数是本层的最重要的函数,本函数将t.wnry进行解密,返回一个大小为0x10000PE文件
TIP
此处有一个小插曲,就是t.wnry文件解密出来的文件提取问题,由于小编是自行学习的,卡住了较长时间,以下是提取的详细过程,望避坑
1、使用ollydbg对该程序进行动态调试,在上述解密函数处打上断点
2、运行到此断点处,然后执行到返回,右侧寄存器中会出现返回的文件的地址
3、选中指定的目标区域hex数据,大小为0x10000,右键点击-》二进制-》二进制复制
4D5A
4、创建一个txt文件,将hex复制进去并保存
5、打开010edit-》file-》import hex-》选择文件类型 hex text(必做) 选中对应的txt文件
6、右键select all 右键 selection -》save salection-》exe文件
小编之前尝试使用复制到剪切板,然后直接复制到010edit中,但是每次复制进去二进制会发生变化,这是一个非常愚蠢的错误,诸位不要模仿
完成以后使用peid对文件进行检测,可以发现是一个dll文件
t.wnry.dll分析
t.wnry.dll模块中TaskStart函数才是真正的加密函数,亦可称之为加密器,wannacry的核心功能都在这里面实现
TaskStart函数
int __stdcall TaskStart(HMODULE hModule, int a2)
{void *v2; // eaxvoid (__thiscall ***v3)(_DWORD, int); // esiHANDLE v4; // eaxHANDLE v5; // eaxHANDLE v6; // ebxHANDLE v7; // eaxHANDLE v8; // eaxHANDLE Thread; // esiWCHAR Filename[260]; // [esp+10h] [ebp-214h] BYREFint v12; // [esp+220h] [ebp-4h]if ( a2 || sub_10004690() )return 0;Filename[0] = word_1000D918;memset(&Filename[1], 0, 518);GetModuleFileNameW(hModule, Filename, 0x103u); #获取本程序的全路径if ( wcsrchr(Filename, 0x5Cu) ) #返回指向最后一个‘\’字符的指针*wcsrchr(Filename, 0x5Cu) = 0; #去掉斜杠SetCurrentDirectoryW(Filename);if ( !sub_10001000(&unk_1000D958, 1) )return 0;dword_1000DD94 = sub_100012D0();if ( !sub_10003410() )return 0;sprintf(Buffer, "%08X.res", 0);sprintf(byte_1000DD24, "%08X.pky", 0);sprintf(byte_1000DD58, "%08X.eky", 0);if ( sub_10004600(0) || sub_10004500(0) ){Thread = CreateThread(0, 0, sub_10004990, 0, 0, 0);WaitForSingleObject(Thread, 0xFFFFFFFF);CloseHandle(Thread);return 0;}v2 = operator new(0x28u);v12 = 0;if ( v2 )v3 = (void (__thiscall ***)(_DWORD, int))sub_10003A10(v2);elsev3 = 0;v12 = -1;if ( !v3 || !sub_10003AC0(byte_1000DD24, byte_1000DD58) )return 0;if ( !sub_100046D0() || dword_1000DC70 ){DeleteFileA(Buffer);memset(&pbBuffer, 0, 0x88u);dword_1000DC70 = 0;sub_10004420(&pbBuffer, 8u);}sub_10003BB0(v3);(**v3)(v3, 1);v4 = CreateThread(0, 0, sub_10004790, 0, 0, 0);if ( v4 )CloseHandle(v4);Sleep(0x64u);v5 = CreateThread(0, 0, sub_100045C0, 0, 0, 0);if ( v5 )CloseHandle(v5);Sleep(0x64u);v6 = CreateThread(0, 0, sub_10005730, 0, 0, 0);Sleep(0x64u);v7 = CreateThread(0, 0, sub_10005300, 0, 0, 0);if ( v7 )CloseHandle(v7);Sleep(0x64u);v8 = CreateThread(0, 0, sub_10004990, 0, 0, 0);if ( v8 )CloseHandle(v8);Sleep(0x64u);sub_100057C0();if ( v6 ){WaitForSingleObject(v6, 0xFFFFFFFF);CloseHandle(v6);}return 0;
}
sub_10004690-》SingleRun
创建名为aMswinzonescach的互斥体,用于防多开,确保单一实例运行
sub_1000100->ReadWriteFile
读取c.wnry文件
Sub_10004600->MutexOpen
检测有一个互斥体,第一次不存在所以创建一个,名为MsWinZonesCacheCoubterMutexA0的 ,设置访问控制属性
sub_10003410->GetApi
获取函数Api
Sub_10004500->Checkfile
它检测一个00000000.dky的文件
//dky解密密钥 pky加密公钥
CreatePubPriFile
Sub_100012D0->CheckUser
检测当前用户是否是系统用户
sub_100011D0-》GetProcess
HMODULE __cdecl sub_100011D0(wchar_t *Destination)
{HANDLE CurrentProcess; // eaxHMODULE result; // eax_DWORD *v3; // esiDWORD TokenInformationLength; // [esp+8h] [ebp-Ch] BYREFHANDLE TokenHandle; // [esp+Ch] [ebp-8h] BYREFwchar_t *Source; // [esp+10h] [ebp-4h] BYREFTokenInformationLength = 0;CurrentProcess = GetCurrentProcess(); #检索当前进程的伪句柄。result = (HMODULE)OpenProcessToken(CurrentProcess, 8u, &TokenHandle);#打开与进程关联的访问令牌。if ( result ){if ( GetTokenInformation(TokenHandle, TokenUser, 0, TokenInformationLength, &TokenInformationLength)|| GetLastError() == 122 )#检索有关访问令牌的指定类型信息。{v3 = GlobalAlloc(0x40u, TokenInformationLength);result = (HMODULE)GetTokenInformation(TokenHandle, TokenUser, v3, TokenInformationLength, &TokenInformationLength);if ( result ){result = LoadLibraryA(LibFileName);if ( result ){result = (HMODULE)GetProcAddress(result, ProcName);if ( result ){Source = 0;result = (HMODULE)((int (__stdcall *)(_DWORD, wchar_t **))result)(*v3, &Source);if ( result ){wcscpy(Destination, Source);if ( v3 )GlobalFree(v3);return (HMODULE)1;}}}}}else{return 0;}}return result;
}
获取当前进程的信息,导入资源
Sub_10004990->StartWana
1、写入c.wnry配置信息
2、启动 @WanaDecryptor@.exe和tasksche.exe
3、创建开机自启动,在注册便Run下添加tasksche.exe
Sub_1001360->Isadmin
AllocateAndInitializeSid: 分配和初始化 Sid 函数分配和初始化最多具有八个子颁发机构的安全标识符 (SID)。
_SID_IDENTIFIER_AUTHORITY结构表示 安全标识符 (SID) 的顶级颁发机构。
CheckTokenMembership:函数确定是否在访问令牌中启用指定的安全标识符 (SID)
判断用户身份
sub_10004890->StartDecryptyexe
sub_100047F0 ->CreateregRun
1、注册表路径“HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run”
2、添加注册表,添加开启启动项