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: "Can We Add New Language Features to PL/SQL?"]

Can we Hack an Oracle APEX Application?

I talked recently about securing APEX and the different security angles that should be considered when securing data in application that is written using APEX and hosted in an Oracle database. There are multiple attack vectors from a web based attack using SQL Injection through to abusing the APEX security or indeed just accessing the data directly in the schema tables in the database. A lot of the possible attack vectors are possible often due to design or configuration issues.

Let us be clear the security necessary to secure data in your database whether the application is written using APEX or any other tool is up to you. You must apply security for data at these levels (we will use APEX as an example here) and we will discuss some possible high level attacks against data:

  • Operating System security: If an attacker can access the OS directly then they could access database data files and steal data

  • Network Security: If an attacker can access the network un-encrypted then the attacker could sniff data

  • Database Configuration (hardening): If the database is not hardened and security configured then an internal DBA, developer, support person or end user with a database account could exploit settings and hardening to gain access to data

  • Patches: If the OS, network or database is not patched then there could be vulnerabilities that can be exploited that could allow access to data

  • Data Security in the database: This is the core issue for security of data. There are limitless ways to attack the data and this depends on the design and permissions. For instance if the designer granted SELECT or READ on business data then no clever exploit is needed and any database account can read the data

  • APEX application hardening and security: If the instance permissions are set incorrectly then many types of attacks are possible

  • APEX workspace security: If all pages are public the data can simply be accessed via the web application


Using APEX as an example we know that Oracle internally uses a package SYS.DBMS_SYS_SQL that allows its processing to build a web page from the APEX. This package allows code to be accessed as any database user when used directly.

This is not about APEX per-se, its just an example that could apply to any application

How is this DBMS_SYS_SQL package exposed in the database?

SQL> set serveroutput on
SQL> @sc_who_can_access
Enter value for output_method: S
old 206: lv_file_or_screen:= upper('&&output_method');
new 206: lv_file_or_screen:= upper('S');
Enter value for owner_to_find: SYS
Enter value for object_to_find: DBMS_SYS_SQL
old 207: write_op('Checking object => '||upper('&&owner_to_find')||'.'||upper('&&object_to_find'));
new 207: write_op('Checking object => '||upper('SYS')||'.'||upper('DBMS_SYS_SQL'));
old 209: get_obj(upper('&&object_to_find'),upper('&&owner_to_find'));
new 209: get_obj(upper('DBMS_SYS_SQL'),upper('SYS'));
Checking object => SYS.DBMS_SYS_SQL
====================================================================



PL/SQL procedure successfully completed.

SQL>

The dangerous procedure in this package is PARSE_AS_USER() as that can be used to execute code as any other user including SYS or SYSTEM or any other DBA or powerful account such as a schema owner; therefore allowing access to any data.

We can check now what other database objects are using DBMS_SYS_SQL:

SQL> set lines 220
SQL> col owner for a30
SQL> col name for a30
SQL> col type for a30
SQL> l
1* select owner,name,type from dba_dependencies where referenced_name='DBMS_SYS_SQL'
SQL> /

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
SYS DBMS_STATS_INTERNAL PACKAGE
SYS DBMS_LOGREP_UTIL PACKAGE
SYS DBMS_SQL PACKAGE BODY
SYS DBMS_SYS_SQL PACKAGE BODY
SYS DBMS_SNAPSHOT_UTL PACKAGE BODY
SYS DBMS_IREFRESH PACKAGE BODY
SYS DBMS_SNAP_INTERNAL PACKAGE BODY
SYS DBMS_RECO_SCRIPT_INVOK PACKAGE BODY
SYS DBMS_STREAMS_ADM_UTL PACKAGE BODY
SYS DBMS_LOGREP_UTIL PACKAGE BODY
SYS DBMS_FILE_GROUP_UTL PACKAGE BODY

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
SYS DBMS_DATA_GUARD_INTERNAL PACKAGE BODY
SYS DBMS_RESOURCE_MANAGER PACKAGE BODY
SYS DBMS_AQADM_SYS PACKAGE BODY
SYS DBMS_STATS PACKAGE BODY
SYS DBMS_STATS_INTERNAL PACKAGE BODY
SYS DBMS_DDL PACKAGE BODY
SYS DBMS_GSM_FIXED PACKAGE BODY
SYS DBMS_GSM_GSMUSER PACKAGE BODY
SYS DBMS_TRANSACTION PACKAGE BODY
SYS DBMS_EXPORT_EXTENSION PACKAGE BODY
SYS OLS_ENFORCEMENT PACKAGE BODY

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
SYS DBMS_PRVTAQIP PACKAGE BODY
SYS LOGMNR_DICT_CACHE PACKAGE BODY
SYS DBMS_LOGMNR_LOGREP_DICT PACKAGE BODY
SYS KUPD$DATA PACKAGE BODY
SYS DBMS_REDEFINITION_INTERNAL PACKAGE BODY
SYS DBMS_REDEFINITION PACKAGE BODY
SYS DBMS_SPACE PACKAGE BODY
SYS DBMS_DST PACKAGE BODY
SYS XS_DATA_SECURITY_UTIL PACKAGE BODY
SYS DBMS_SQL_TRANSLATOR_EXPORT PACKAGE BODY
SYS WWV_DBMS_SQL_APEX_220200 PACKAGE BODY

