/* _____________________________________________________________________________ Subject: Oracle 10g TNS AES-128 authentication details Authors: Massimiliano Montoro Issue date: July, 1, 2008 ______________________________________________________________________________ This code shows the encryption algorithm used by Oracle 10g TNS protocol authentication. Recently I found on the Internet interesting articles about Oracle TNS security but no one of them covers the algorithm used by version 10g in details. The following documents: http://www.pwc.com/extweb/service.nsf/docid/3AC99308583CCE398025727400391E31/$file/oraauthdg_pub.pdf http://freeworld.thc.org/papers/thc-orakelsniffert.pdf do not describe the AES algorithm used by Oracle TNS 10g and the article http://soonerorlater.hu/index.khtml?article_id=511 only descrybe the oracle DLL functions used by it. The software "oradecrypt" at this link http://www.soonerorlater.hu/download/oradecrypt.zip can be used to check the correctness of encrypted authentication parameters AUTH_PASSWORD and AUTH_SESSKEY sent on the network but because it uses the native "oran10.dll" functions it is not useful to prove the effort made by Oracle guys to improve the security of TNS authentication protocol from version 8i and 9i to version 10g. Test authentication parameters captured from the network: username: TESTUSER AUTH_SESSKEY: EEABE812530C6D4432F781DFC14A7C7F81EAE1804F340D3289732477FD351FCC AUTH_SESSKEY_CLIENT: 7B244D7A1DB5ABE553FB9B7325110024911FCBE95EF99E7965A754BC41CF31C0 AUTH_PASSWORD: 4C5E28E66B6382117F9D41B08957A3B9E363B42760C33B44CA5D53EA90204ABE The following code will show the AES-128 encryption algorithm to be used in order to check the correctness of the password "TESTPASS" associated to the Oracle username "TESTUSER". NOTE: The following code does not use native functions of "oran10.dll" but the algorithm has been adapted to work with OpenSSL software. The code could be incomplete but correct enough to prove the concept. __________________________________________________________________________ The information in this document is provided "AS IS" without warranty of any kind. In no event shall the authors be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages due to the misuse of any information provided in this document and in the use of the software compiled from the following code. ______________________________________________________________________________ */ // filename: oracle_tns_aes128_check.cpp #include "windows.h" #include #include #include //********************************************************************************************************************* // Hashes captured on the network during authentication phase unsigned char AUTH_SESSKEY [] = {0xEE,0xAB,0xE8,0x12,0x53,0x0C,0x6D,0x44,0x32,0xF7,0x81,0xDF,0xC1,0x4A,0x7C,0x7F,0x81,0xEA,0xE1,0x80,0x4F,0x34,0x0D,0x32,0x89,0x73,0x24,0x77,0xFD,0x35,0x1F,0xCC}; unsigned char AUTH_SESSKEY_C[] = {0x7B,0x24,0x4D,0x7A,0x1D,0xB5,0xAB,0xE5,0x53,0xFB,0x9B,0x73,0x25,0x11,0x00,0x24,0x91,0x1F,0xCB,0xE9,0x5E,0xF9,0x9E,0x79,0x65,0xA7,0x54,0xBC,0x41,0xCF,0x31,0xC0}; unsigned char AUTH_PASSWORD [] = {0x4C,0x5E,0x28,0xE6,0x6B,0x63,0x82,0x11,0x7F,0x9D,0x41,0xB0,0x89,0x57,0xA3,0xB9,0xE3,0x63,0xB4,0x27,0x60,0xC3,0x3B,0x44,0xCA,0x5D,0x53,0xEA,0x90,0x20,0x4A,0xBE}; //********************************************************************************************************************* unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; int ORACLE_Hash (char* username, char *passwd, int passwd_len, unsigned char* oracle_hash) { char ToEncrypt[256]; char temp[256]; DES_cblock iv,iv2; DES_key_schedule ks1, ks2; int len=0; int j,ulen,plen; memset (ToEncrypt,0,sizeof(ToEncrypt)); strupr (username); strupr (passwd); ulen = strlen(username); plen = passwd_len; for (len=1,j=0; j 126)) break; } ascii_len = pos; padding_byte = ascii_string_not_terminated[pos]; for (;pos\n"); printf ("*************************************************************\n\n"); // Create Oracle Hash from username and password ORACLE_Hash (username, password, strlen (password), Oracle_Hash); // Decrypt AUTH_PASSWORD int passlen = ORACLE_TNS_Decrypt_Password_10g (Oracle_Hash, AUTH_SESSKEY, AUTH_SESSKEY_C, AUTH_PASSWORD, 32, decrypted_password); if (passlen != -1) { printf ("Decrypted password: %s ", decrypted_password); if (strcmp (decrypted_password, "TESTPASS") == 0) printf ("(correct)\n\n"); else printf ("(failed)\n\n"); } else printf ("Couldn't decrypt password\n\n"); return 0; }