locky勒索软件恶意样本分析2

阿尔法实验室陈峰峰、胡进

前言

随着安全知识的普及,公民安全意识普遍提高了,恶意代码传播已经不局限于exe程序了,Locky敲诈者病毒就是其中之一,Locky敲诈者使用js进行传播,js负责下载外壳程序,外壳程序负责保护真正病毒样本,免除查杀。本文主要对Locky外壳程序和核心程序做了一个分析,来一起了解Locky代码自我保护的手段以及核心程序对文件加密勒索过程的分析。

一        样本基本信息

Js下载者:f16c46c917fa5012810dc35b17b855bf.js

外壳:e7c42d7052e59db13d26e3f3777d04af.exe

核心程序:9DF5F1DA758679672322C2D03DAE77A3.exe

二       详细分析

第一节   JS下载者分析

Js下载者的功能是下载Locky勒索病毒并执行,其使用了代码混淆的方法,使得文件内容无法被识别,而且其变种很多,所以很难对其进行检测

我们捕捉的原始脚本如下

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

经过去除花指令,语法整理,变量重新标明,等技术手段,最终得到的脚本:

现在看清楚了,其实就是一个下载者,当然我们将下载链接替换掉了。

JS的代码经过混淆的,所以会出现很多版本,不对其进行还原,是无法判断其是否为恶意

下面我们来分析一下下载的程序(即外壳程序)

第二节  外壳程序的分析

下载获得的程序是在核心程序的基础上增加了一个外壳,保护核心程序不被杀毒软件查杀。核心程序被分成4部分加密存放在程序中,外壳程序首先先对核心程序进行解密合并然后在内存中执行。

外壳程序解密核心程序的代码也被加密,这里我们称之为MainDecode代码

#01  解密MAINDECODE

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

MainDecode代码被加密了,下面是加密后的代码

解密函数如下

由于混淆代码太多,我就不贴汇编代码了,下面是我用C还原后的代码

看这段代码是不是有点晕,没关系,作者耍了一下

首先我们要获得解密的长度,病毒作者的计算方式是 -0xe05-lpCodeAddr+(lpCodeAddr+i)\

我们展开看就是-0xe05-lpCodeAddr+lpCodeAddr+i

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

我们给lpCodeAddr去掉就是 i-0xe05

也就是如果i-0xe05等于0,那么就退出循环,也就是加密代码的长度为e05

我们再看看解密单个字节的DescryptByte算法

我们就用代码解密,后的格式如下

解密完成后程序采用堆栈不平衡形式跳到解密后的代码里

#02  MAINDECODE拼凑完整的核型程序文件

本病毒里面藏了一个主要功能的Pe文件(我们称之为核心程序),这个文件不但加密了,并且被分割成四块存放在文件中。

1.合并核心程序

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

核心程序被分割成四部分保存在文件中,位置大小信息被加密存放,我们对其解密后获得四部分的位置偏移以及大小。

解密代码

解密后的数据如下

MainDecode会申请四组的A buffer的总大小得长度,

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

再给他们拼凑起来,

总大小为0x11B31,此时Buffer中的数据还是被加密过的,还需要去对这块内存进行解密。

2.解密拼凑后的PE文件

从文件中提取并组后后的PE文件数据是被加密过的,所以还需要去对这块数据进行解密。解密算法采用了梅森旋转随机数算法产生随机数,通过处理后对数据进行移位,获得最终数据,梅森旋转随机数算法产生的数是随机,但是他给种子写死了,所以产生的数据肯定是一样的,第一次初始化用的key是12BD6AAh,申请一个大A buffer size=0x11b31,用来存放最终数据,B buffer size=0x11b31存在加密后的PE文件,申请一个Int数组C buffer size=0x11b31存放解密表。

初始化C从0开始一直到0x11b30

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

使用梅森旋转随机数算法产生随机数,初始化用的key是12BD6AAh

使用梅森旋转随机数算法产生的随机数S,

C[i]=C[S%0x11b30]

这样最终生成解密表C,通过解密表C对B Buffer进行解密

A[i]=B[C[i]]

获得最终的数据存放在A Buffer中

现在我们来看看解密后A的内容,不是个PE文件,还得再做一次解压缩的操作

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

内存地址+4 等于解密后的长度

内存地址+8 等于需要解压缩的长度(0x113b1-0xc=0x11b25)

用COMPRESSION_FORMAT_LZNT1解压缩

解压后的结果出现4D5A,PE程序出现了

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

#03  MAINDECODE执行核心程序

MainDecode将核心程序拼凑完整并解密后,就开始调用核心程序。调用方式是在内存中加载执行。

1.        拷贝PE头

2.        拷贝节

3.        修复重定位表

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

4.        修复导入表

5.        修复节点属性

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

6.        修复SEH链