33 rows selected.

SQL>

Wow, that's a lot of packages in a 23 version database that use this dangerous package.

DBMS_SQL uses this package, Label security uses it, Real Application Security uses it, Log Miner uses it, Advanced Queuing uses it, SQL Translation and more...

So, the use of this package is extensive and used by SYS in a lot of cases.

There are other ways to achieve the same result as an attacker; i.e. there are other ways in the database to execute code as another user.

The package SYS.WWV_DBMS_SQL_APEX_220200 is clearly the APEX package that is used by APEX to access DBMS_SYS_SQL so we should look deeper at this. This package also has a PARSE_AS_USER() function. We do not know if this includes any protection to prevent misuse or is a thin wrapper. The package description includes:

SQL> desc WWV_DBMS_SQL_APEX_220200
PROCEDURE CLEAR_ERROR_BACKTRACE
...
PROCEDURE PARSE_AS_USER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
P_CURSOR NUMBER(38) IN
P_QUERY VARCHAR2 IN
P_USERNAME VARCHAR2 IN
P_USE_ROLES BOOLEAN IN DEFAULT
PROCEDURE PARSE_AS_USER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
P_CURSOR NUMBER(38) IN
ERROR:
ORA-24328: illegal attribute value


P_STATEMENT TABLE OF IN
P_USERNAME VARCHAR2 IN
P_LFFLG BOOLEAN IN DEFAULT
P_USE_ROLES BOOLEAN IN DEFAULT

SQL>

Let's just focus on the APEX use of this package by looking at the WWV_DBMS_SQL_APEX_220200 package. We can check who can access this package:

SQL> @sc_who_can_access
Enter value for output_method: S
old 206: lv_file_or_screen:= upper('&&output_method');
new 206: lv_file_or_screen:= upper('S');
Enter value for owner_to_find: SYS
Enter value for object_to_find: WWV_DBMS_SQL_APEX_220200
old 207: write_op('Checking object => '||upper('&&owner_to_find')||'.'||upper('&&object_to_find'));
new 207: write_op('Checking object => '||upper('SYS')||'.'||upper('WWV_DBMS_SQL_APEX_220200'));
old 209: get_obj(upper('&&object_to_find'),upper('&&owner_to_find'));
new 209: get_obj(upper('WWV_DBMS_SQL_APEX_220200'),upper('SYS'));
Checking object => SYS.WWV_DBMS_SQL_APEX_220200
====================================================================


Object type is => PACKAGE (TAB)
Privilege => EXECUTE is granted to =>
User => APEX_220200 (ADM = NO)

PL/SQL procedure successfully completed.

SQL>

So the APEX schema APEX_220200 can access this package. We should check who can access each of these packages and see if any are accessible outside of APEX; let's check WWV_FLOW_DYNAMIC_EXEC as that sounds interesting:

SQL> select owner,name,type from dba_dependencies where referenced_name='WWV_DBMS_SQL_APEX_220200';

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
SYS WWV_DBMS_SQL_APEX_220200 PACKAGE BODY
APEX_220200 WWV_FLOW_SESSION_RAS PACKAGE
APEX_220200 WWV_FLOW_DYNAMIC_EXEC PACKAGE BODY
APEX_220200 WWV_FLOW_CODE_EXEC_MLE PACKAGE BODY
APEX_220200 WWV_FLOW_SESSION PACKAGE BODY
APEX_220200 WWV_FLOW_SESSION_RAS PACKAGE BODY

6 rows selected.

SQL>

We can test one of the packages, WWV_FLOW_DYNAMIC_EXEC to see if it is granted to anything:

SQL> @sc_who_can_access
Enter value for output_method: S
old 206: lv_file_or_screen:= upper('&&output_method');
new 206: lv_file_or_screen:= upper('S');
Enter value for owner_to_find: APEX_220200
Enter value for object_to_find: WWV_FLOW_DYNAMIC_EXEC
old 207: write_op('Checking object => '||upper('&&owner_to_find')||'.'||upper('&&object_to_find'));
new 207: write_op('Checking object => '||upper('APEX_220200')||'.'||upper('WWV_FLOW_DYNAMIC_EXEC'));
old 209: get_obj(upper('&&object_to_find'),upper('&&owner_to_find'));
new 209: get_obj(upper('WWV_FLOW_DYNAMIC_EXEC'),upper('APEX_220200'));
Checking object => APEX_220200.WWV_FLOW_DYNAMIC_EXEC
====================================================================



PL/SQL procedure successfully completed.

SQL>

Nothing in this case BUT we should check all packages and then check for dependencies and then dependencies of those and so on. We don't know how DBMS_SYS_SQL is exposed in WWV_FLOW_DYNAMIC_EXEC and we don't know if there is any security checks in this package. Further we do not know if any children of this package (i.e. callers) expose the core functionality of DBMS_SYS_SQL or indeed if they even use WWV_FLOW_DYNAMIC_EXEC or expose anything or have any security embedded. Remember an attack is successful if we can steal data not if we can grant DBA to ourselves. If we check WWV_FLOW_DYNAMIC_EXEC to see what packages call this we can see:

SQL> col owner for a30
SQL> col name for a30
SQL> col type for a30
SQL> set lines 220
SQL> l
1* select owner,name,type from dba_dependencies where referenced_name='WWV_FLOW_DYNAMIC_EXEC'
SQL> /

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
APEX_220200 WWV_FLOW_UTILITIES PACKAGE
APEX_220200 WWV_FLOW PACKAGE BODY
APEX_220200 WWV_FLOW_UPGRADE PACKAGE BODY
APEX_220200 WWV_FLOW_DYNAMIC_EXEC PACKAGE BODY
APEX_220200 WWV_FLOW_CODE_EXEC PACKAGE BODY
APEX_220200 WWV_FLOW_CODE_EXEC_PLSQL PACKAGE BODY
APEX_220200 WWV_FLOW_LANG PACKAGE BODY
APEX_220200 WWV_RENDER_CHART2 PACKAGE BODY
APEX_220200 WWV_FLOW_DISP_PAGE_PLUGS PACKAGE BODY
APEX_220200 WWV_FLOW_SW_UTIL PACKAGE BODY
APEX_220200 WWV_FLOW_SECURITY PACKAGE BODY
APEX_220200 WWV_FLOW_FORMS PACKAGE BODY
APEX_220200 WWV_FLOW_BUILDER PACKAGE BODY
APEX_220200 WWV_RENDER_REPORT3 PACKAGE BODY
APEX_220200 WWV_FLOW_RENDER_QUERY PACKAGE BODY
APEX_220200 WWV_FLOW_PROVISION PACKAGE BODY
APEX_220200 WWV_FLOW_PROVISIONING PACKAGE BODY
APEX_220200 WWV_FLOW_TREE PACKAGE BODY
APEX_220200 WWV_FLOW_COLLECTION PACKAGE BODY
APEX_220200 WWV_FLOW_ITEM PACKAGE BODY
APEX_220200 WWV_FLOW_CUSTOM_AUTH_STD PACKAGE BODY
APEX_220200 WWV_FLOW_SW_API PACKAGE BODY

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
APEX_220200 WWV_FLOW_CONDITIONS PACKAGE BODY
APEX_220200 WWV_FLOW_SVG PACKAGE BODY
APEX_220200 WWV_FLOW_CALENDAR PACKAGE BODY
APEX_220200 WWV_FLOW_APP_INSTALL_INT PACKAGE BODY
APEX_220200 WWV_FLOW_WEB_SERVICES PACKAGE BODY
APEX_220200 WWV_FLOW_FEEDBACK_INT PACKAGE BODY
APEX_220200 WWV_FLOW_DML PACKAGE BODY
APEX_220200 WWV_FLOW_THEME_MANAGER PACKAGE BODY
APEX_220200 WWV_FLOW_UTILITIES PACKAGE BODY
APEX_220200 WWV_FLOW_ERROR PACKAGE BODY
APEX_220200 WWV_FLOW_INSTANCE_ADMIN PACKAGE BODY
APEX_220200 WWV_FLOW_PLUGIN PACKAGE BODY
APEX_220200 WWV_FLOW_INSTALL_WIZARD PACKAGE BODY
APEX_220200 WWV_FLOW_TEAM_FILE PACKAGE BODY
APEX_220200 WWV_FLOW_PLUGIN_UTIL PACKAGE BODY
APEX_220200 WWV_FLOW_VALIDATION PACKAGE BODY
APEX_220200 WWV_FLOW_COMPUTATION PACKAGE BODY
APEX_220200 WWV_FLOW_NATIVE_ITEM PACKAGE BODY
APEX_220200 WWV_FLOW_DATA_UPLOAD PACKAGE BODY
APEX_220200 WWV_FLOW_REGION_NATIVE PACKAGE BODY
APEX_220200 WWV_FLOW_REGION_LIST PACKAGE BODY
APEX_220200 WWV_FLOW_PROCESS_NATIVE PACKAGE BODY

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
APEX_220200 WWV_FLOW_INVOKE_API_PROCESS PACKAGE BODY
APEX_220200 WWV_FLOW_AUTHORIZATION PACKAGE BODY
APEX_220200 WWV_FLOW_AUTHENTICATION PACKAGE BODY
APEX_220200 WWV_FLOW_INTERACTIVE_GRID PACKAGE BODY
APEX_220200 WWV_FLOW_AUTHENTICATION_NATIVE PACKAGE BODY
APEX_220200 WWV_FLOW_MAINT PACKAGE BODY
APEX_220200 WWV_FLOW_DEBUG PACKAGE BODY
APEX_220200 WWV_FLOW_TREE_REGION PACKAGE BODY
APEX_220200 WWV_FLOW_LEGACY_PLUGINS PACKAGE BODY
APEX_220200 WWV_FLOW_EXEC PACKAGE BODY
APEX_220200 WWV_FLOW_EXEC_LOCAL PACKAGE BODY
APEX_220200 WWV_FLOW_SW_PAGE_CALLS PACKAGE BODY
APEX_220200 WWV_FLOW_EXEC_REMOTE PACKAGE BODY
APEX_220200 WWV_FLOW_DATALOAD_XML PACKAGE BODY
APEX_220200 WWV_FLOW_EXEC_WEB_SRC PACKAGE BODY
APEX_220200 WWV_FLOW_ADVISOR_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_EXEC_WEB_SRC_RESTSQL PACKAGE BODY
APEX_220200 WWV_FLOW_WEB_SRC_SYNC PACKAGE BODY
APEX_220200 WWV_FLOW_F4000_PLUGINS PACKAGE BODY
APEX_220200 WWV_FLOW_F4000_UTIL PACKAGE BODY
APEX_220200 WWV_FLOW_PROPERTY_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_DATA_PROFILE_DEV PACKAGE BODY

