讀取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;