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')