OWNER NAME TYPE
------------------------------ ------------------------------ ------------------------------
APEX_220200 WWV_FLOW_WEB_SRC_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_IR_API PACKAGE BODY
APEX_220200 WWV_FLOW_REST_WS PACKAGE BODY
APEX_220200 WWV_SAMPLE_DATASET PACKAGE BODY
APEX_220200 WWV_DICTIONARY_CACHE_DEV PACKAGE BODY
APEX_220200 WWV_DBMS_CLOUD PACKAGE BODY
APEX_220200 WWV_FLOW_SODA_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_DATA_LOADER PACKAGE BODY
APEX_220200 WWV_FLOW_APPROVAL PACKAGE BODY
APEX_220200 WWV_DG_BLUEPRINT_UTIL_INT PACKAGE BODY
APEX_220200 WWV_FLOW_DATA_LOADING PACKAGE BODY
APEX_220200 WWV_FLOW_WIZARD_API PACKAGE BODY
APEX_220200 WWV_FLOW_CALENDAR_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_PLUGIN_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_CODE_EXEC_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_CODE_EXEC_MLE_DEV PACKAGE BODY
APEX_220200 WWV_FLOW_PLSQL_EDITOR PACKAGE BODY
APEX_220200 WWV_FLOW_LOAD_DATA PACKAGE BODY
APEX_220200 WWV_FLOW_GENERATE_DDL PACKAGE BODY

85 rows selected.

SQL>

