首页
社区
课程
招聘
[原创] WannaDie 勒索病毒 详细分析
2018-1-12 15:33 10372

[原创] WannaDie 勒索病毒 详细分析

2018-1-12 15:33
10372

目录

0x01 程序信息

0x02 程序行为

0x03 分析思路

0x04 初始工作

0x05 病毒母体分析

0x06 病毒子体分析

0x07 分析解密部分

0x08 核心加密代码分析

0x09 进程检测函数分析

0x01 程序信息

病毒名: lantern installer.exe

Size: 4,272,640 字节

壳: UPX 0.89.6 - 1.02 / 1.05 - 2.90

编写语言: 易语言

[MD5] 7C72C7DADDF61B98804CBA0C5EDA4669

[SHA256] F17E7BBFC5B003672C872BD5B4FE2BD4B15CAA1E91045FE40D2FA2DFBA607837

0x02 程序行为

(1) 隐藏自身

(2) 释放病毒子体

(3) 关闭UAC

(4) 注册开机启动项

(5) 进程检测

(6) 删除卷影副本

(7) 发送邮件

0x03 分析思路

(1) 查看是否加壳.

(2) 观察病毒运行起来之后做了一些什么.

(3) 用火绒剑载入运行, 检测一些敏感行为.

0x04 初始工作

(1) PEID载入, 发现了UPX 壳, 用ESP定律轻松脱掉.



(2) 根据一下特征分析得出这是一个易语言程序.

易语言的标准图标


易语言的跳转表



(3) 在虚拟机中运行程序, 取得一些程序特征.

  (1) 自我隐藏

  (2) 打不开任务管理器

  (3) 桌面背景被换

  (4) 各个盘根目录都有勒索图片

  (5) 文件被加密后大小不变 <最重要的特征, 以此可以判断使用了流加密算法>

  (6) 写了开机启动项.

(4) 运行截图



(5) 拿到一些基础的特征, 就可以开始逆向分析了.


0x05 病毒母体分析

(1) 病毒母体最主要的功能就是把病毒子体释放到系统临时目录,并执行.

(2) 其余的功能就是病毒子体的前5步一样了, 为了篇幅不太臃肿, 就省略了.



0x06 病毒子体分析

(1) 通过易语言的特征码:FF 55 FC 5F 5E 89 5D F4 下断点,

     这里会处理main函数, 按钮事件, 时钟 … 等各种事件.


(2) 下好断点之后, 运行, 就会断到此处, 按F7即可找到main函数, 继续往下分析即可.




(3) 创建Event, 用来防多开



(4) 提升进程权限



(5) 提升自身进程优先级



6) 写注册表破坏UAC,

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA

写入值: <0>



(7) 修改开机启动项

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\WannaDie

写入值:“<C:\Users\AYZRxx\AppData\Local\Temp\dump_daughter_.exe”>



(8) 禁用注册表工具, 写注册表

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\Disableregistrytools

写入值: <1>



(9) 禁用任务管理器, 写注册表

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr

写入值: <1>



(10) 设置自身文件属性为<隐藏|系统|只读|存档>



(11) 删除卷影副本, 执行CMD命令: "cmd /c vssadmin delete shadow /all /quiet & wmic shadowcopy delete & bcdedit /set {default} boostatu"




(12) 生成随机序列号, 这些序列号只是用来辨别中毒机器的, 并不是真正的解密Key.



(13) 获取盘符



(14) (14.1)这个勒索病毒的加密方式很渣, 每一种后缀都需要全盘遍历一次, 在进行加密, 这样会导致加密效率非常低.

       (14.2) 这是所有会加密的后缀, 但是有些后缀只会修改名称, 并不会加密数据

“*.zip,*.rar,*.7z,*.e,*.ec,*.bak,*.cpp,*.c,*.h,*.cs,*.dOc,*.docx,*.xls,*.xlsx,*.ppt,*.pptx,*.mdb,*.php,*.gif,*.rtf,*.png,*.jpg,*.jpeg,*.txt,*.avi,*.msg,*.mp3

