您好,登錄后才能下訂單哦!
密碼哈希值在Oracle 12c數據庫中調整
Simeon
原文鏈接:
https://www.trustwave.com/Resources/SpiderLabs-Blog/Changes-in-Oracle-Database-12c-password-hashes/
Oracle在Oracle Database 12c中對用戶密碼哈希進行了改進。通過使用基于PBKDF2的SHA512哈希算法,替代過去簡單的SHA1哈希加密,使得密碼哈希更安全。在這篇文章中,我將解釋一些變化及其安全影響。
1.Oracle密碼哈希值
使用Oracle 11g數據庫時,sys.user$表中的spare4列存儲用戶密碼哈希值。
這是sys.user$.spare4 用戶demo使用密碼“epsilon”(可插入數據庫)的輸入示例:
S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C
詳細步驟:
SQL> create user demo identified by epsilon;
User created.
SQL> select spare4 from sys.user$ where name = 'DEMO';
S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C
筆者注:查詢oracle用戶必須是大寫名稱
sys.user$.password跟demo用戶的密碼值一樣:
SQL> select password from sys.user$ where name = 'DEMO';
運行結果:
2B7983437FE9FEB6
筆者注:
執(zhí)行查詢select password from sys.user$ where name = SYS';如圖1所示。
圖1獲取SYS用戶密碼值
這將省略password值的討論:它使用相同的算法(大寫和連接用戶名和密碼,然后執(zhí)行3DES散列)計算,跟以前的Oracle數據庫版本中使用一樣的算法。
在spare4 列的值由分號分隔(“ S:”,“ H:”和“ T:”)的三個部分組成。
“S:”部分長度是60個字符或30個字節(jié):
8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A
“ H:”部分長度是32個字符或16個字節(jié):
DC9894A01797D91D92ECA1DA66242209
最后,“ T:”部分長度是160個字符或80個字節(jié):
23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C
那么他們究竟有什么含義呢?
2.S部分
在Oracle數據庫11g中有“ S:”部分,它的創(chuàng)建過程如下:
password hash (20 bytes) = sha1(password + salt (10 bytes))
(有關更多詳細信息,請訪問http://marcel.vandewaters.nl/oracle/security/password-hashes。)
Oracle Database 12c也是如此:下面的簡單測試證明了這一點。
對于S上面的值(8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A):
哈希是8F2D65FB5547B71C8DA3760F10960428CD307B1C,salt是6271691FC55C1F56554A
密碼是“epsilon”,所以讓我們來計算SHA1哈希'epsilon' + 0x6271691FC55C1F56554A:
import hashlib
sha1 = hashlib.sha1()
sha1.update("epsilon")
sha1.update('\x62\x71\x69\x1f\xc5\x5c\x1f\x56\x55\x4a')
sha1.hexdigest().upper()
該計算產生:' 8F2D65FB5547B71C8DA3760F10960428CD307B1C',如圖2所示。
圖2計算epsilon的密碼值
這與11g算法相同。
3.H部分
在$ORACLE_HOME/rdbms/admin下查看一個SQL文件時可以發(fā)現這一點:
create or replace view DBA_DIGEST_VERIFIERS
(USERNAME, HAS_DIGEST_VERIFIERS, DIGEST_TYPE) as
select u.name, 'YES', 'MD5' from user$ u where instr(spare4, 'H:')>0
union
select u.name, 'NO', NULL from user$ u where not(instr(spare4, 'H:')>0) or spare4 is null
/
所以它似乎是一個MD5哈希加密。
請注意,下面的SQL代碼$ORACLE_HOME/rdbms/admin 會修改spare4 列的值以刪除H: 降級。
這是spare4.H如何計算的:用戶名是大寫的,然后MD5哈希加密計算其值,' XDB'和密碼用冒號分隔(也即md5('DEMO:XDB:epsilon'),32位加密):
import hashlib
m = hashlib.md5()
m.update('DEMO:XDB:epsilon')
m.hexdigest().upper()
'DC9894A01797D91D92ECA1DA66242209'
這使得可以使用預先計算密碼字典的散列值來對內置的用戶密碼進行***,例如使用前綴SYSTEM:XDB:的系統(tǒng)用戶密碼。
該H值似乎用于XDB中的摘要式身份驗證。
4.T部分
這僅適用于12.1.0.2。對于12c之前的版本,T部分不可用。
我們通過更新sqlnet.ora 文件(假設客戶端來自12.1.0.2發(fā)行版)來啟用12c密碼哈希:
# sqlnet.ora
SQLNET.ALLOWED_LOGON_VERSION_SERVER = 12a
然后重新創(chuàng)建演示用戶(首先重新連接客戶端):
drop user demo;
create user demo identified by epsilon;
select spare4 from sys.user$ where name = 'DEMO';
H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B
注意到該spare4值不再包含“S:”部分,只有“H:”部分和“T:”部分在那里。
在Oracle Database 12c文檔中,我們可以找到這個:
5.關于12C驗證器
基于一個包含PBKDF2和SHA512的優(yōu)化算法,所以密碼應該通過PBKDF2,隨后SHA512來生成T(部分)。在認證期間,服務器發(fā)送所謂的AUTH_VFR_DATA (匹配值spare4.T的最后16個字節(jié))到客戶端:
-- Server to client packet snippet
39 39 39 00 00 00 00 0D-00 00 00 0D 41 55 54 48 999.........AUTH
5F 56 46 52 5F 44 41 54-41 20 00 00 00 20 38 44 _VFR_DATA.....8D
44 31 42 45 33 46 36 37-42 46 46 39 38 31 33 41 D1BE3F67BFF9813A
34 36 34 33 38 32 33 38-31 41 42 33 36 42 15 48 464382381AB36B.H
所以我們可以把這個T 值分成兩部分(前64個字節(jié)和AUTH_VFR_DATA):
E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD (前128個字符或64個字節(jié))8DD1BE3F67BFF9813A464382381AB36B (最后32個字符或16個字節(jié)AUTH_VFR_DATA)
假設AUTH_VFR_DATA 密碼設置/重置時隨機生成。因此Python代碼生成的第一個64字節(jié)T 是(需要PBKDF2 Python模塊):
import pbkdf2, hashlib
AUTH_VFR_DATA = b'\x8d\xd1\xbe\x3f\x67\xbf\xf9\x81\x3a\x46\x43\x82\x38\x1a\xb3\x6b' # This is received from the server once the latest protocol is negotiated
salt = AUTH_VFR_DATA + b'AUTH_PBKDF2_SPEEDY_KEY'
key = pbkdf2.PBKDF2("epsilon", salt, 4096, hashlib.sha512) # Password
key_64bytes = key.read(64) # This 64-byte derived key is encrypted by the client and sent to the server as AUTH_PBKDF2_SPEEDY_KEY
t = hashlib.sha512() # This happens on the server after they key is decrypted from the AUTH_PBKDF2_SPEEDY_KEY value
t.update(key_64bytes)
t.update(AUTH_VFR_DATA)
t.hexdigest().upper() # First 64 bytes of spare4.T: value if password is correct
運行結果:
E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD
總結
Oracle在12c中添加了MD5哈希和基于PBKDF2的SHA512哈希加密。在Oracle文檔中有一個引用:
用于生成12C 驗證的哈希密碼函數是基于包含PBKDF2和SHA-512的非優(yōu)化算法。PBKDF2算法通常被介紹為當擁有12C的驗證者找回原密碼時,面對***者所面臨的挑戰(zhàn)時的非對稱計算算法。
筆者注:由于Oracle 12C驗證器存在,通過抓包,可以通過暴力破解來獲取Oracle的密碼,后續(xù)內容為筆者補充。
6.PBKDF2簡介及其算法
(1)PBKDF2簡介
PBKDF2簡單而言就是將salted hash進行多次重復計算,這個次數是可選擇的。如果計算一次所需要的時間是1微秒,那么計算1百萬次就需要1秒鐘。假如***一個密碼所需的rainbow table有1千萬條,建立所對應的rainbow table所需要的時間就是115天。這個代價足以讓大部分的***者忘而生畏。
(2)PBKDF2算法
DK = PBKDF2(P,S,c,dkLen)
可選項: RPF 基本偽隨機函數(hLen表示偽隨機函數輸出的字節(jié)長度)
輸入:
P 口令,一字節(jié)串
S 鹽值,字節(jié)串
c 迭代次數,正整數
dkLen 導出密鑰的指定字節(jié)長度,正整數,最大約(2^32-1)*hLen
輸出: DK 導出密鑰,長度dkLen字節(jié)
步驟:
1. 如果dkLen>(2^32-1)*hLen,輸出“derived key too long”并停止。
2. 假設l是導出密鑰的hLen個字節(jié)塊的個數,r表示最后一個塊的字節(jié)數。
l = CEIL (dkLen / hLen) ,
r = dkLen - (l - 1) * hLen .
這里,CEIL(x)是“ceiling”函數,即,大于或等于x的最小整數。
4. 對于導出密鑰的每一塊,運用函數F于口令P、鹽S、迭代次數c和塊索引以計算塊:
T_1 = F (P, S, c, 1) ,
T_2 = F (P, S, c, 2) ,
...
T_l = F (P, S, c, l) ,
這里函數F定義為基本偽隨機函數PRF應用于口令P和鹽S的串聯(lián)和塊索引i的前c次循環(huán)的異或和。
F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
其中
U_1 = PRF (P, S || INT (i)) ,
U_2 = PRF (P, U_1) ,
...
U_c = PRF (P, U_{c-1}) .
這里,INT(i)是整數i的四字節(jié)編碼,高字節(jié)在先。
3. 串聯(lián)各塊,抽取前dkLen字節(jié)以產生導出密鑰DK:
DK = T_1 || T_2 || ... || T_l<0..r-1>
4. 輸出導出密鑰DK。
注意:函數F的構造遵循“belt-and-suspenders”方法。U_i次循環(huán)被遞歸計算以消除敵手的并行度;它們被異或到一起以減少有關遞歸退化到一個小的值集的擔憂。
密碼解密:
select username, password from dba_users;
hashcat -m 10200 -a 0 oracle.hash -o oracle.txt --remove oracle.hash wordlist.txt
hashcat -m 1800 -a 3 oracle.hash ?d?d?d?d?d?d?d?d?d?d?d
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。