7.        填写寄存器

8.        修复堆栈

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

9.        跳到新OEP处

至此,外壳程序完成使命,核心程序开始工作。

Ps:快速提取核心程序过程

程序载入后运行后发现开始位置处的代码被写成00,对写入00位置的地方下断点。运行

Ctrl+F9

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

继续单步

就可以dump核心程序代码主体。

第三节核心程序分析

#01 恶意代码流程分析

1 获取系统语言,判断是否是俄罗斯的,是的话直接退出,不是继续下面步骤。

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

2 获取系统信息,并计算出id(区别不同客户端用)

取其中的{..}内容获取md5

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

前16 bytes就是id

3 根据id算出一个项,并写入HKEY_CURRENT_USER\Software\fA21OkqPsY。

并且计算出字符串,找注册表中是否有RSA 的 key。有key就直接进行加密线程。没有就去网络获取RSA key。

4 获取用来加密的主要RSA key

根据系统信息组成下面字符

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

求md5值,buffer = md5(buffer) + buffer

加密

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

加密完数据后,首先会向固定的ip发送来获取key

随机取其中一个,post上面加密的信息,当所有ip都获取不到时候,会使用一个随机算法获得一个域名,然后请求来获取key。

HTTP/1.1 POST 错误!超链接引用无效。

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

随机生成域名用到的最后一段(以.ru, .info, .biz, .clicksu, .work, .pl, .org, .pw, .xyz结尾的域名)

发送请求,得到返回值后需要解密。

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

解密后验证返回数据解密后是否合法

RSA key 格式

最后加密写入注册表。

5 获取勒索文本

类似上面获取key的情况,发送的数据变成id= EA3CF08A962DF289 &act=gettext&lang=zh

也是先加密,在POST,回来的数据先解密,再验证MD5,最后加密写入注册表。

6 判断硬盘类型,并执行相应操作

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

7 创建线程,查找待加密的文件,并加密文件!(主要加密线程)

查找目录或文件名中包含下面字段就跳过

找后缀名是下列后缀名的文件

8 找到文件后对文件进行加密

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

文件加密主要随机生成16 bytes的aes_key,用RSA加密aes_key,再用AES 加密文件名,和文件主体。详细过程查看03。每次加密一个文件后,会在该目录写入勒索信息(_HELP_instructions.txt)!。

9 所有文件都加密完成后,会向C&C发送加密的状态。

向服务器POST过程与获取KEY以及TEXT一致,主要发送的数据如下:

10 删除备份

11写入开机启动

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

12 加密完成后还会写入注册表,表示加密完成。

最终的注册表如下

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

13 最后修改桌面以及显示勒索界面

修改桌面背景

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

打开勒索信息文件

14 移动自身到tmp目录下,并改名

加密完成后删除当前目录下文件

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

#02文件加密过程

1 首先根据文件路径以及名称获取文件的属性。

2 随机生成0×10大小的字符,用来组成新的文件名

新的文件名 = id + Random_16_char + .locky

3直接将旧的文件重命名为新的文件名

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

4 随机生成16 bytes 的AES_key

5 RSA加密16 bytes AES_Key,生成0×100 bytes 密文

加密使用的PKCS1先将明文扩充为长度为0×100大小的数据

EM = 0×00 || 0×02 || PS || 0×00 || M.

00 02 + random(0×100 – 3 – len) + 00 + M

明文扩展后加密。扩展的格式如下。

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

由于PS是系统生成的,自己加密的时候不会和程序加密的RSA有一样的结果!

6 aes加密文件名

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

加密的过程:

首先生成0×800大小的数据

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

7 读取文件,并加密

加密过程同加密文件名的时候,但是中间数据aes加密后从0×230偏移处开始异或。

当超过0xff后,会使用下面方式继续增加中间数据

8 将加密结果写入文件

9 写入文件RSA加密的AES_key(0×100)和AES加密的文件名(0×230)

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]  

10 最后文件的组成

三  总结

Locky勒索病毒,采用很多对抗检测技术,其JS代码、外壳代码很容易变形能够躲避大部分的检测;其采用的是RSA2048位的密钥加密aes_key,每个客户端收到的key都是唯一的,文件被加密后没有Key的情况不能解密。这是一个非常难检测、难防范,危害性极大的病毒

[7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] 

