ZJPC第三届电子数据取证大赛——逆向部分详解
取证校赛,专于逆向题目,结果发现逆向题根本没给多少分,所以吃了大亏……
这里主要分析两个部分——手机软件逆向和勒锁病毒程序逆向
手机部分
这里仅分析apk。在这之前的对手机基本信息采集的题目就恕我不多讲了。
49. 手机中有一APK具有文件加解密功能,请找出该APK,其签名有效期终止年份为
有很多师傅都卡在这一步。其实就找软件而言,还是有一些套路的,一般而言,关键软件的安装时间都会和比赛时间非常接近,也就是说只要按时间顺序倒序排一下,然后看哪个软件包名最不正常就可以了。
先看到安装时间第三个新的,名字也很奇怪的安装包(哪有直接把“取证”当名字的),然后直接去搜索文件夹
然后就把里面的base.apk导出,安装到模拟器里面就可以了。
apk的基本信息可以使用jadx、MT、JEB等软件直接看,甚至直接压缩包拆包就可以了。总之就是拿到证书文件。
可以看到是2053年。
这里安装包看上去使用了v1+v2,实际上只使用了v1签名,所以不用在意v2。
50. 接上题,该APK的包名是什么?
com.zjpc.forensics
51. 接上题,APK的SHA256值是什么?(32位小写)
什么32位小写……
直接算一下就可以了。
534129449cf8e96e07e95da98585e53efdaa9fd91f6e77fbf962d300fa0587cd
52. 接上题,APK有几个用户界面?(格式:3)
其实就是在manifest里面看注册了几个activity。在apk里面,每一个activity都对应了一个窗口。题目里面问的用户界面应该也就是这个意思。
可以看到是2个
53.接上题,APK的入口函数是?
apk基础知识,入口函数肯定是mainactivity函数。这也是软件的第一个activity。
com.zjpc.forensics.MainActivity
54.接上题,APK中对用户输入的密码执行了什么操作?
先来看看应用的主界面。这能帮助我们快速分析出来程序使用了哪些架构。
界面很简单,交互组件只有一个按钮一个文本框。
所幸题目本身没有加壳,也没有签名校验,java反编译出来还是很顺利的……
首先来到onCreat函数,可以看到在按钮点击之后,程序会从文本框中读入密码,然后进行checkpass函数。
checkpass函数里边头一次看过去还是有点恐怖的,但是不要怕,逐个分析过去就可以了。
首先这里我们要分两个方面看,秘钥的比对不过两个成分——用户输入的密码和程序给出的密文。相等就是通过,不等就是失败。
于是我们可以看到Encrypt()里面有一个很显眼的“.equals”函数——这个就是比对的函数了。在其左边就是用户输入的密码,右边就是程序给出的密文。
在这里我们先分析用户输入的密码。其在输入之后经过了encrypt函数加密,所以转到encrypt函数进行分析
代码本身没什么新意,有点经验的师傅都知道这个就是base64的加密程序,不过需要注意到的是,程序补位用的字符是"Q"而不是"=",所以可以猜测是换表base64。
事实上jeb已经很贴心地把码表注释在函数开头的getString处了……不用去翻偏移表和string.xml还是方便了不少。
至少到这一步,本题的答案就已经明确了——base64
55.接上题,APK查看加密文件的密码是什么?
这里我们就要去分析程序给出的密文了。
一堆函数的嵌套,仍然是逐个击破。
这边拉下来几个函数来看看。其实这些嵌套函数干的只有一件事——逐位异或计算。区别就是换了的值罢了。所以解密也很简单,原模原样地把程序抄下来再运行一遍就可以了。
不过我这里用了更直接的办法,直接动态调试就可以了。
先到比对和跳转函数处下断点
附加调试。
随便输一个密码,然后进入加密函数,时刻注意寄存器。
然后就可以在v0寄存器中看到最终的密文了。
导出为ASCII字符。结尾为QQ,应该没问题。D0LPC=bPC=5WyXIRDR4fUnQQ
然后写一下脚本,用程序的自定义码表进行base64解密
import base64
STANDARD_ALPHABET = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
CUSTOM_ALPHABET = b'n4/Xv90ElB32S6MmyK+iVIgkjU17CDGaLYxeuzsc8TqNOtrJWPfRp=HFhAwdb5oZQ'
ENCODE_TRANS = bytes.maketrans(STANDARD_ALPHABET, CUSTOM_ALPHABET)
DECODE_TRANS = bytes.maketrans(CUSTOM_ALPHABET, STANDARD_ALPHABET)
def encode(input):
return base64.b64encode(input).translate(ENCODE_TRANS)
def decode(input):
return base64.b64decode(input.translate(DECODE_TRANS))
enstr = encode("sdsiw0tXHSdQqlbHOtcWsToGmZp6q1hiHSiGfDqXfZodfEEtwDFFmSoMmeF14SbuOZwJeEnZwXbd4SdTcXoWOGs1NVqiT0pvseA5h1c1Ne2=".encode())
print(enstr.decode()) #dcT2
destr = decode("D0LPC=bPC=5WyXIRDR4fUnQQ")
print(destr.decode()) #123
密码:th1s_1s_p@5sw0rd。成功进入。
56.接上题,APK内被加密文件的文件名是什么?
接下来分析第二个窗口——SuccessActivity
readEncryptedBitmap……这个函数真是简单粗暴啊。总之加密文件就这样被指明了
eee.dat
57.接上题,APK加解密文件使用的是什么算法?
逐位和0x99进行异或运算
58.接上题,请提交解密后界面的flag。(格式:flag{32位小写md5值})
见上图
flag{15b796b1769e5085ea8c0f13620e28ed}
附加
因为没有签名校验,所以事实上我们可以直接注释掉中的checkpass中的跳转函数,签名打包后覆盖安装,就可以输入任意密码进入flag界面了。
注释掉476行上的代码
签名打包
安装,输入123
勒锁软件部分
勒锁软件的逆向其实没有直接对应的题目……只是因为有一个被加密的文件《工作计划.docx.encrypted》,其内容很可能是其他题目的线索,所以有必要破解一下。
目标很明确——恢复被加密的文件。
受害人的桌面上的cry.exe和黑客kali里面的leisuo.exe是同一个文件,所以可以确认这个就是勒锁文件。
首先我们能从缩略图上看出来,这是python封装成的PE文件,所以直接IDA反汇编肯定是不行的(高级语言的PE文件封装,反编译出来会非常复杂,几乎可以说不可读)。需要借助脚本将其还原成pyc。
这边我选择使用pyinstxtractor。
分离出一堆文件。我们这里重点关注这两个pyc文件
一般来说,源码的pyc会与被分析的PE文件同名,但这里并不是。不过看到import这种只会出现在源码开头的语句,也能猜到这个就是源码的pyc文件了。
然后我们把struct.pyc的前八字节覆盖到import_os.pyc里面去。
然后用pycdc工具进行解析,把源码翻译出来
源码并不全……关键的加解密代码处直接pass掉了。但没关系,收集现有的信息,我们仍然可以推理出程序所使用的加密方式。
首先看到调用的包,肯定有AES和base64 。因为base64通常只用来编码输出,所以我们默认这里只使用了AES算法。
秘钥key就是"mid2dog"。需要注意的是,程序中对"mid2dog"还进行了左对齐并且用0x00填充到十六字节的操作。
AES算法解密需要这几样东西——密文、偏移、加密方式、秘钥、秘钥的填充方式。
密文就是被加密的文档。偏移未知。加密方式未知。秘钥和填充方式都是已知的,因为程序已经将其填充到16字节,所以无需在解密时指定填充类型。
所幸偏移和加密方式并不多,我们大可以一个个试过去。
首先将秘钥进行base64编码处理,便于后续传入解码器
然后试出来是无需填充以及0偏移的ECB算法
将解密出来的十六进制数转为文件,然后就可以打开了……?
fake_flag?搁着我全部白费力气了是吧?
那自然是不可能的,再仔细看看就知道还藏了点其他数据。
破解成功:
Flag{this_is_a_fake_flag}flag{true_flag_26193479874012}
总结
逆向部分还是很有意思的,但说实话,能不能给高难度相对应的高分值啊……好不容易从勒锁软件中破解出来flag,结果答案里面根本就没有,等于是我白破解了。有这时间我去做内存题早就捞分捞麻了(残念)。