Call: +44 (0)1904 557620 Call
Blog

Pete Finnigan's Oracle Security Weblog

This is the weblog for Pete Finnigan. Pete works in the area of Oracle security and he specialises in auditing Oracle databases for security issues. This weblog is aimed squarely at those interested in the security of their Oracle databases.

[Previous entry: "New Oracle Security book - Oracle Incident Response and Forensics"] [Next entry: "Pete Finnigan Presented About Oracle Database Vault and Oracle Security"]

Grant DBA to yourself - exploit or not?



Yesterday Peter from the Master of Disaster Blog sent me an email to ask if I had seen the issue in his post before and whether it was a new exploit. I looked at the post and immediately recognised that this is not an exploit. Peter cannot grant DBA two himself as an exploit but he can do it because he first had granted system privileges that allow this. I could not post a blog post yesterday as I was teaching one of my online Oracle security classes.

As well as online Oracle security classes I will also be teaching my two day class - How to perform a security audit of an Oracle database in my home city of York, UK. There are still places left and if you would like to make the trip to York, please contact me to book your place. This class is taught by me and enables you to go away and secure your own databases

Whilst I had time first thing to do a quick demo and email Peter yesterday I didn't have time till now to write up a proper post; so here it is.

The blog post on Peters page has been updated to state that I sent him an explanation and the issue is not an exploit but the code he posted in the post linked above is pretty much the same. In the post Peter suggested that he could create a new user and then grant a bunch of roles and other grants to that user and then connect as the new user (although the actual connect was not shown) and then the new user was able to grant DBA to himself.

I did some tests based on Peters code. First i created a script tuser.sql based on the significant part of his script - granting IMP_FULL_DATABASE is the key. here is the script:


-- tuser.sql
create user tuser identified by tuser
default tablespace users
temporary tablespace temp;

GRANT CONNECT TO TUSER;

grant imp_full_database to tuser;

connect tuser/tuser@//192.168.1.95:1539/orcl.localdomain

grant dba to tuser;


I then ran this script as follows:


C:\_aa\PB\bin>sqlplus sys/oracle1@//192.168.1.95:1539/orcl.localdomain
as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Tue Oct 10 08:27:58 2017

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


Connected to:
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production

SQL> @tuser

User created.


Grant succeeded.


Grant succeeded.

Connected.

Grant succeeded.

SQL> sho user
USER is "TUSER"

SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
CONNECT
IMP_FULL_DATABASE
SELECT_CATALOG_ROLE
HS_ADMIN_SELECT_ROLE
EXECUTE_CATALOG_ROLE
HS_ADMIN_EXECUTE_ROLE

6 rows selected.


The role is not enabled as when you grant a role to yourself its not there by default. So log out and log back in at the TUSER and see if the DBA role is enabled:


SQL> connect tuser/tuser@//192.168.1.95:1539/orcl.localdomain
Connected.
SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
CONNECT
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_SELECT_ROLE
EXECUTE_CATALOG_ROLE
HS_ADMIN_EXECUTE_ROLE
CAPTURE_ADMIN
EXP_FULL_DATABASE
IMP_FULL_DATABASE
DATAPUMP_EXP_FULL_DATABASE
DATAPUMP_IMP_FULL_DATABASE

ROLE
--------------------------------------------------------------------------------
GATHER_SYSTEM_STATISTICS
OPTIMIZER_PROCESSING_RATE
EM_EXPRESS_ALL
EM_EXPRESS_BASIC
SCHEDULER_ADMIN
XDBADMIN
XDB_SET_INVOKER
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
OLAP_XS_ADMIN

ROLE
--------------------------------------------------------------------------------
OLAP_DBA

23 rows selected.

SQL>


The TUSER user now has the DBA role but as I said this is not an exploit or bug, its because the TUSER has IMP_FULL_DATABASE and in fact he needs to system privileges to grant the DBA role. GRANT ANY ROLE and GRANT ANY PRIVILEGE:


SQL> @who_has_priv



who_has_priv: Release 1.0.3.0.0 - Production on Sat Jun 10 03:57:39 2017
Copyright (c) 2004 PeteFinnigan.com Limited. All rights reserved.

