0x00
今天上python课听到老师中途提起说 有很多微信接收的dat文件,但是暂时不清楚如何解密成图片,所以回来准备自己研究研究(折腾折腾),帮老师解决一下问题~
顺便减轻一下上课不听课的愧疚感
0x01 分析
首先找一下微信存储文件的地方在哪里,一通(百度 )研究发现存储的路径如下C:\Users\用户\Documents\WeChat Files\wxid_kxxxxxxx\FileStorage\Image
根据文件夹名字也能发现这些文件应该就是加密后的图片文件了,16进制编辑器看一看
发现大部分文件开头都是7D5A
, 众所周知jpg格式开头几个字节为0xFFD8
, 不如做个异或看看
dat文件和正常jpg文件前两个字节异或结果为0x8282
, 推测是不是dat文件所有字节都异或了0x82
, 随便挑一个dat文件,把其中所有的字节挨个异或0x82
成功恢复成了图片! 推测是正确的
0x02 发现问题
不过经过测试有时候脚本会失效,Why?
前面还提到有些文件接收后开头不是7D5A
,这是非Jpg格式图片加密后的存储,经过研究发现密钥依然是Jpg格式加密的密钥。如果脚本第一次检测的不是Jpg格式的图片的话,就拿不到正确的密钥,自然就失效了
改进函数
根据规律改进一下自动检测密钥的函数,找到一个dat文件后依次与jpg,png,gif的头部做异或,如果异或的前两个字节一样则就确定了密钥
如果脚本失效则手动解决
如果脚本依然失效的话就手动解决 ,方法就是找一个Jpg格式的图片通过微信传输过去,然后在微信存储图片的那个目录下找到刚刚新增加的dat文件,把这个文件拿去用脚本跑一次,脚本会显示出正确的密钥
然后把这个值填写进脚本的secretKey
中即可
0x03 Talk is cheap ,Show the code
使用的时候只需要改inpath
和out_path
两个变量就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 import osinpath = r"D:/CTF文件/微信dat文件/" out_path = r"D:/CTF文件/微信dat文件/" jpg = 0xFFD8 png = 0x8950 gif = 0x4749 secretKey = 0x00 def autoCheck (path ): global secretKey if secretKey != 0x00 : pass else : print ("[*] autoCheck:" ) file_List = os.listdir(path) for file_Name in file_List: file_WithPath = os.path.join(path, file_Name) if file_WithPath.endswith("dat" ): print (f"[*] 检测dat文件: {file_Name} " ) with open (file_WithPath, "rb" ) as raw_DatFile: head2Byte = int .from_bytes(raw_DatFile.read(2 ), byteorder='big' ) for i in [jpg,png,gif]: LowByte = (head2Byte ^ i) >> 8 HighByte = (head2Byte ^ i) & 0x00FF if LowByte == HighByte : secretKey = LowByte print (f"[*] SecretKey: {hex (secretKey)} " ) break break else : pass if secretKey == 0x00 : while True : try : secretKey = int (input ("[#] 未找到秘钥,可手动输入(例如0x82): " ),16 ) except : print ("格式错误,正确格式如: 0x82" ) else : break def checkFileTypes (path ): print (f"[*] 当前目录: {path} " ) fileTypes = set () file_List = os.listdir(path) for file_Name in file_List: file_WithPath = os.path.join(path, file_Name) if file_WithPath.endswith("dat" ): print (f"[*] dat文件: {file_Name} " ) with open (file_WithPath, "rb" ) as raw_DatFile: head2Byte = int .from_bytes(raw_DatFile.read(2 ), byteorder='big' ) fileTypes.add(hex (head2Byte)) else : pass print (f"文件类型数量: {fileTypes} " ) def imageDecode (file_WithPath, file_Name ): out = out_path+file_Name+".png" with open (file_WithPath, "rb" ) as dat_read, open (out, "wb" ) as png_write: for now in dat_read: for nowByte in now: newByte = nowByte ^ secretKey png_write.write(bytes ([newByte])) def findFile (path ): autoCheck(path) print (f"[*] 当前目录: {path} " ) file_List = os.listdir(path) for file_Name in file_List: file_WithPath = os.path.join(path, file_Name) if file_WithPath.endswith("dat" ): print (f"[*] dat文件: {file_Name} " ) imageDecode(file_WithPath,file_Name) else : pass findFile(inpath)
0x04
解密后发现我微信为什么会悄悄存储了这么多乱七八糟我没见过的图片…
amazing…