https://www.jianshu.com/p/d0a741c9439a
背景:最近公司生產環境通過堡壘機對數據庫進行接管。通過堡壘機配置PL/SQL工具,啟動后會自動進行用戶名密碼填充。這樣數據庫密碼就不需要暴露給運維人員,而且可以通過堡壘機進行日志審計。·
為了驗證堡壘機是通過認證模式進行連接還是通過填充密碼的模式進行連接,先將PL/SQL的密碼保存打開,然后通過堡壘機進行連接。連接成功后關閉PL/SQL並退出堡壘機。下次直接通過選擇記住的用戶進行登錄,發現可以直接登錄成功。說明,我司使用的堡壘機只是對用戶密碼,進行填充,並非采用認證轉發的模式。
如何設置PL/SQL密碼保存?
打開PL/SQL,依次進入目錄:工具->首選項->登錄歷史;
勾選存儲歷史及帶密碼存儲,點擊已確認,退出PL/SQL重新登錄。
成功登錄后會自動保存密碼,下次登錄時可以點擊用戶名右邊...按鈕,通過下拉的用戶列表進行選擇,選擇后PL/SQL會自動登錄,不需要再輸入密碼。PL/SQL默認存儲登錄信息,不存儲密碼。
如何解密PL/SQL保存的密碼?
數據
要想解密PL/SQL保存的密碼,首先,我們需要知道密碼存儲位置。PL/SQL將登錄信息及密碼存儲在user.prefs下。該文件一般存儲在如下位置。其中<username>是你的用戶名。
C:\Users<username>\AppData\Roaming\PLSQL Developer\Preferences<username>\
C:\Program Files\PLSQL Developer\Preferences<username>\
C:\Program Files (x86)\PLSQL Developer\Preferences<username>\
本人使用綠色版的PLSQL,存儲位置為:C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator 打開user.prefs文件,其中標題[LogonHistory]下面存在多行數字字符串,每一行即為一個登錄信息,這些信息是加密的,其明文格式如下:
<username>/<password>@<server>
算法
加密算法非常簡單,主要由位移和xor組成 。生成的密文看起來像這樣:
273645624572423045763066456443024120413041724566408044424900419043284194407643904160
第一組四位數(2736)是密鑰值-他是有系統運行時隨機生成的四位數(大於2000,小於3000),后面每一位字符根據下面算法進行運算得到4位數字,直至加密完畢。
下面是JAVA實現的加密代碼:
public static void cryptPassword() { int key = 2736; String plaintext = "user/password@server"; String result = Integer.toString(key); for (int i = 0; i < plaintext.length(); i++) { int mask = Integer.valueOf(plaintext.charAt(i)) << 4; int n = (mask ^ (key + (i + 1) * 10)) + 1000; result += Integer.toString(n); } System.out.println(result); }
user/password@server加密結果為:
273645624572423045763066456443024120413041724566408044424900419043284194407643904160
下面是JAVA實現的解密代碼:
public static void decryptPassword(){ String cryptText = "273645624572423045763066456443024120413041724566408044424900419043284194407643904160"; String plainText = ""; ArrayList<Integer> values = new ArrayList<Integer>(); for (int i = 0; i < cryptText.length(); i+= 4){ values.add(Integer.parseInt((cryptText.substring(i, i + 4)))); } int key = values.get(0); values.remove(0); for (int i = 0; i < values.size(); i++) { int val = values.get(i) - 1000; int mask = key + (10 * (i + 1)); int res = (val ^ mask) >> 4; plainText += Character.toString((char)(res)); } System.out.println("plainText:"+plainText); }
注意:生產環境切記不要開啟保存密碼的選項,否則本地環境一旦被人獲取,生產密碼將直接暴露,竊取者甚至不需要進行解密,直接將密文拷貝至PLSQL對應位置即可直接登錄。
通過上面的破解過程,說明這種模式的數據庫接管沒有實際意義,並不能規避密碼在內部泄露的問題。
參考資料:https://adamcaudill.com/2016/02/02/plsql-developer-nonexistent-encryption/
作者:tc_song
鏈接:https://www.jianshu.com/p/d0a741c9439a
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
