0x00 定义
.dat文件不是标准的文件格式,很多应用都会使用这个后缀存储数据。一般只能通过产生该文件的程序正确访问,如QQ、微信都会产生.dat文件。
以微信为例。微信使用该后缀的文件存储图片(显然是不如聊天记录那么机密,没有存储为.db文件),文件保存于FileStorage文件夹。以十六进制方式查看这些文件,可以发现许多文件的头部字节为8A AD,也有17 CE等。
实际上微信程序是将图片的每个字节与某个值异或后进行存储的(异或是对文件加解密的基本操作之一)。
0x01 提取
常见的后缀都有独特的文件头:
| 格式 | 头部 |
|---|---|
| .jpg | FF D8 FF |
| .png | 89 50 4E 47 |
| .bmp | 42 4D |
| .gif | 47 49 46 38 |
| .zip | 50 4B 03 04 |
| .rar | 52 61 72 21 |
| .avi | 41 56 49 20 |
使用异或性质还原出常量(由于是逐字节操作,常量应当是由两个相同的字节构成的):

很巧合,使用.jpg的头部得到的常量就是正确的。
利用这个常量对原文件的每个字节按位异或即可还原出图片了(还原成功就说明思路可行)。
0x02 试验
基于一道实战题目:


其头部为17 CE,使用.jpg头部的计算结果显然是有问题的:

但是使用.png的头部似乎得到了正确的常量:

0x03 脚本
编写一个脚本执行按位异或:
# -*- coding: utf-8 -*-
# 常量为9E9E
def decodeHack(fi, fo):
data_in = open(fi, 'rb')
out = './' + fo + '.png'
data_out = open(out, 'wb')
for i in data_in:
for byte in i:
new_byte = byte ^ 0x9E
data_out.write(bytes([new_byte]))
data_in.close()
data_out.close()
if __name__ == "__main__":
decodeHack('./keli.dat', 'hack_output')
0x04 结果


