Recovering TDE Encryption Keys

June 19, 2016 ❖ Tags: oracle, wallet, tde, encyption

There was a good discussion with some co-workers on database security, which really came down to locking down the OS accounts. Meaning, you can use technologies like Oracle TDE or Oracle Vault or Database Vault or Whatever Vault (™), but if the operating system isn’t secure then nothing is really. Frits Hoogland had mentioned that with tools like Linux’s shmcat you could attach to the OS memory and scrape whatever data happens to be available. If an encrypted database block is decrypted in the SGA then it is readable. Now, in cases where security is taken seriously then the OS is typically locked down, however, this got me thinking about what else is available in memory.

There was a financial institution that had lost its Oracle SSO Wallet password and due to compliance issues were forced to do a complete export and import with a new encryption key. Is it possible that the TDE encryption key is available in memory and if it is, is it possible to add just the key to a new wallet for TDE to use? Let’s see.

First off, environment:

[oracle@sandbox ~]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.5 (Tikanga)

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

My sqlnet.ora:

# sqlnet.ora Network Configuration File: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora
# Generated by Oracle configuration tools.

NAMES.DIRECTORY_PATH= (TNSNAMES)
ADR_BASE = /u01/app/oracle

#ENCRYPTION_WALLET_LOCATION=
#  (SOURCE=(METHOD=FILE)(METHOD_DATA=
#    (DIRECTORY=/u01/app/oracle/admin/ora11gr2/tde_wallet/)))

WALLET_LOCATION =
   (SOURCE =
     (METHOD = FILE)
     (METHOD_DATA =
       (DIRECTORY = /u01/app/oracle/admin/ora11gr2/tde_wallet)
     )
   )

#SQLNET.WALLET_OVERRIDE = TRUE
SSL_CLIENT_AUTHENTICATION = FALSE
SSL_VERSION = 0

Let’s set up an encryption key and create an encrypted tablespace.

SQL> !ls -l /u01/app/oracle/admin/ora11gr2/tde_wallet
total 0

SQL> alter system set encryption key identified by "abcd1234";

System altered.

SQL> !ls -l /u01/app/oracle/admin/ora11gr2/tde_wallet
total 4
-rw-r--r-- 1 oracle oinstall 1309 Sep  9 21:21 ewallet.p12

SQL> select * from v$encryption_wallet;

WRL_TYPE
--------------------
WRL_PARAMETER
--------------------------------------------------------------------------------
STATUS
------------------
file
/u01/app/oracle/admin/ora11gr2/tde_wallet
OPEN

SQL> alter system set encryption wallet close identified by "abcd1234";

System altered.

SQL> alter system set encryption wallet open identified by "abcd1234";

System altered.

SQL> create tablespace tde_tbs datafile '+DATA' size 1M encryption using 'AES256' default storage (encrypt);

Tablespace created.

SQL> create table t (id number) tablespace tde_tbs;

Table created.

SQL> insert into t (id) values (1);

1 row created.

SQL> commit;

Commit complete.

Ok, now let’s check out the contents of our wallet:

[oracle@sandbox ora11gr2]$ mkstore -wrl /u01/app/oracle/admin/ora11gr2/tde_wallet -list
Oracle Secret Store Tool : Version 11.2.0.2.0 - Production
Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.

Enter wallet password:
Oracle Secret Store entries:
ORACLE.SECURITY.DB.ENCRYPTION.AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ORACLE.SECURITY.DB.ENCRYPTION.MASTERKEY 

[oracle@sandbox ~]$ mkstore -wrl /u01/app/oracle/admin/ora11gr2/tde_wallet -viewEntry ORACLE.SECURITY.DB.ENCRYPTION.AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Oracle Secret Store Tool : Version 11.2.0.2.0 - Production
Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.

Enter wallet password:
ORACLE.SECURITY.DB.ENCRYPTION.AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA = AEMAASAAlQCipDUWe29wSWLzdQWbcCczxpeMYyL3isvGSFlOxO4DEABzWudMB81vL2m4qi51N/3kBQcAeHQDFw84NA==

Ok, everything looks good above, but let’s see what’s in memory.

[oracle@bbh ~]$ shmcat -M 0x74b5ac88 |grep --text ORACLE.SECURITY.DB.ENCRYPTION
…
																		 1▒@2nq▒▒H▒y䜰   JC=US,O="VeriSign, Inc.",OU=Class 2 Public Primary Certification AuthorityQ▒▒▒▒y䜰      0▒▒yIh▒y▒▒y9▒▒▒y䜰      ▒f~NE▒^Wo<▒^▒▒a▒▒▒y䜰   90▒40▒▒▒f0_1▒^Wo<*▒H▒▒
   0    UUS1 0U
