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. 第三次作业--导入excel表格(完整版)

    031302322 031302316 将教师排课表导入系统 使用powerdesigner设计数据库表格 设计概念模型 打开new -> Conceptual Data Model创建概念模型 ...

  2. (Alpha)Let's-典型用户和场景&功能规格说明书

    典型用户和场景 Personal/典型用户 名字 阿王 性别.年龄 男.20 职业 学生 收入 无 知识层次和能力 大学学生,善于乐于使用电脑.手机 生活/工作情况 上学 动机.目的.困难 感到大学生 ...

  3. FPGA---Basys3(实验内容汇总贴)

    前言 本博文为FPGA---Basys3入门板的实验汇总帖子. 实验指导书 实验源码github地址 实验目录 组合逻辑电路设计 编码器 比较器 全加器 时序逻辑电路设计 D 触发器的实现 同步复位的 ...

  4. VC2013一些感受

    这是一个我很早就在用的编译器,因为是微软官方的,极其高大上,安装包,界面错误的提示处理都相当简洁明了,不像VC6.0以及Codeblock太low了 但其实,我想说,我并不怎么用这玩意~就像Siri做 ...

  5. github优缺点

    以前bitbucket沒有支援git github可以直接在網站上瀏覽push的圖片 github 可以針對code行數直接留言與回覆 github Markdown支援很好 github 的issu ...

  6. grunt入门讲解1:grunt的基本概念和使用

    Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. Grunt 0.4.x 必须配合Node.js >= 0.8.0版本使用.老版本的 Node. ...

  7. [转帖] Kubernetes如何使用ReplicationController、Replica Set、Deployment管理Pod ----文章很好 但是还没具体操作实践 也还没记住.

    Kubernetes如何使用ReplicationController.Replica Set.Deployment管理Pod https://blog.csdn.net/yjk13703623757 ...

  8. github如何添加新的分支

    需求:甲建立分支分给乙步骤:在甲创建的项目仓库里边点右上角的按钮 就可以通过名字搜索了. 在乙的右上角 再选中Repositories就可以看到所有的 存储库 了

  9. Python multiprocessing模块的Pool类来代表进程池对象

    #-*-coding:utf-8-*- '''multiprocessing模块提供了一个Pool类来代表进程池对象 1.Pool可以提供指定数量的进程供用户调用,默认大小是CPU的核心数: 2.当有 ...

  10. JAVA AES CBC PKCS5Padding加解密

    package com.hzxc.groupactivity.util; /** * Created by hdwang on 2019/1/17. */ import org.slf4j.Logge ...