7.2.18
,已经不支持6.x
版本的下载了,估计现在也没人安装低版本的Foxmail,所以也就没有写6.x
的解密函数。但是密码的加密算法还是原来的,网上也有文章分析Foxmail的加密算法了,特别是这篇:Foxmail邮箱密取原理与方法研究非常详细。在前人的分析的基础加上GitHub上的开源项目帮助下,我在解密方面没有花太多时间,反而是在解析Foxmail的配置文件上花的时间比较多。C:\\Foxmail 7.2\\Storage\\[email_addr]\\Accounts
,按照用户分配目录,配置文件保存在Account.rec0
文件中,这个后缀名和文件的格式应该Foxmail自己定的,没有特别的序列化函数能解析文件,可以用命令:strings Account.rec0
打印所有可见字符串(图左),整个配置文件大小大概为2M,真实有用的数据大概就3.5kb,而且还是重复了4次的,所以每个帐号的信息不到1kb,即使是这样解析三个帐号的配置文件还是要十几秒,不知道是不是Ruby语言的问题还是我的代码有问题。Email
为键,后面的[email protected]
为值的话,可见字符之间有8个字节的小于0x80
的十六进制数据填充的,所以值是字符串的偏移是9;配置文件中还有其他数据类型的,比如:端口是int型,是否开启SSL是bool型,这两个的偏移都是5,截取长度都是2。OutgoingPort
的值偏移后得到的为\\xd1\\x01
小端存储的十六进01d1
转为十进制为465
。OutgoingSSL
的值偏移后得到的为\\x01\\x00
小端存储的十六进转为十进制为1
,就是True。offset = 0
version = 0
if file[0] == "\\xD0"
offset = 2
else
offset = 9
version = 1
end
index = 0
buffer = ''
email_info = {}
while index < file.length
if (file[index] && file[index] > "\\x20" && file[index] < "\\x7f" && file[index] != "\\x3d")
buffer += file[index]
if ['Email', 'IncomingServer', 'OutgoingServer', 'Password'].include?(buffer)
email_info[buffer] = find_string(file, index + offset) || nil
elsif ['IncomingPort', 'OutgoingPort'].include?(buffer)
email_info[buffer] = find_string(file, index + 5, 2) || nil
elsif ['InComingSSL', 'OutgoingSSL'].include?(buffer)
email_info[buffer] = find_string(file, index + 5, 2) == 1 || false
else
pass
end
else
buffer = ''
end
index += 1
end
def find_string(file, offset, length = 0)
result_string = ''
if length == 0
while (file[offset] > "\\x20" && file[offset] < "\\x7f")
result_string << file[offset]
offset += 1
end
return result_string
elsif offset && length != 0
return file[offset, length].unpack1('S!*') # port or ssl
else
return nil
end
end
def foxmail_crypto(version, ciphertext)
miag_crypt = '~draGon~'
v7_miag_crypt = '~F@7%m$~'
fc0 = '5A'.to_i(16)
if version == 1
miag_crypt = v7_miag_crypt.unpack('c*')
fc0 = '71'.to_i(16)
end
size = ciphertext.length / 2
index = 0
b = []
(0..size).step(1) do |i|
b[i] = ciphertext[index, 2].to_i(16)
index += 2
end
b = b[0..-2]
cc = []
cc[0] = b[0] ^ fc0
cc[1..-1] = b[1..-1]
while miag_crypt.length < b.length
new_miag_crypt = miag_crypt * 2
miag_crypt = new_miag_crypt
end
d = []
(1..b.length).each do |i|
d[i - 1] = b[i] ^ miag_crypt[i - 1]
end
d[-1] = 0
e = []
(0..d.length - 1).each do |i|
if (d[i] - cc[i] < 0)
e[i] = d[i] + 255 - cc[i]
else
e[i] = d[i] - cc[i]
end
end
e = e[0..-2]
# require 'pry'; binding.pry
return e.pack('C*')
end
https://wenku.baidu.com/view/1fcaf49cda38376baf1faeff#
https://github.com/jacobsoo/FoxmailRecovery/