dQ▒▒▒P/▒y䜰▒▒蕼▒▒▒▒P/▒y▒y @▒yAEMAASAAlQCipDUWe29wSWLzdQWbcCczxpeMYyL3isvGSFlOxO4DEABzWudMB81vL2m4qi51N/3kBQcAeHQDFw84NA==y▒▒▒h7▒y▒6▒▒6▒ORACLE.SECURITY.DB.ENCRYPTION.AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ▒▒▒h7▒y䜰      0R\p9▒yY▒▒▒h7▒y䜰       5AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAA0_1AI▒▒▒*▒H▒▒6▒▒▒yORACLE.SECURITY.DB.ENCRYPTION.MASTERKEYQ▒▒▒h7▒y䜰     0'4▒8▒y▒▒▒▒h7▒y▒6▒ ▒yp▒▒▒)4▒8▒{̺▒i▒▒▒▒9▒y▒6▒▒▒y0▒<0▒▒p▒▒▒)4▒8▒{̺▒0
   0    UUS10U

Hmmm. There is our key in memory and clear text. So, the next question is and sort of the point of this exercise, can we remove this wallet (pretending to lose the wallet or password) and add this encryption key to a newly created wallet?

[oracle@sandbox ora11gr2]$ mv tde_wallet tde_wallet_orig  
[oracle@sandbox ora11gr2]$ orapki wallet create -wallet /u01/app/oracle/admin/ora11gr2/tde_wallet -auto_login_local -pwd andyklock123 
Oracle PKI Tool : Version 11.2.0.2.0 - Production 
Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 

[oracle@sandbox ora11gr2]$ mkstore -wrl /u01/app/oracle/admin/ora11gr2/tde_wallet -createEntry ORACLE.SECURITY.DB.ENCRYPTION.MASTERKEY AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Oracle Secret Store Tool : Version 11.2.0.2.0 - Production 
Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 

Enter wallet password: 

[oracle@sandbox ora11gr2]$ mkstore -wrl /u01/app/oracle/admin/ora11gr2/tde_wallet -createEntry ORACLE.SECURITY.DB.ENCRYPTION.AZXbXU8xmE8ivy0/MkYbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AEMAASAAlQCipDUWe29wSWLzdQWbcCczxpeMYyL3isvGSFlOxO4DEABzWudMB81vL2m4qi51N/3kBQcAeHQDFw84NA== 
Oracle Secret Store Tool : Version 11.2.0.2.0 - Production 
Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 

[oracle@sandbox ora11gr2]$ sqlplus / as sysdba 
SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 24 11:00:43 2016 Copyright (c) 1982, 2010, Oracle. All rights reserved. 
Connected to an idle instance. 
SQL> startup;
ORACLE instance started.

Total System Global Area  534462464 bytes
Fixed Size                  2228200 bytes
Variable Size             327155736 bytes
Database Buffers          197132288 bytes
Redo Buffers                7946240 bytes
Database mounted.
Database opened.

SQL> select * from v$encryption_wallet;

WRL_TYPE
--------------------
WRL_PARAMETER
--------------------------------------------------------------------------------
STATUS
------------------
file
/u01/app/oracle/admin/ora11gr2/tde_wallet
OPEN


SQL> select * from andy.tde_t;

	ID
----------
	 1

That’s actually kind of messed up. My instance didn’t even know about my andyklock123 password. The beauty of SSO I guess… And not needed since I know the password of the wallet I just created…

For a sanity check, let’s make sure the wallet I hand cranked is actually being used:

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL>
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
[oracle@bbh ora11gr2]$ ls
adump  dpdump  pfile  tde_wallet
[oracle@bbh ora11gr2]$ mv tde_wallet tde_wallet_hold
[oracle@bbh ora11gr2]$ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 24 11:15:17 2016

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Enter user-name: / as sysdba
Connected to an idle instance.

SQL> startup;
ORACLE instance started.

Total System Global Area  534462464 bytes
Fixed Size                  2228200 bytes
Variable Size             327155736 bytes
Database Buffers          197132288 bytes
Redo Buffers                7946240 bytes
Database mounted.
Database opened.
SQL> select * from v$encryption_wallet;

WRL_TYPE
--------------------
WRL_PARAMETER
--------------------------------------------------------------------------------
STATUS
------------------
file
/u01/app/oracle/admin/ora11gr2/tde_wallet
CLOSED


SQL> select * from andy.tde_t;
select * from andy.tde_t
		   *
ERROR at line 1:
ORA-28365: wallet is not open

So, there you go. Another way to restore an encryption key :). Would you run shmcat on a production system? Probably not. Would you use it (or some other C program that scans memory) if you had to export/import a 15 TB tablespace? Maybe?

Either way, no matter what security features you’ve implemented, if you don’t lock down your keys and your operating systems you really aren’t as secure as you may think.