*.mp4,*.pdf,*.pps”



(15) 加密完成后, 将勒索图片写到桌面.



(16) 遍历所有盘符, 在盘符根目录写勒索文件.




(17) 设置桌面背景为勒索图片.




(18) 载入勒索窗口




(19) 病毒会通过访问www.baidu.com来判断是否联网




网络没有连接则弹出此框



(20) 连接邮箱



(21) 拍摄快照






(22) 把拍摄的快照当作附件, 加入邮件,  并发送到指定邮箱





(23) 删除快照文件




0x07 分析解密部分

(1) 加了一个反调试函数, 不过只是简单的检测调试端口, 被OD插件给过了.



(2) 比较密钥是否正确, 因为需要继续分析, 所以手动修改下, 使之条件成立.



(3) 调用解密窗口, 并且创建一个解密线程



(4) 解密线程的无非就是遍历磁盘来解密文件.



0x08 核心加密代码分析

(1) 计算加密Key, 获取物理驱动器0的序列号<不确定> 0xB3211363




(2) 将这个0xB3211363十六进制的数转换为10进制的字符串, 就得到了最终用来加密的Key.




(3) 遍历*.ec文件并加密.




(4) 先读入文件



(5) 生成0x100大小的密码表



(6) 加密函数, 这个函数就需要用到IDA分析了.



(7) 对这个函数F5之后会修改一下参数类型就可以直接复制到VS中使用了, 代码如下:

      说个IDA F5复制代码的小技巧: 尽量使用BYTE类型, 而不是char类型,  因为char类型为数组的下标时, 会被当成4个字节, 其余3个字节是未知的,

                                                        有可能导致错误.

# include <stdio.h>
# include <string.h>
#include  <atlstr.h>
#include <windows.h>

typedef unsigned int uint;
uint POLYNOMIAL = 0xEDB88320;
int have_table = 0;
uint table[256];

void make_table()
{
	int i = 0, j = 0, crc = 0;
	have_table = 1;
	for (i = 0; i < 256; i++)
		for (j = 0, table[i] = i; j < 8; j++)
			table[i] = (table[i] >> 1) ^ ((table[i] & 1) ? POLYNOMIAL : 0);
}

uint crc32(uint crc, char *buff, int len)
{
	if (!have_table) make_table();
	crc = ~crc;
	for (int i = 0; i < len; i++)
		crc = (crc >> 8) ^ table[(crc ^ buff[i]) & 0xff];
	return ~crc;
}

DWORD GetDriveFeature()
{
	HANDLE hPhysicalDriveIOCTL;
	DWORD dwCbBytesReturned;

	char driveName[20] = "\\\\.\\PhysicalDrive0";
	hPhysicalDriveIOCTL = CreateFileA(driveName, 0, 1 | 2, 0, 3, 0, 0);
	if ((DWORD)hPhysicalDriveIOCTL == -1)
	{
		return FALSE;
	}

	DWORD dwBufferSize;
	dwBufferSize = 1024;
	char query[12] = {};
	char buffer[1024] = {};

	BOOL bSt;
	DWORD dwCrc1;
	bSt = DeviceIoControl(hPhysicalDriveIOCTL, 2954240, query,
		12, buffer, dwBufferSize, &dwCbBytesReturned, 0);
		
	if (bSt = TRUE)
	{
		dwCrc1 = crc32(0, buffer, 1024);
	}
	CloseHandle(hPhysicalDriveIOCTL);
	return dwCrc1;
}


//交换字节
BYTE *__cdecl ChangeByte(BYTE *a1, BYTE *a2)
{
	BYTE *result; // eax@1
	char v3; // cl@1
	result = a1;
	v3 = *a1;
	*a1 = *a2;
	*a2 = v3;
	return result;
}

