21c Gradual Database Password Rollover brings new backdoor opportunities

This post is also available in: Português

Oracle Database 21c introduced the new feature called "Gradual Database Password Rollover". This allows the database password of the application user to be altered while allowing the older password to remain valid for the time specified by the PASSWORD_ROLLOVER_TIME limit (PROFILE parameter).

With this new feature, a password of an application can be changed without having to schedule a downtime, which is great. However, any new feature also brings new security opportunities for attackers.

If an attacker wants to place a "second" password to later access the "SYS" or a "DBA" schema (aka backdoor) without raising any alert, this is now easy as 2 passwords can concurrently work for the same account.

Example 1:

[oracle@lab21c ~]$ sqlplus /nolog

SQL*Plus: Release 21.0.0.0.0 - Production on Mon Dec 21 12:25:13 2020
Version 21.1.0.0.0

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

SQL> conn / as sysdba
Connected.
SQL> create user C##DBA identified by "welcome1";

User created.

SQL> grant create session to C##DBA;

Grant succeeded.

SQL> conn C##DBA/welcome1
Connected.
SQL> conn C##DBA/mysecretpass
Connected.
SQL> alter user C##DBA identified by "welcome2";

User altered.

SQL> conn C##DBA/welcome2
Connected.
SQL> conn C##DBA/mysecretpass
Connected.

Example 2:

SQL> conn / as sysdba
Connected.
SQL> alter user system identified by "welcome1";

User altered.

SQL> alter user system expire password rollover period;

User altered.

SQL> alter user system identified by "welcome1";

User altered.

SQL> conn system/mysecretpass
Connected.
SQL>

How someone could do something nasty like this and how we protect against this possible backdoor implementation is what you are going to see in this post.

PS: In my previous post, I explained how the new hashes we have in SPARE4 column of USER$ works during the rollover period. I recommend reading it before moving forward.

Getting started

So first of all, to allow a second password to work, an attacker would need to create a new password HASH on SPARE4 column on the USER$ table. Oracle did a great improvement and now it's impossible to run any UPDATE against USER$ table unless you open the database in migration mode. So this is not an option.

Another way to add another password HASH  would be intercepting the "ALTER USER ... IDENTIFIED BY ..." or the "CREATE USER ... IDENTIFIED BY ..."  DDL calls.

First thing that came into my mind was using a "before DDL trigger". However, Oracle did another great implementation and it's not possible to get the current used password on those triggers (via ora_sql_txt variable). So if the attacker used this method, the password would not least more than 7 days (max value for PASSWORD_ROLLOVER_TIME) as he can't keep setting it.

Going straight to the point, the final idea he could have would be intercepting this calls using profile functions, the only place where we do know the user password. When a CREATE or ALTER user password is called, the profile function would create a job to:

  1. Change the PASSWORD_ROLLOVER_TIME used by this account profile to 7 days (max allowed), if not already.
  2. Temporarily disable PASSWORD_REUSE_TIME, PASSWORD_REUSE_MAX (to avoid reuse errors).
  3. Temporarily disable PASSWORD_VERIFY_FUNCTION (to avoid a loop in the code).
  4. Set the password to a desired value (backdoor password).
  5. Expire the password rollover so the backdoor password will be the only one valid.
  6. Set the password to the user specified value.
  7. Restore back the disabled profile resources.

This job will execute every 6 days so the attacker will ensure that the "second" password will always be valid (as the expiration is 7 days).

So what is required:

  • Create a procedure "proc1" that will set the new user password and the backdoor user password.
  • Create a scheduler program that will use this procedure.
  • Create a procedure "proc2" that will create the job using the program and the procedure "proc1" above whenever a user CREATE or ALTER is triggered.
  • Change the current password functions to call this procedure "proc2".

The sample code to keep the second password always valid is available here: https://github.com/dbarj/sql-scripts/blob/main/gradual_rollover_permanent_2ndpass.sql

How to protect

To protect against this kind of opportunity (that can be used for the good and for the bad), you must:

  1. First and the most obvious: protect your systems that no user can connect (or escalate) to SYS . For a attacker to implement this backdoor, he must first be SYS. I know this sounds irrelevant, but most of the DB systems I've worked for are so badly security designed that is very easy for a normal user to perform this.
  2. Enable Oracle Database Vault (if you have license to do it), which will make this much much harder (not to say impossible) to be implemented.
  3. Use orachksum tool to scan your database periodically for internal code changes. The tool would point out the objects created under SYS schema that does not come with the default DB installation/creation.

Conclusion

The best way to be always ahead and protect our DB systems is putting ourselves in the mind of an attacker and think how he could use any new feature to possibly deploy a malware in our databases. #thisistheway

And always remember:

With great features comes great responsibility.
(Rodrigo Jorge - 2020-Dec, copied and adapt from Spider Man =]).

Have you enjoyed? Please leave a comment or give a 👍!

Leave a Reply

Your email address will not be published.