读取HeidiSQL 配置文件中的密码
2017-1-21 5:42:01 codegaypython
HeidiSQL是一款开源的SQL管理工具,用管理MYSQL,MSSQL 等数据库,
不少管理工具都会把密码存在本地,HeidiSQL也是的,可是只是通过很是简单的编码,因此我通过简单的分析后就知道了解密的方法。
连HeidiSQL源码都不用读...git
我使用的是版本是HeidiSQL_9.4_Portable,配置会存在软件目录下的portable_settings.txt中,
HeidiSQL安装版会配置信息存在如下注册表中:github
HKEY_CURRENT_USER\Software\HeidiSQL\
密码会保存在:
HKEY_CURRENT_USER\Software\HeidiSQL\Servers
这个节点下面。sql
HeidiSQL portable版运行后也会创建注册表信息,退出软件会删除,配置信息最终会保存到portable_settings.txt中:
HKEY_CURRENT_USER\Software\HeidiSQL Portable [一串随机数]
数据库
相似这样:HKEY_CURRENT_USER\Software\HeidiSQL Portable 9532
session
打开portable_settings.txt能够看到配置文件中有如下这样的ip 密码之类这样的信息dom
HeidiSQL配置文件节选:函数
Servers\Unnamed-2\SessionCreated<|||>1<|||>2017-01-20 13:32:21 Servers\Unnamed-2\Host<|||>1<|||>127.0.0.1 Servers\Unnamed-2\WindowsAuth<|||>3<|||>0 Servers\Unnamed-2\User<|||>1<|||>root Servers\Unnamed-2\Password<|||>1<|||>6A6A6A9 Servers\Unnamed-2\LoginPrompt<|||>3<|||>0 Servers\Unnamed-2\Port<|||>1<|||>3306 Servers\Unnamed-2\NetType<|||>3<|||>0 Servers\Unnamed-2\Compressed<|||>3<|||>0 Servers\Unnamed-2\LocalTimeZone<|||>3<|||>0 Servers\Unnamed-2\QueryTimeout<|||>3<|||>0 Servers\Unnamed-2\KeepAlive<|||>3<|||>0 Servers\Unnamed-2\FullTableStatus<|||>3<|||>1 Servers\Unnamed-2\Databases<|||>1<|||> Servers\Unnamed-2\Comment<|||>1<|||> Servers\Unnamed-2\StartupScriptFilename<|||>1<|||> Servers\Unnamed-2\SSHtunnelHost<|||>1<|||> Servers\Unnamed-2\SSHtunnelHostPort<|||>3<|||>0 Servers\Unnamed-2\SSHtunnelUser<|||>1<|||> Servers\Unnamed-2\SSHtunnelPassword<|||>1<|||>1 Servers\Unnamed-2\SSHtunnelTimeout<|||>3<|||>4 Servers\Unnamed-2\SSHtunnelPrivateKey<|||>1<|||> Servers\Unnamed-2\SSHtunnelPort<|||>3<|||>3307 Servers\Unnamed-2\SSL_Active<|||>3<|||>0 Servers\Unnamed-2\SSL_Key<|||>1<|||> Servers\Unnamed-2\SSL_Cert<|||>1<|||> Servers\Unnamed-2\SSL_CA<|||>1<|||> Servers\Unnamed-2\SSL_Cipher<|||>1<|||>
当时分析的过程中,我尝试去看HeidiSQL的源码中对密码编码解码的部分,稍微在GITHUB上搜索了一下,
不过没有定位到对应的代码段。哈哈,太水了。
我经过反复把密码填为a r 1 aaa aaaa rrrr 之类这样的,而后查ASCII码表和配置文件中的密码串对比,工具
终于发现了算出密码的规则,以密码aaa为例子,
在配置文件能够获得6A6A6A9
6A转为10进制获得106 减最后一位的9获得97,恰好能够对应ASCII码上的字母a,有3个6A,因此还能够还原获得aaa
也就是说前面的都是ASCII码,最后一位是偏移量,ASCII减偏移量就是对应的密码字符。网站
如下是在ipython中解码的演示
int("6A",16) Out[1]: 106 106 - 9 Out[2]: 97 chr(97) Out[3]: 'a'
如下是一个读取HeidiSQL 配置文件中的密码的python3代码:
# -*- coding: utf-8 -*- """ 2017-1-21 3:42:54 codegay """ import re settings = r"D:\临安初雨\Soft\HeidiSQL_9.4_Portable\portable_settings.txt" with open(settings,encoding="utf8") as f: lines = [r.strip() for r in f.readlines() if "\\Password<" in r] passwords = [re.split("\<\|\|\|\>",r)[-1] for r in lines] def heidipass(code): ascii = code[:-1] d = int(code[-1]) decode = lambda x:chr(int(x,16) - d) password = ''.join(map(decode,re.findall("\w{2}",ascii))) return password for r in passwords: print(heidipass(r))
HeidiSQL官方网站: http://www.heidisql.com/
HeidiSQL源码(非官方)https://github.com/HeidiSQL/HeidiSQL
ASCII码对照表 http://tool.oschina.net/commons?type=4 (没有16进制,差评)
2017-1-22 3:30:25 补充: 这个连接有其余用户帖出了各类语言版本的代码 https://gist.github.com/jpatters/4553139
2017-1-28 2:06:53 补充: Heidisql 源码中密码加密解密的函数名分别是encrypt decrypt:
https://github.com/HeidiSQL/HeidiSQL/blob/c62da41849ff943bf913ad76f16bc60c1653abc5/source/helpers.pas
为了防止原连接失效,我把代码摘出来:
{*** Password-encryption, used to store session-passwords in registry @param string Text to encrypt @return string Encrypted Text } function encrypt(str: String) : String; var i, salt, nr : integer; h : String; begin randomize(); result := ''; salt := random(9) + 1; for i:=1 to length(str) do begin nr := ord(str[i])+salt; if nr > 255 then nr := nr - 255; h := inttohex(nr,0); if length(h) = 1 then h := '0' + h; result := result + h; end; result := result + inttostr(salt); end; {*** Password-decryption, used to restore session-passwords from registry @param string Text to decrypt @return string Decrypted Text } function decrypt(str: String) : String; var j, salt, nr : integer; begin result := ''; if str = '' then exit; j := 1; salt := StrToIntDef(str[length(str)],0); result := ''; while j < length(str)-1 do begin nr := StrToInt('$' + str[j] + str[j+1]) - salt; if nr < 0 then nr := nr + 255; result := result + chr(nr); inc(j, 2); end; end;