We can go further, we could check all child packages of everything that uses DBMS_SYS_SQL and we would need to ensure that every path is protected. i.e. ensure only the code necessary can be executed. The problem with DBMS_SYS_SQL is that it can run code as other users and run any code. This is a good example of what you must look at in your own code and applications; if you expose a route to read or change data protect that route properly.

So there are many routes possible; exploit a package that exposes something dangerous with things like SQL Injection or gain access to the owner of the package and simply use it or find a child that accesses the package and do the same, use it, exploit it or gain access to the owner.

So lets check the state of APEX_220200 and see if its accessible:

SQL> @find_all_privs



find_all_privs: Release 1.0.7.0.0 - Production on Tue May 28 07:45:23 2024
Copyright (c) 2004 PeteFinnigan.com Limited. All rights reserved.

NAME OF USER TO CHECK [ORCL]: APEX_220200
OUTPUT METHOD Screen/File [S]: S
FILE NAME FOR OUTPUT [priv.lst]:
OUTPUT DIRECTORY [DIRECTORY or file (/tmp)]:

User => APEX_220200 has been granted the following privileges
====================================================================
SYS PRIV => ALTER DATABASE grantable => NO
SYS PRIV => ALTER SESSION grantable => NO
SYS PRIV => ALTER USER grantable => NO
SYS PRIV => CREATE CLUSTER grantable => YES
SYS PRIV => CREATE DIMENSION grantable => YES
SYS PRIV => CREATE INDEXTYPE grantable => YES
SYS PRIV => CREATE JOB grantable => YES
SYS PRIV => CREATE MATERIALIZED VIEW grantable => YES
SYS PRIV => CREATE MLE grantable => YES
SYS PRIV => CREATE OPERATOR grantable => YES
SYS PRIV => CREATE PROCEDURE grantable => YES
SYS PRIV => CREATE PUBLIC SYNONYM grantable => NO
SYS PRIV => CREATE ROLE grantable => NO
SYS PRIV => CREATE SEQUENCE grantable => YES
SYS PRIV => CREATE SESSION grantable => YES
SYS PRIV => CREATE SYNONYM grantable => YES
SYS PRIV => CREATE TABLE grantable => YES
SYS PRIV => CREATE TABLESPACE grantable => NO
SYS PRIV => CREATE TRIGGER grantable => YES
SYS PRIV => CREATE TYPE grantable => YES
SYS PRIV => CREATE USER grantable => NO
SYS PRIV => CREATE VIEW grantable => YES
SYS PRIV => DROP PUBLIC SYNONYM grantable => NO
SYS PRIV => DROP TABLESPACE grantable => NO
SYS PRIV => DROP USER grantable => NO
SYS PRIV => EXECUTE DYNAMIC MLE grantable => YES
SYS PRIV => EXEMPT REDACTION POLICY grantable => NO
SYS PRIV => INHERIT ANY PRIVILEGES grantable => NO
SYS PRIV => UNLIMITED TABLESPACE grantable => NO
TABLE PRIV => DELETE object => MDSYS.SDO_GEOM_METADATA_TABLE grantable => NO
TABLE PRIV => DELETE object => FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$ grantable =>
YES
TABLE PRIV => EXECUTE object => SYS.ANYDATA grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_APPLICATION_INFO grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_ASSERT grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_CRYPTO grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_CRYPTO_INTERNAL grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_DB_VERSION grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_FLASHBACK grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_LDAP grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_LDAP_UTL grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_LOCK grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_METADATA grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_MLE grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_OUTPUT grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_PRIV_CAPTURE grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_RANDOM grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_REDACT grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_REGISTRY grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_SCHEDULER grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_SESSION grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_SQL grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_STATS grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_STATS_INTERNAL grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_TYPES grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_UTILITY grantable => NO
TABLE PRIV => EXECUTE object => XDB.DBMS_XMLDOM grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XMLGEN grantable => NO
TABLE PRIV => EXECUTE object => XDB.DBMS_XMLPARSER grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XMLSTORE grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XPLAN grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XPLAN_TYPE_TABLE grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XS_NSATTR grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XS_NSATTRLIST grantable => NO
TABLE PRIV => EXECUTE object => SYS.DBMS_XS_SESSIONS grantable => NO
TABLE PRIV => EXECUTE object => SYS.DIANA grantable => NO
TABLE PRIV => EXECUTE object => SYS.DIUTIL grantable => NO
TABLE PRIV => EXECUTE object => SYS.GETLONG grantable => NO
TABLE PRIV => EXECUTE object => SYS.HTF grantable => NO
TABLE PRIV => EXECUTE object => SYS.HTP grantable => NO
TABLE PRIV => EXECUTE object => SYS.JSON_ARRAY_T grantable => NO
TABLE PRIV => EXECUTE object => SYS.JSON_DATAGUIDE grantable => NO
...
TABLE PRIV => SELECT object => SYS.DUAL grantable => YES
TABLE PRIV => SELECT object => FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$ grantable =>
YES
TABLE PRIV => UPDATE object => FLOWS_FILES.WWV_FLOW_FILE_OBJECTS$ grantable =>
YES