//生成密码表(密钥, 密钥长度, 生成0x100尺寸的密码表)
int GenerateKeyTable(char* szKey, signed int nKeyLen, BYTE* szKeyTable)
{
	signed int v3 = 0; // eax@1
	BYTE *v4 = 0; // ebp@1
	int result = 0; // eax@3
	BYTE v6 = 0; // esi@4
	BYTE *v7 = 0; // ebx@4
	bool v8 = 0; // zf@5
	signed int v9 = 0; // [sp+4h] [bp-8h]@4
	unsigned __int8 v10 = 0; // [sp+18h] [bp+Ch]@4

	v3 = 0;
	v4 = (BYTE *)szKeyTable;
	do
	{
		*(BYTE *)(v3 + szKeyTable) = v3;
		++v3;
	} while (v3 < 0x100);
	result = nKeyLen;
	*(BYTE *)(szKeyTable + 0x100) = 0;
	*(BYTE *)(szKeyTable + 0x101) = 0;
	if (nKeyLen > 0)
	{
		v10 = 0;
		//LOBYTE(v6) = 0;
		v7 = v4;
		v9 = 256;
		do
		{
			v6 = (unsigned __int8)(*(BYTE *)(v10 + szKey) + v6 + *v7);
			ChangeByte(v7++, &v4[v6]);
			result = v9 - 1;
			v8 = v9-- == 1;
			v10 = (v10 + 1) % nKeyLen;
		} while (!v8);
	}
	return result;
}


//RC4加密(被加密数据, 被加密数据长度, 0x100尺寸的密码表)
char __cdecl Rc4_Enc(BYTE *pbByEncData, int nLen, BYTE *pbKeyTable)
{
	BYTE *v3; // esi@1
	int v4; // ebx@1
	BYTE result; // al@1
	BYTE v6; // cl@1
	BYTE v7; // di@2
	BYTE v8; // bp@2
	BYTE *v9; // ST20_4@3
	BYTE *v10; // ST1C_4@3
	BYTE v11; // [sp+8h] [bp-Ch]@3
	BYTE v12; // [sp+20h] [bp+Ch]@1
	BYTE v13; // [sp+20h] [bp+Ch]@3

	v3 = pbKeyTable;
	v4 = 0;
	result = pbKeyTable[0x100];
	v6 = pbKeyTable[0x101];
	v12 = pbKeyTable[0x100];
	if (nLen <= 0)
	{
		v3[0x100] = result;
		v3[0x101] = v6;
	}
	else
	{
		v7 = v12;
		v8 = v6;
		do
		{
			v13 = v7 + 1;
			v7 = v13;
			v9 = &v3[(unsigned __int8)v13];
			v11 = v8 + *v9;
			v8 = v11;
			v10 = &v3[(unsigned __int8)v11];
			ChangeByte(v9, v10);
			//因为这里只是进行异或, 经过测试这段代码可以加密, 也可以解密
			pbByEncData[v4] ^= v3[((unsigned __int8)*v9 + (unsigned __int8)*v10) & 0xFF];
			++v4;
		} while (v4 < nLen);
		result = v11;
		v3[0x100] = v13;
		v3[0x101] = v11;
	}
	return result;
}