PRIVILEGE TO CHECK [SELECT ANY TABLE]: GRANT ANY ROLE
OUTPUT METHOD Screen/File [S]:
FILE NAME FOR OUTPUT [priv.lst]:
OUTPUT DIRECTORY [DIRECTORY or file (/tmp)]:
EXCLUDE CERTAIN USERS [N]:
USER TO SKIP [TEST%]:

Privilege => GRANT ANY ROLE has been granted to =>
====================================================================
User => SYS (ADM = NO)
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
Role => DV_REALM_OWNER (ADM = NO) which is granted to =>
User => SYS (ADM = YES)
Role => IMP_FULL_DATABASE (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is
granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
Role => EM_EXPRESS_ALL (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
User => SPATIAL_CSW_ADMIN_USR (ADM = NO)

PL/SQL procedure successfully completed.

For updates please visit /tools.htm

SQL>
SQL> @who_has_priv



who_has_priv: Release 1.0.3.0.0 - Production on Sat Jun 10 04:25:11 2017
Copyright (c) 2004 PeteFinnigan.com Limited. All rights reserved.

PRIVILEGE TO CHECK [SELECT ANY TABLE]: GRANT ANY PRIVILEGE
OUTPUT METHOD Screen/File [S]:
FILE NAME FOR OUTPUT [priv.lst]:
OUTPUT DIRECTORY [DIRECTORY or file (/tmp)]:
EXCLUDE CERTAIN USERS [N]:
USER TO SKIP [TEST%]:

Privilege => GRANT ANY PRIVILEGE has been granted to =>
====================================================================
User => TUSER (ADM = NO)
Role => IMP_FULL_DATABASE (ADM = NO) which is granted to =>
User => SYS (ADM = YES)
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is
granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
Role => DV_REALM_OWNER (ADM = NO) which is granted to =>
User => SYS (ADM = YES)
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
User => GSMADMIN_INTERNAL (ADM = NO)
User => SYS (ADM = NO)
Role => EM_EXPRESS_ALL (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
Role => DBA (ADM = NO) which is granted to =>
User => TUSER (ADM = NO)
User => SYS (ADM = YES)
User => SYSTEM (ADM = NO)

PL/SQL procedure successfully completed.

For updates please visit /tools.htm

SQL>


As you can see from the above who_can_access script results the IMP_FULL_DATABASE has these rights. Logically you would expect that GRANT ANY ROLE would allow someone to grant the DBA role to themselves but this is not the case:


Peters-MacBook-Pro:____12_2 pxf$ sqlplus sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Wed Oct 11 11:43:29 2017

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


Connected to:
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production

SQL>
SQL> create user tuser identified by tuser;

User created.

SQL> grant create session to tuser;

Grant succeeded.

SQL> grant grant any role to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;
grant dba to tuser
*
ERROR at line 1:
ORA-01031: insufficient privileges


SQL>


If we also try and grant GRANT ANY PRIVILEGE then it fails differently:


SQL> connect sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba
Connected.
SQL> drop user tuser cascade;

User dropped.

SQL> create user tuser identified by tuser;

User created.

SQL> grant create session, grant any privilege to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;
grant dba to tuser
*
ERROR at line 1:
ORA-01924: role 'DBA' not granted or does not exist


SQL>


Finally, we need to grant both rights and the it works:


SQL> connect sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba
Connected.
SQL> drop user tuser cascade;

User dropped.

SQL> create user tuser identified by tuser;

User created.

SQL> grant create session, grant any role, grant any privilege to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;

Grant succeeded.

SQL>


So we actually need CREATE SESSION to connect, GRANT ANY ROLE and GRANT ANY PRIVILEGE to be able to grant DBA to ourselves. The reason the original code by Peter works is because he granted IMP_FULL_DATABASE to his user; so no exploit and no bug. The issue is because this role has these two system privileges. The IMP_FULL_DATABASE role is very dangerous and is as good as SYSDBA. This is because it also has ALTER USER and we can then change the SYS password and become SYSDBA. Do not grant IMP_FULL_DATABASE or rights such as GRANT ANY%.

Remember about my classes and please register if you would like to join a class especially the live Work class at the end of October.