oracle 密碼詳解以及破解

翰墨文海發表於2021-07-25

參考的相關資料等:

https://docs.oracle.com/en/database/oracle/oracle-database/18/spmsu/finding-and-resetting-user-passwords-10g-password-version.html#GUID-D7B09DFE-F55D-449A-8F8A-174D89936304

http://marcel.vandewaters.nl/oracle/security/password-hashes

https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/

 

實驗環境:

oracle:11.2.4環境升級到了19C(11g升級前建的使用者密碼是不區分大小寫的)

 一.Oracle密碼記錄以及大小寫敏感和優先順序

在10G版本的時候,使用者密碼存在dba_users檢視中,在11.1之前的版本,可以通過alter user identified by values password 來還原oracle 資料庫歷史密碼(當年在電網運維做二級等保的時候,就發現了10g,11g重置密碼不一樣),但是在11g以及以上版本中出現一下特性:

1. dba_users中無password記錄(值為空),這個可以通過直接查詢user$.password依然有記錄。

2.通過修改USER$.SPARE4為空實現了遮蔽ORACLE 11g,12C以及以上版本密碼大小寫敏感(password_versions優先順序大於sec_case_sensitive_logon)

 

如下:

col name for a20
col password for a40
col spare4 for a40
select name,password,SPARE4 from user$ WHERE name='SYSTEM';

 

 SELECT a.username,a.password_versions FROM dba_users a WHERE a.username='SYSTEM';

 

PASSWORD_VERSIONS列顯示該帳戶存在的密碼版本的列表。10G指的是較早的不區分大小寫的Oracle密碼版本,11G指的是基於SHA-1的密碼版本,並12C指的是基於SHA-2的SHA-512密碼版本。

 

 

 

 

 本次測試使用者SYSTEM的SPARE4為空,從低版本(10g)匯入到11g中的使用者登入是不區分大小寫,而11g本身建立的使用者是區分大小寫(預設sec_case_sensitive_logon為true,區分大小寫),而他們的區別僅僅是在dba_users.password_versions為10G,USER$.SPARE4列為空(10g的該列為空),說明sec_case_sensitive_logon 根本沒有起到作用;

ALTER USER system PASSWORD EXPIRE;  --登陸提示修改密碼或者直接執行修改密碼(我是直接修改密碼的)
alter user system identified by "oracle";

 

 

重置密碼後,dba_users.password_versions變成10G 11G 12C了;SPARE4有值了。
在測試重新登入:

 

 等我把SPARE4修改成空值後再試一下:

 

select name,password,SPARE4 from user$ WHERE name='SYSTEM';

UPDATE user$ a SET a.spare4='' WHERE name='SYSTEM';
COMMIT;
select name,password,SPARE4 from user$ WHERE name='SYSTEM';

alter system flush shared_pool;

 

 綜上所述,說明password_versions(變成了10g,11g,12C)的優先順序大於sec_case_sensitive_logon這個引數,在sec_case_sensitive_logon下(還是為true),如果我修改了USER$.SPARE4(為空),可以實現不區分密碼大小寫的問題;

spare4 可以進行密碼重新整理:既可以用USER$中的PASSWORD,也可以用USER$中的SPARE4

  12C:

SELECT ' alter user ' || NAME || ' identified by values ''' ||B.SPARE4 || ''';' AS reset_password
FROM SYS.USER$ B
INNER JOIN DBA_USERS A
ON B.NAME = A.USERNAME
WHERE ACCOUNT_STATUS = 'OPEN'
and a.username<>'SYS'
and b.spare4 is not null;

11g:

select ' alter user ' || name ||' identified by values '''||password ||''';' from sys.user$
where name in (select username from dba_users
where ACCOUNT_STATUS<>'LOCK' and ACCOUNT_STATUS not like 'EXPIRED%LOCKED');

  但是通過測試values user$.spare4恢復以前密碼後,user$.password列為空(SYS使用者除外,其他使用者為空,且由於12.2之後 ORACLE 口令檔案,存放至ASM裡面,因此無法再通過alter user sys identified by 'values'重置SYS密碼,登陸提示密碼錯誤,如果用user$.password重置密碼,那麼spare4為空,且PASSWORD_VERSIONS版本會下降成10g,就不會區分大小寫了,但是密碼依舊區分大小寫。這裡可以看出來,user$.password項以後可能取消掉,為了相容性,因此Oracle在後續版本中依舊保留.

 二.oracle使用者密碼的加密方法

10g中使用基於DES的版本,在11g中,它使用基於SHA1密碼的版本,從11g第1版開始的區分大小寫的密碼,在12c中使用基於SHA-2的SHA-512密碼版本,Oracle在Oracle Database 12c中對使用者密碼雜湊進行了改進。通過使用基於PBKDF2的SHA512雜湊演算法,替代過去簡單的SHA1雜湊加密,使得密碼雜湊更安全。

 

2.1 10g雜湊的過程

  • 將使用者名稱轉換為使用者名稱的大寫版本(使用者名稱sys變為SYS)
  • 將密碼轉換為密碼的大寫版本(密碼測試變為TEST)
  • 縮寫的使用者名稱和密碼(使用者名稱SYS,密碼TEST變為SYSTEST)
  • 使用(永久-始終相同)金鑰對(使用3DES演算法的)隱式值進行加密
  • 使用祕密金鑰加密(使用3DES演算法)隱含值(此金鑰是第一次加密的最後8個位元組)
  • 實際的密碼雜湊值將是第二輪加密的最後8個位元組,以這8個位元組的可讀十六進位制表示形式儲存-因此為16個字元)

 

2.2 11g雜湊的過程

  • Oracle生成一個10位元組的SALT(看起來是隨機的)
  • 密碼(區分大小寫)和SALT(10位元組)的值變為無效
  • 生成SHA1雜湊值作為隱含值
  • 11g密碼雜湊變為:“ S:”加< SHA1雜湊-可讀的十六進位制表示形式>加< SALT-可讀的十六進位制表示形式,20個字元>

 

2.3 12C雜湊的過程

 Oracle 對 Oracle Database 12c 中的使用者密碼雜湊進行了改進。通過使用基於 PBKDF2 的 SHA512 雜湊演算法,而不是簡單的 SHA1 雜湊,密碼雜湊更加安全。對於 Oracle 資料庫 11g, 表中spare4 列sys.user$儲存使用者密碼雜湊。

create user demo identified by epsilon;
select spare4 from sys.user$ where name = 'DEMO';

select password from sys.user$ where name = 'DEMO';

 

  spare4為:

S:50C53B964CACCA700E7B751778985731F605D97C8D5CA32736AAD3A912D9;T:A0A64DCB72163A1
81B123131B7FAE450628103507607E7EF4BEA88D7FA6762B238ABDA7027EFD1436F0AFAC2AFF8DB3
BB17CB0D0A85358D195CD619C84F3969894B02274CAF970584059A7C09565C1F0

sys.user$.password為:

2B7983437FE9FEB6(大寫並連線使用者名稱和密碼,然後進行 3DES 雜湊計算)

  

 該spare4 列的值有三個部分(“ S:‘‘ H:’和’ T:”)用分號隔開;然而,我在用19c測試的時候,已經沒有H:部分了。只有S:和T:部分。

 

  •  “ S:”部分長度為 60 個字元或 30 個位元組:

 50C53B964CACCA700E7B751778985731F605D97C8D5CA32736AAD3A912D9

在 Oracle 資料庫 11g 中有“ S:”部分,它的建立方式如下:

password hash (20 bytes) = sha1(password + salt (10 bytes))

Oracle Database 12c 也是如此:下面的簡單測試證明了這一點。

對於S 上述 ( 50C53B964CACCA700E7B751778985731F605D97C8D5CA32736AAD3A912D9) 中

雜湊是50C53B964CACCA700E7B751778985731F605D97C8D5CA32736AAD3A912D9

密碼是“ epsilon”,所以計算 SHA1 雜湊值'epsilon' + 8D5CA32736AAD3A912D9

import hashlib
sha1 = hashlib.sha1()
sha1.update("epsilon")
sha1.update('\x8D\x5C\xA3\x27\x36\xAA\xD3\xA9\x12\xD9')
sha1.hexdigest().upper()

該計算產生:

' 50C53B964CACCA700E7B751778985731F605D97C8D5CA32736AAD3A912D9'

這與 11g 演算法相同。

 

  • H:" 部分長度為 32 個字元或 16 個位元組: (19c沒有) 

H部分

在檢視下$ORACLE_HOME/rdbms/admin 一個SQL 檔案時可以發現這一點:

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' 和密碼用冒號分隔:

import hashlib
m = hashlib.md5()
m.update('DEMO:XDB:epsilon')
m.hexdigest().upper()
'DC9894A01797D91D92ECA1DA66242209'

 

 

 

這使得可以使用預先計算的雜湊值來攻擊內建使用者密碼,這些雜湊值以諸如“ SYSTEM:XDB:”之類的常量為字首的字典單詞

H 值似乎用於 XDB 中的摘要式身份驗證。

 

  • “ T:”部分長度為 160 個字元或 80 個位元組:

A0A64DCB72163A1
81B123131B7FAE450628103507607E7EF4BEA88D7FA6762B238ABDA7027EFD1436F0AFAC2AFF8DB3
BB17CB0D0A85358D195CD619C84F3969894B02274CAF970584059A7C09565C1F0

讓我們僅通過更新sqlnet.ora 檔案來啟用 12c 密碼雜湊(假設客戶端也來自 12.1.0.2 發行版):

# sqlnet.ora
SQLNET.ALLOWED_LOGON_VERSION_SERVER = 12a

 

 

drop user demo;

create user demo identified by epsilon;

select spare4 from sys.user$ where name = 'DEMO';

H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B

 

請注意,該spare4 值不再具有S: 部件,只有T: 元件在那裡。

關於 12C 驗證器
基於涉及 PBKDF2 和 SHA512 的去優化演算法...

所以密碼應該通過 PBKDF2 處理,然後是 SHA512 以生成T.

在身份驗證期間,伺服器向客戶端傳送所謂的AUTH_VFR_DATA (匹配值的最後 16 個位元組spare4.T ):

-- 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 個位元組和AUTH_VFR_DATA):

E3C3E63EFDC9CC837FBF7BFC2225B5E6CF0273C6B3C02BE0C7501A29E4A79FC0172132661D9135D79F2A514BD72028AF77157DEEB8983993EA93067771760FFF(前 128 個字元或 64 個位元組)
2029784967FA795BBF7D3E1699D5F30F(後 32 個字元或 16 個位元組 - AUTH_VFR_DATA

讓我們假設AUTH_VFR_DATA 密碼是設定/重置時隨機生成的。因此,生成前 64 個位元組的 Python 程式碼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驗證器存在,通過抓包,可以通過暴力破解來獲取Oracle的密碼,有關抓包的資訊請自行查詢

 

三.oracle密碼的破解

首先,如果在生產上有許可權做相關的操作,不太建議做這種不道德的事情,但是測試環境做一下是可以的

很多網上的破解工具:orabf-v0.7.6,ops_sse2(這個只能破解sys的)

ops_sse2下載地址:http://conus.info/utils/ops_SIMD/

我用的是orabf-v0.7.6

 

簡單密碼測試:

 

 

 

 

破解成功:oracle

稍微複雜的密碼測試:

 

有特殊字元的密碼測試:

 

 

 

 如果稍微複雜的密碼,orabf-v0.7.6破解也同樣是遙遙無期(計算機效能好一點可能會稍微好一點)。

tar -xf ops_SIMD_linux86.tar

linux

yum -y install libstdc++.so.6

./ops_sse2

 

 

 含特殊字元或者長度稍長一點的複雜密碼試一下

 

 

當然我自己建的一個使用者,密碼9位,嗯,ops_sse2也是夠嗆了,也只能破解如oracle這種預設密碼,說實話,我自己都可以猜測測試一下,這種的簡單密碼!

  https://codeload.github.com/Seabreg/thc-orakelcrackert11g/zip/master

 

 

 

 

 

相關文章