初学者的静态分析挑战writeup7

题目来源至 https://www.malwaretech.com/beginner-malware-reversing-challenges

所有挑战都是在不使用调试器的情况下完成的,你的目标应该是能够在不运行exe的情况下完成每个挑战。

ransomware1

勒索解密,难度等级1星。

题目说是一个脚本小子写的勒索软件,问能否解密flag.txt文件?

仅为静态分析,不需要使用调试器。

下载解压完如图:
在这里插入图片描述
文件夹为加密过的文件,exe为加密程序demo。
在这里插入图片描述
先分析exe文件,使用IDA打开。

自动识别了start程序,进入看看。
在这里插入图片描述
进入sub_401000
在这里插入图片描述
之前已分析过,所以已经做了些注释与重命名。

这个函数有两个参数,通过API可知,有打开文件与写入文件的操作,这里应该就是加密的核心了。

查snprintf函数的四个参数,结合已经加密的文件特征可以知道a1为需要加密的原始文件的文件名,这里的作用仅仅是拼接字符串作为加密后的文件名。

接下来的CreateFileA函数是打开已经存在的文件,第二个CreateFileA函数是新建一个文件。

do while循环里第一步先检查读取文件时是否成功,如果成功读取4096个字节则执行for循环。

for循环循环的次数为ReadFile实际读取的字节数v6,如果文件超过4096个字节,则v6第一次读取就为4096。

如果文件小于4096个字节,则v6为实际文件的大小。

for循环里有个参数a2未知,将a2的值加上i与0x20的取模运算后的结果再与当前文件从文件开头的第i个字节的值进行异或,
最后的结果再赋值到源位置里。

循环4096次后,就结束循环。最后关闭文件句柄,退出。

加密的原理是对文件的前4096个字节进行计算后重新赋值,如果文件小于4096就对整个文件内容进行处理再在对应位置赋值。

问题的关键是a2的值是什么?

第一次不使用a2,直接对flag.txt进行处理,发现打开后是乱码,说明解密不成功。

这里的话确实要发挥脑洞了,压缩包里给了两类文件,一类是加密后的图片,一类是存在flag的txt文件。

先看图片文件,发现是英文命名的,后缀都为jpg格式。既然a2的值是固定的,加上jpg格式都是有一定特征的,那么如果这些jpg文件里有部分内容是一样的话,说明就可以通过再进行异或运算得到a2这个key的值。

使用Beyond Compare依次打开这些图片,然后一一比较,发现前22个字节是一致的(这里以为找到了突破口,发现却不是)。
在这里插入图片描述
说明图片是突破口,然后弄了半天没有发现如果找到图片开头的特征码,因为每个jpg文件好像除了开头两个字节是特征码之外,其余的字节不一定是一致的,我陷入了无解中。

然后突然觉得这个很难解密了,因为无法知道a2的值到底是什么。

带着怀疑就复制加密后的文件名Chrysanthemum去谷歌搜索下,发现了原来是Win7 自带的壁纸图片,啊啊啊,确实不能放过任何信息。
在这里插入图片描述
突然醒悟,或许这就是突破口,马上打开Win7寻找原始的壁纸图片,编辑器打开,与加密后的文件进行对比。
在这里插入图片描述
源壁纸文件如下图:
在这里插入图片描述
加密后的壁纸文件如下图:
在这里插入图片描述
最后,通过上述两个图片里前4096个字节的每个字节进行异或运算后得到规律发现a2的取值是一个字节数组。

key = [
0x6E, 0xF7, 0x9B, 0x0E, 0x45, 0x55, 0x5E, 0x95,
0x96, 0xFE, 0xAB, 0x75, 0x80, 0xB4, 0x0E, 0x40,
0x3D, 0xF5, 0xA7, 0x1B, 0xED, 0xD5, 0x5B, 0x80,
0xA9, 0xD3, 0x8D, 0x2C, 0xB8, 0x0A, 0x40, 0x0F
]

并且经过32个字节运算后,会重复这个过程,直到处理的字节数达到4096个。

得到key值后,可以通过之前逆出的加密流程对flag.txt_encrypted进行解密了。

解密脚本如下:

# coding:utf-8
key = [
    0x6E, 0xF7, 0x9B, 0x0E, 0x45, 0x55, 0x5E, 0x95,
    0x96, 0xFE, 0xAB, 0x75, 0x80, 0xB4, 0x0E, 0x40,
    0x3D, 0xF5, 0xA7, 0x1B, 0xED, 0xD5, 0x5B, 0x80,
    0xA9, 0xD3, 0x8D, 0x2C, 0xB8, 0x0A, 0x40, 0x0F
]


decrypted = ''
file_name = "flag.txt_encrypted"


with open(file_name, 'rb') as f:
    encrypted = f.read()


for i in range(len(encrypted)):
    decrypted += chr(encrypted[i] ^ key[i % 0x20])


with open(file_name.replace('_encrypted', ''), 'w') as f:
    f.write(decrypted)
    print(decrypted)

在这里插入图片描述
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章