样本简介:
代码混淆过,不太好分析。
生成随机秘钥来加密用户文件,从而实施勒索行为。
本贴的内容包括:
1、介绍勒索软件加密用户文件的流程;
2、对这个混淆软件进行静态分析、动态调试分析;
3、修改这个软件,尝试复原被加密的文件;
(整理的初衷是尽可能详细地把全过程交代清楚,导致帖子比较长。先跟大家说声抱歉。
如果不想全部看完的话,可以选择自己感兴趣的部分来看~)
帖子的大致目录:
一,本贴涉及的工具与文件
二,介绍勒索软件加密用户文件的流程
三,静态分析
1、软件初印象
2、静态分析操作的思路
3、开始分析。
四,动态分析
1、感谢丑小鸭大佬的学习贴
2、目的
3、操作思路
4、动态分析
五、勒索软件的卸载
六、尝试恢复被加密的用户文件
1、操作思路
2、尝试复原的准备工作
3、尝试复原
4、查找加密结果不一致的原因
5、从尝试到放弃
七、总结
1、为什么仅加密头1024个字节
2、为什么解密文件失败
一,本贴涉及的工具与文件
Apktool:可对恶意软件进行反编译,从而获得smali代码;
Android Device Monitor:可用于查看模拟器的运行状况,从而定位恶意软件的运行进程等信息;
Android Studio:可对smali代码进行debug;
mumu模拟器:安装恶意软件;
signapk.jar:用于签名软件。
testKey.pk8文件与testKey.x509.pem文件:用于对重打包后的软件进行签名,不签名就没法安装运行了。
二,勒索软件加密用户文件的流程(以加密/sdcard目录为例)
1、申请权限
申请对外存(/sdcard目录)的“写权限”,即在AndroidManifest.xml文件中申请“android.permission.WRITE_EXTERNAL_STORAGE”权限,并在代码中判断/sdcard目录是否“可写”;
2、遍历文件
遍历/sdcard目录下的所有文件,根据黑白名单选择即将要加密的用户文件。
2.1 若采用白名单模式,即勒索软件指定自己要加密的文件类型(如doc,docx,jpeg,png等),若/sdcard目录下文件的后缀名在这些文件类型范围内,则被勒索软件列入“将要加密的文件列表”中;
2.2 若采用黑名单模式,即勒索软件指定自己不可以加密的文件类型,若/sdcard目录下文件的后缀名在这些文件类型范围内,则勒索软件将跳过该文件,将其它文件列入“将要加密的文件列表”中;
3、加密用户文件
采用官方API来加密或自定义方法来加密。
4、删除原文件
否则它的加密有何意义。有些情况下不需要删除原文件,因为原文件被加密内容直接覆盖。
5、进行勒索行为
告知用户“你的文件被我加密啦,给钱就帮你恢复”。勒索行为的实现方式大多以文字的形式出现在手机界面,也可能出现在被加密文件内,又或是以音频的形式来进行勒索。
6、解密文件
用户提交赎金后,勒索软件对文件进行解密。稍微有良心一点的勒索软件,才会进行到这步。有些勒索软件,根本就不提供解密的操作,“拿钱不办事”。
三,静态分析
1、软件初印象
要分析一个软件,总得先看看它长啥样吧。是帅小伙,还是邻家小姐姐,不扔到JEB怎么看得出来呢。那么,扔!
打开JEB,直接把软件拖进来,或者用“打开文件”也一样:
图片2.png (66.68 KB, 下载次数: 0)
2019-4-5 14:50 上传
(图片2.png)
从上面两张图可以认定,混淆得挺彻底的,暗暗搓手:是个学动态调试的好机会啦。直接上手动态调试是要上的,但不是现在,得先进行一波静态分析,否则动态调试时debug都不知道断点该打在哪里了。
所以初印象是啥,就是混淆过了呗,没啥。
2、静态分析操作的思路
加密文件型的勒索软件跟其他类型的恶意软件不同,它的特征更明显。
分析其他类型的恶意软件时,最好是从入口Activity一步一步往下分析(如图片1中被圈出的activity,同时有LAUNCHER和MAIN的)。
但此类恶意软件不用,因为它的恶意行为非常突出,加密+勒索,至于其他行为就不在这个帖子的考虑范畴内了。
在(二)中,我有提到,该类型勒索软件会遍历文件夹,从而找到想要加密的文件。
遍历文件夹,一般用的是File->listFiles()方法(参数及类型我就不写了),而该方法是不会被混淆的,找到listFiles()方法后,就可找到该软件攻击的目录,往下继续分析可找到加密文件、解密文件的部分。
找到解密文件的部分后,修改该软件的smali代码,尝试在未提交赎金的情况下调用“解密文件”的功能,从而达到复原文件的目的。
3、那么,开始分析啦。我先分析为敬。
3.1、用JEB打开该软件,直接在Bytecode里全局搜“listFile”:
图片4.png (39.23 KB, 下载次数: 0)
2019-4-5 14:50 上传
图片6.png (34.37 KB, 下载次数: 0)
2019-4-5 14:50 上传
(图片4、5、6)
到这有两个疑问:(1)可疑字符串e.a的值是什么,做什么用的;(2)e.e的作用是什么,以及在哪被使用。
结合该类型恶意软件的行为,我们不难猜测,此处的行为应该是:遍历目录下所有文件,对每个文件进行判断,文件名是否包含可疑字符串1或可疑字符串2,将符合某一条件的文件名保存到e.e 中。可以合理地猜测,后续将会对e.e保存的文件进行加密或解密。
为方便查找,将e.a重命名为“可疑字符串EA”,但以本人现在的能力无法静态还原出e.a的值,故打算在后续动态调试时查看e.a的值。
3.2、追查e.e在哪被调用。为了方便在搜索,先重命名为“可疑文件列表”,然后在整个bytecode里全局搜索:
图片8.png (55.47 KB, 下载次数: 0)
2019-4-5 14:51 上传
图片10.png (50.03 KB, 下载次数: 0)
2019-4-5 14:52 上传
图片12.png (51.48 KB, 下载次数: 0)
2019-4-5 14:52 上传
图片14.png (46.83 KB, 下载次数: 0)
2019-4-5 14:52 上传
(图片10、11、12、13、14)
其中:
图片12是用官方API进行加密操作。
图片13中看到,最多仅加密头1024个字节。
图片14中的Arrays.copyOfRange(arg6,arg7,arg6.length)是对arg6进行复制,从arg7(如arg7等于0)的位置开始复制,直到复制完arg6结束。
图片14中的System.arraycopy(arg5,0,v0,0,arg5.length)是将arg5整个复制到v0中。
将图片9反混淆后的结果如下:
图片16.png (87.41 KB, 下载次数: 0)
2019-4-5 14:53 上传
(图片16.png)
反编译后,可在该软件所在目录下发现一个同名的文件夹:
图片18.png (39.05 KB, 下载次数: 0)
2019-4-5 14:53 上传
(图片17、18)
看到smali文件夹了嘛,smali代码来得如此容易~美滋滋
4.2将smali代码放到Android Studio里。
具体操作:
4.2.1、在其他任意地方新建一个文件夹,并把图片18中的smali文件夹拷贝过去,并重命名为src:
图片20.png (13.02 KB, 下载次数: 0)
2019-4-5 14:53 上传
(图片19、20)
4.2.2、运行Android Studio ,在首页选择“Open an existing Android Studio project”,选中图片20中的test文件夹,打开后记得选择为Project:
图片22.png (58.32 KB, 下载次数: 0)
2019-4-5 14:53 上传
(图片21、22)
4.2.3、安装smaliIdea插件,插件文件可以去丑小鸭大神的帖子里拿,记得给他一份感谢呀~
图片24.png (212.78 KB, 下载次数: 0)
2019-4-5 14:54 上传
(图片24.png)
上图中的/x/y/z/Android/sdk目录就是啦,至于x,y,z是啥,就自行带入自己的啦。不知道就问你的Android Studio去~
在终端进入sdk目录,进入tools目录,找到monitor,就是它,Android Device Monitor就是它,盘它!噢不,bash 它!
图片26.png (19.5 KB, 下载次数: 0)
2019-4-5 14:54 上传
(图片26.png)
4.4.2、调用软件的入口组件。入口组件为“软件包名/入口activity”。适用命令“adb shell am start –D –n PackageName/MainActivity”,这里am start即“启动”的意思,-D表示进入debug模式,-n表示组件,PackageName就是包名啦,需要用真实的包名代入,MainActivity就是入口Activity,也需要用真实的值代入噢,这里只是形参啦。这是可以看到,模拟器已经进入debug模式了,击掌~
图片28.png (36.11 KB, 下载次数: 0)
2019-4-5 14:55 上传
图片30.png (3.05 KB, 下载次数: 0)
2019-4-5 14:55 上传
(图片30.png)
并可直接在Bytecode里找到对应的smali代码:
图片32.png (70.8 KB, 下载次数: 0)
2019-4-5 14:55 上传
(图片32.png)
同理e.a也是一样的操作:
图片34.png (11.08 KB, 下载次数: 0)
2019-4-5 14:55 上传
图片36.png (30.51 KB, 下载次数: 0)
2019-4-5 14:56 上传
图片38.png (37.81 KB, 下载次数: 0)
2019-4-5 14:56 上传
(图片36、37、38)
4.10、这时候,Android Studio已经运行到我们打断点的地方了,来,赶紧记录值了。这个时候,e.a和f.m的值就不是迷了。
图片40.png (90.9 KB, 下载次数: 0)
2019-4-5 14:57 上传
(图片39、40)
4.11、结合一下静态分析的几个图,把e.a的值与f.m的值带进去,我们重新梳理一下:
图片5、6:若v0文件可被“写”,且v0的文件名不包含“cryeye”(即e.a[3]的值)且不包含“.apk”(即e.a[4]的值),则将v0添加到e.e中。(例:/sdcard目录下的testManifest.txt可被写,且文件名不包含“cryeye”与“.apk”,故将testManifest.txt添加到e.e中)
图片7、8、9中的v0_4就是上面的v0。(例:v0_4的其中一个值为testManifest.txt)
图片10:对于arg5这个文件,是否存在以“.cryeye”为后缀的文件存在。(例,对于testManifest.txt文件,判断是否同时存在testManifest.txt.cryeye文件。)
图片12:Cipher v1=Cipher.getInstance(“AES/ECB/NoPadding”) ,创建cipher对象v1用于加解密。其中算法为AES,模式为ECB,填充方式为NoPadding。这边就先不多解释啦。放到总结的地方再聊聊/p>
图片15:
(1)当this.i为true时,进行加密行为。这里直接用testManifest.txt这个例子来说了,假设该文件有5555个字节。读取testManifest.txt的头1024个字节到v1中,若testManifest.txt.cryeye文件不存在,对v1进行加密。读取testManifest.txt的全部内容,并用v1覆盖该内容的头1024个字节,并将新的内容赋值给v1。也就是说,v1现在的头1024个字节是被加密的,剩下的字节是testManifest.txt的原始内容。(此处还未将v1写入文件)This.h=this.h+”/sdcard/testManifest.txt”+”…[“+“5555”+“bytes]”+“n”,即this.h=this.h+”/sdcard/testManifest.txt…[5555bytes]n” 。
(2)当this.i为false时,进行解密行为。这里依旧用testManifest.txt来说。若testManifest.txt.cryeye文件存在,读取testManifest.txt文件的头1024个字节进行解密,同时读取testManifest.txt的全部内容,将解密后的1024个字节重新放回头部并赋值给v1 。也就是说,v1此时应该保存着testManifest.txt的全部原始内容。(此处还未将v1写入文件)。This.h就不写啦,跟上面的操作差不多。
这样,是不是对这个恶意软件有些了解了呢我们就来看看它坏事做得怎么样了,是不是如它代码里说的那样~
4.12、这个时候,看模拟器上,勒索软件告诉我们,它已经加密6个文件啦。
图片42.png (74.68 KB, 下载次数: 0)
2019-4-6 13:49 上传
(图片42.png)
从图片42中看到出现了两个带.cryeye的文件,这难道就是被加密后的文件是,原文件还在,这是什么操作“du –sh *”命令,该命令用于查看当前目录下所有文件与文件夹的大小。在这里可以看出来.cryeye文件都是空文件!
图片44.png (130.17 KB, 下载次数: 0)
2019-4-6 13:49 上传
(图片44.png)
为什么这个软件只加密头1024个字节呢里先不告诉你,等你看完了就找到答案啦,嘿嘿嘿。
一切都这么顺利,勾起了想要解密的欲望~解密前,得先卸载这个勒索软件吧。
五、勒索软件的卸载
1、停止恶意软件
该软件没法手动退出,那就只能对它不客气啦,用“adb shell am force-stop PackageName”来强制停止运行,记得把PackageName换成具体的包名呀。
2、取消授权
由于前期给这个软件授权了设备管理,所以现在还没法直接卸载,得先取消设备管理,点击“设备”—“安全”—“设备管理器”—“取消勾选”—“取消激活”:
图片46.png (19.43 KB, 下载次数: 0)
2019-4-6 13:50 上传
图片48.png (20.32 KB, 下载次数: 0)
2019-4-6 13:50 上传
图片50.png (39.13 KB, 下载次数: 0)
2019-4-6 13:50 上传
(图片50.png)
4、卸载完成~记得现在不要删除刚刚被加密的文件噢,要留着后面解密用呢。
六、尝试恢复被加密的用户文件
1、操作思路:
当然是想办法调用“解密文件”的操作啦。在图51中我们可以看到当this.i为false时执行加密操作。那么,目前就有两个想法:将if(this.i)修改为if(!this.i),或者将this.i被赋值为true的地方改为赋值为false,。
图片52.png (12.67 KB, 下载次数: 1)
2019-4-6 13:51 上传
图片52.png
3、尝试复原的方法一“将if(this.i)修改为if(!this.i)”
3.1、在JEB的bytecode里找到图片51中if(this.i)对应的地方:
图片54.png (23.87 KB, 下载次数: 0)
2019-4-6 13:51 上传
(图片54)
3.3 、在f.1.smali文件中,找到与图片53相对应的地方:
图片56.png (44.19 KB, 下载次数: 0)
2019-4-6 13:52 上传
(图片56)
3.5、保存修改后的f.1.smali文件,在终端进入图片17所示的地方,此时文件夹79..71f内的smali文件夹就保存着我们刚刚修改的f.1.smali文件。对文件夹79..71f进行编译,即进行重打包操作,
图片58.png (51.68 KB, 下载次数: 0)
2019-4-6 13:52 上传
图片60.png (24.01 KB, 下载次数: 0)
2019-4-6 13:52 上传
图片62.png (27.94 KB, 下载次数: 0)
2019-4-6 13:53 上传
(图片60、61、62)
3.8、安装运行decrypted.apk文件,发现文件并未被复原,且头1024个字节被改动,已经与图片44不一样了,说明两种情况:要么我们没修改成功,if(this.i)依旧跳转到加密的部分,文件又被加密了一次。要么,if(this.i)经我们修改后确实运行到解密部分了,但解密部分的代码并无法真正完成解密操作。不管是哪一种情况,现在/sdcard/testManifest.txt现在已经被加密两回了,不能要了。
图片64.png (236.77 KB, 下载次数: 0)
2019-4-6 13:53 上传
(图片64)
4、查找加密结果不一致的原因
4.1、回到加密与解密的代码中
图片66.png (59.97 KB, 下载次数: 0)
2019-4-6 13:53 上传
(图片65、66)
其中,f.m[30]与f.m[32]的值都是“AES/ECB/NoPadding”。V1.init参数中的1和2对应的是“加密”和“解密”模式,所以,焦点就放在arg5和this.k中了。
4.2、由于丢失了查找原因过程中的截图,所以只能放上找到的最终原因。最终原因在下面图片67中,该恶意软件使用SecureRandom,也就是说图片67的返回值是随机的,故图片65与图片66中的v0也是随机的。当然,在同一次运行恶意软件的情况下,图片65和图片66中的v0是相同的,所以是可以进行解密行为的。但是,卸载恶意软件后v0也就丢失了,再次安装运行的话v0已经不同了,故无法进行解密操作:

图片67.png (42.47 KB, 下载次数: 0)
2019-4-6 13:54 上传
(图片67)
5、从尝试到放弃
现在已经触碰到我的知识盲区了,如果有大佬知道后续该如何操作的话,希望可以交流交流~先献上我的膝盖给大佬们。
七、总结
一开始没想到帖子会这么长,那总结总结吧。(可能会与上文部分内容有所重叠,但是,总结嘛)
1、为什么仅加密头1024个字节:
降低它被杀软检查出来的风险,不少检测方法都是靠计算文件的香农熵。说白点就是,加密一整个文件的话,文件的香农熵会很高,杀软就会判定这个文件被加密了,那么对这个文件进行操作的就是恶意软件了;所以,只加密一部份,甚至是一小部分内容,并不会使文件的香农熵改变太多,那么杀软就无法通过香农熵的方法来检测到这个恶意软件了。虽然只加密了一部分,但对用户来说那伤害已经足够了呀。同样也到达了加密勒索的目的。
2、为什么解密文件失败:
加密时,这个软件所使用的加密秘钥是随机生成的,即随机数由SecureRandom产生,而该类产生随机数时手机了一些随机事件,比如用户点击呀什么的。所以要完全复现出第一次被加密时的情景(即所有随机事件都一样,比如用户在哪个时间点点击屏幕之类的)几乎是不可能的。也就是说,我们拿不到加密时所使用的随机数,因为无法用那个未知的随机数来进行解密。
3、抓住恶意软件的特性进行分析
如果知道了恶意软件的类型,知道它的独特恶意行为,那么直接抓住这个特性作为切入点进行分析,会事半功倍。如分析与这个软件相似的软件时,可参照(三)中的第2步静态分析操作的思路。
4、从尝试到放弃,来得如此容易~
5、写一篇长帖子,真的容易脑阔疼。当然,长帖子看起来也容易脑阔疼。但是只挑重点写吧,我又担心交代不清前因后果,原谅我~
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91301 人正在系统学习中 相关资源:【内存遍历工具】Cheat.Engine.V5.4.简体中文版-专业指导文档类…
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!