ocky勒索软件恶意样本分析2的更多相关文章

  1. ocky勒索软件恶意样本分析1

    locky勒索软件恶意样本分析1 1 locky勒索软件构成概述 前些时期爆发的Locky勒索软件病毒这边也拿到了一个样本,简要做如下分析.样本主要包含三个程序: A xx.js文件:Jscript脚 ...

  2. 360安全中心:WannaCry勒索软件威胁形势分析

    猫宁!!! 参考链接:http://zt.360.cn/1101061855.php?dtid=1101062360&did=210646167 这不是全文,而是重点摘要部分. 2017年5月 ...

  3. 【API】恶意样本分析手册——API函数篇

    学编程又有材料了 http://blog.nsfocus.net/malware-sample-analysis-api/

  4. Android勒索软件研究报告

    Android勒索软件研究报告 Author:360移动安全团队 0x00 摘要 手机勒索软件是一种通过锁住用户移动设备,使用户无法正常使用设备,并以此胁迫用户支付解锁费用的恶意软件.其表现为手机触摸 ...

  5. 2017-2018-2 20155314《网络对抗技术》Exp4 恶意代码分析

    2017-2018-2 20155314<网络对抗技术>Exp4 恶意代码分析 目录 实验要求 实验内容 实验环境 基础问题回答 预备知识 实验步骤 1 静态分析 1.1 使用virsca ...

  6. 【逆向实战】恶意勒索软件分析_披着羊皮的狼_被注入恶意代码的apk

    /文章作者:Kali_MG1937 QQ:3496925334 CNBLOG博客号:ALDYS4/ 今天逛某论坛的时候发现了一篇求助贴 有意思,好久没分析过恶意软件了 今天就拿它来练练手 反编译工具 ...

  7. MS Office CVE-2015-1641 恶意 Exploit 样本分析

    MS Office CVE-2015-1641 恶意 Exploit 样本分析 在对最近的一个恶意 MS Office 文档样本进行分析时,我们发现了一些有趣的特性.这个文档利用 CVE-2015-1 ...

  8. 发送垃圾邮件的僵尸网络——药物(多)、赌博、股票债券等广告+钓鱼邮件、恶意下载链接、勒索软件+推广加密货币、垃圾股票、色情网站(带宏的office文件、pdf等附件)

    卡巴斯基实验室<2017年Q2垃圾邮件与网络钓鱼分析报告> 米雪儿 2017-09-07 from:http://www.freebuf.com/articles/network/1465 ...

  9. locky勒索样本分析

    前段时间收到locky样本,分析之后遂做一个分析. 样本如下所示,一般locky勒索的先决条件是一个js的脚本,脚本经过了复杂的混淆,主要用于下载该样本文件并运行,. 解密 样本本身进行了保护,通过i ...

随机推荐

  1. 调研ios开发环境的演变

    一:ios的发展演变: 以下两句为百度百科IOS,可自行查阅,不多赘述,就Ctrl+c,Ctrl+v两句表示一下. 2007年1月9日苹果公司在Macworld展览会上公布,随后于同年的6月发布第一版 ...

  2. beta 圆桌 7

    031602111 傅海涛 1.今天进展 主界面微调,部分地方加入用户体验设计 2.存在问题 文档转化太久 3.明天安排 完成全部接口的交互 4.心得体会 文档转化优化不了 031602115 黄家雄 ...

  3. Linux搭建好apache后,只有本地能访问,局域或外网不能访问

    由于防火墙的访问控制导致本地端口不能被访问. 解决方法: 1,直接关闭防火墙  systemctl stop firewalld.service #停止防火墙服务 systemctl disable ...

  4. Linux命令(七)查找文件或目录 find

    find 命令可以根据给定的路劲和表达式查找指定的文件或目录.find 参数选项很多,并且支持正则表达式,功能强大. 和管道结合使用可以实现复杂的功能,是系统管理和普通用户必须掌握的命令. 一.fin ...

  5. Win2008r2 由ESXi 转换到 HyperV的处理过程

    1. 大部分2008r2 采取了 windows loader的方式激活 这种方式 会导致hyperV 启动失败 因为他家在了错误的bios类型 所以第一步建议 使用windows loader 卸载 ...

  6. 解决SVN安装语言包后无法选择中文的问题(亲测可行)

    TortoiseSVN_1.8.8安装后无法选择简体中文,或者安装语言包后也无法选择中文 1.找到 SVN 安装目录,把里面的Languages文件夹删掉 2.安装语言包,百度一下也有很多安装包和语言 ...

  7. Js单元测试工具 以及 粗浅的对我的快乐运算进行测试

    1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...

  8. 二叉树的Java实现及特点总结

    二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 我们先介绍一些关于二叉树的概念名词. 二叉树: ...

  9. 防止短时间js 重复执行

    function debounce(fn, delay) { // 持久化一个定时器 timer let timer = null; // 闭包函数可以访问 timer return function ...

  10. 淘宝卖家搜索器V1.6算法注册机。

    该软件的算法非常简单,适合小白练手.(E语言写的)1.OD加载该软件,输入bp MessageBoxA 2.点击注册 3.OD就会中断下来了 4.按ALT+K打开调用堆栈 5.往上翻,就来到算法处了 ...