int main()
{
	//计算当前电脑的密钥, 测试机器的密钥为  "-1289677981"
// 	DWORD dwFeature = GetDriveFeature();
// 	CStringA csFeature;
// 	csFeature.Format("%d", dwFeature);
// 	printf("%s\n", csFeature.GetBuffer());
// 	csFeature.ReleaseBuffer();

	HANDLE hFile = CreateFileA("C:\\Users\\AYZRxx\\Desktop\\11.ec",
		GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 
		NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	DWORD dwFileSize = GetFileSize(hFile, NULL);

	byte* pbFileBuf = new byte[dwFileSize];
	DWORD dwRead = 0;
	ReadFile(hFile, pbFileBuf, dwFileSize, &dwRead, NULL);

	char szkey[0x10] = "-1289677981";
	BYTE pbKeyTable[0x200] = {};
	//生成0x100大小的密钥
	GenerateKeyTable(szkey, 0xB, pbKeyTable);
	//解密数据
	Rc4_Enc(pbFileBuf, dwFileSize, pbKeyTable);

	SetFilePointer(hFile, NULL, NULL, NULL);
	WriteFile(hFile, pbFileBuf, dwFileSize, &dwRead, NULL);

	CloseHandle(hFile);
	system("pause");
	return 0;
}




0x09 进程检测函数分析

(1) 时钟只是简单的结束任务管理器进程而已, 通过API 条件断点则可以搞定.

(2) API<DispatchMessage> 下条件断点 short ptr [[esp+4]+4] == WM_TIMER

(3) Timer结束进程: "taskmgr.exe" "任务管理器.exe"

Timer回调函数地址: 0040D2C6  时钟周期: 1000ms




udd文件及密码样本, 有需要的就找我把, 附件传不上来, 不知道为什么.





[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-7-15 09:14 被AYZRxx编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (22)
雪    币: 75
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
itiansin 2018-1-12 15:45
2
0
原来我也能占个沙发      楼主这图全部都裂了是什么情况
雪    币: 3395
活跃值: (900)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
AYZRxx 2 2018-1-12 16:12
3
0
已经把图修复了,  我一个一个图片传的,  字节从word上复制有问题,  不清晰
雪    币: 2697
活跃值: (389)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
pak无名 2018-1-12 16:58
4
0
请教下od那里怎么改的~~api能显示中文备注
雪    币: 89
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shenpengz 2018-1-12 17:34
5
0
同请教下od那里怎么改的~~api能显示中文备注
雪    币: 3395
活跃值: (900)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
AYZRxx 2 2018-1-12 18:22
6
0
对地址用  shift  +  :  就可以了,  就是打标签
雪    币: 355
活跃值: (276)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
阿東 3 2018-1-12 22:16
7
0
感谢分享  支持下
雪    币: 2697
活跃值: (389)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
pak无名 2018-1-13 15:48
8
0
暗夜之刃 对地址用 shift + : 就可以了, 就是打标签
一个个手动改吗。。。。。
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhengsidie 2018-1-16 09:55
9
0
分析得还不错
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_南瓜小哥° 2018-1-16 11:27
10
0
报告的核心思想是:  看图说话!
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
草原小蚂蚱 2018-1-16 15:00
11
0
雪    币: 171
活跃值: (474)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Lthis 1 2018-1-17 10:17
12
0
哥们,给个hash值上来吧。
雪    币: 12839
活跃值: (8998)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
hzqst 3 2018-1-17 11:15
13
0
看到“第三方支持库”,还以为是哪个易语言大手子又出名了
雪    币: 3395
活跃值: (900)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
AYZRxx 2 2018-1-17 15:04
14
0
分析文件和样本链接:  https://pan.baidu.com/s/1o956On4  密码:  ajxd
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
KuNgBiM 66 2018-1-17 15:40
15
0
调戏作者1:https://www.zhihu.com/question/264331588/answer/282786152
调戏作者2:https://bbs.ichunqiu.com/thread-29386-1-1.html?from=zh
雪    币: 2431
活跃值: (2869)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
boursonjane 2018-1-17 18:34
16
0
回帖拿钱去发帖,  支持666
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
冷灵气 2018-1-17 21:54
17
0
老铁,很给力
雪    币: 447
活跃值: (1473)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Mrack 2018-1-19 17:06
18
0
是不是用了我的E  Killer插件啊。名字很像。
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
聖blue 2018-1-19 22:56
19
0
雪    币: 8236
活跃值: (4946)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
大道在我 2018-1-20 00:58
20
0
很详细  学到知识了
雪    币: 16154
活跃值: (5961)
能力值: ( LV13,RANK:861 )
在线值:
发帖
回帖
粉丝
大帅锅 4 2018-1-20 01:53
21
0
雪    币: 225
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mortalboold 2018-2-11 18:18
22
0
Mrack 是不是用了我的E Killer插件啊。名字很像。
大佬,求你的e  killer插件啊。吾爱上的链接失效了
雪    币: 485
活跃值: (2144)
能力值: ( LV12,RANK:356 )
在线值:
发帖
回帖
粉丝
findreamwang 6 2018-3-20 14:19
23
0
大佬,你原始文件密码是啥啊???一直不对
游客
登录 | 注册 方可回帖
返回