PL/SQL procedure successfully completed.

For updates please visit http://www.petefinnigan.com/tools.htm

SQL>

This schema has lots of useful privileges such as ALTER USER; With this an attacked is SYSDBA as if the attacker gets access to APEX_220200 then they ca simply change the SYS password IF they can access the root container of course; if not then gain access to an account that can steal data or do other damage. What about the APEX_220200 account:

SQL> @sc_print 'select * from dba_users where username=''''APEX_220200'''''
Executing Query [select * from dba_users where username='APEX_220200']

USERNAME : APEX_220200
USER_ID : 131
PASSWORD :
ACCOUNT_STATUS : LOCKED
LOCK_DATE : 03-APR-23
EXPIRY_DATE :
DEFAULT_TABLESPACE : SYSAUX
TEMPORARY_TABLESPACE : TEMP
LOCAL_TEMP_TABLESPACE : TEMP
CREATED : 03-APR-23
PROFILE : DEFAULT
INITIAL_RSRC_CONSUMER_GROUP : DEFAULT_CONSUMER_GROUP
EXTERNAL_NAME :
PASSWORD_VERSIONS :
EDITIONS_ENABLED : N
AUTHENTICATION_TYPE : NONE
PROXY_ONLY_CONNECT : N
COMMON : NO
LAST_LOGIN :
ORACLE_MAINTAINED : Y
INHERITED : NO
DEFAULT_COLLATION : USING_NLS_COMP
IMPLICIT : NO
ALL_SHARD : NO
EXTERNAL_SHARD : NO
PASSWORD_CHANGE_DATE :
MANDATORY_PROFILE_VIOLATION : NO
PROTECTED : NO
READ_ONLY : NO
DICTIONARY_PROTECTED : NO
-------------------------------------------

PL/SQL procedure successfully completed.

SQL>

So, APEX_220200 is LOCKED BUT if we have access to an account that has ALTER USER then we could gain access to APEX_220200 or add the ability to proxy to it:

SQL> @sc_who_has_priv
Enter value for priv_to_find: ALTER USER
Privilege => ALTER USER has been granted to =>
====================================================================
User => APEX_220200 (ADM = NO)
User => ORDS_METADATA (ADM = NO)
User => HRREST (ADM = NO)
User => VF (ADM = NO)
User => TESTER (ADM = NO)
User => SYS (ADM = NO)
Role => DBA (ADM = NO) which is granted to =>
User => AV (ADM = NO)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
Role => IMP_FULL_DATABASE (ADM = NO) which is granted to =>
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => AV (ADM = NO)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
User => SYS (ADM = YES)
Role => DBA (ADM = NO) which is granted to =>
User => AV (ADM = NO)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
Role => DBA (ADM = NO) which is granted to =>
User => AV (ADM = NO)
User => SYSTEM (ADM = NO)
User => SYS (ADM = YES)
User => SYS (ADM = YES)
User => GSMADMIN_INTERNAL (ADM = NO)
Role => DV_ACCTMGR (ADM = NO) which is granted to =>

PL/SQL procedure successfully completed.

SQL>

Plenty of users to investigate. A detailed review of the database and application design should be made.

The idea here is to check for weakness in your data security design and application design and see if its possible to get access to dangerous things in your applications that would then allow you to steal data or change data. Check all access paths and see if its possible. Add protection code to your own code; i.e. use ACCESSIBLE BY clause to ensure that your package or procedure can only be called from where you decide OR go one better and use one of the call stack procedures and check the stack yourself BUT also check all possible access to schemas that leak or expose weakness and check all chains of access. Also check PL/SQL code for security vulnerabilities and check your application security permissions.

As you can see, data security is about layers and understanding all of the possible layers and finding ways to make sure each layer is secure and protections are implemented where necessary.

#oracleace #sym_42 #oracle #database #security #23c #23ai #securecode #plsql #grants #datasecurity #databreach #protect