Abusing Oracle’s CREATE DATABASE LINK privilege for fun and profit!

Oracle database (like any other database) offers functionality to create a database link via which you can connect to a remote database. You can then run a SQL Query on the remote database and get the results. This is exactly like the Openrowset/Openquery feature of MS-SQL.

CREATE DATABASE LINK local
CONNECT TO USERNAME IDENTIFIED BY PASSWORD
USING 'ORCL_SID'

NetSpi did a good job at documenting how to abuse MS-SQL openquery feature. During a recent pentest, we came across a SQLi in a web application which talks to Oracle database 11g R2. Desperate, as we were, to get a shell, this is how things unfolded:

—
Generic integer based blind SQLi in a web app
1. picked up by BurpPro
2. Exploitation in SQLmap didn’t work by default

Reason: SQLmap’s default boolean based injection works by issuing AND clauses:

select * from foo where id=5 and 1=1
select * from foo where id=5 and 1=2

Tip 1: This works 9 out of 10 times, but if the original entry id=5 does not return any records, you will miss SQLi. So just make the first entry return records by adding or 1=1

Sqlmap will complain:

"[13:24:41] [WARNING] it appears that you have provided tainted parameter values ('id=189881 or 1=1') with most probably leftover chars from manual SQL injection tests (;()') or non-valid numerical value. Please, always use only valid parameter values so sqlmap could be able to properly run
Are you sure you want to continue? [y/N] Y"

Ignore the warning and select Y to continue. Now sqlmap will do its bit and you can get SQL Shell and extract anything you want.

SQL-shell from SQLmap

—
So, after looking inside the database, we find our user has limited privileges. The database also seemed to be reasonably patched. We are not DBA and while we can extract data held in the database, we cannot have too much fun!

*Marketing*
As creators’ of SQLiLab we take great pride in researching new attacks and applying this research in our pentests. You can master SQLi and other injection flaws like LDAP, Xpath, XXE etc at our upcoming Black hat training class in Las Vegas.
*Marketing*
—
So, carrying on we identify that the database user has these privileges:

Immediately, the privilege CREATE DATABASE LINK caught our attention. Note that Oracle’s SQL language do not allow you to write multiple statements. So, how are we going to create a DB_LINK in a SQLi which is probably in a Select statement? Check out our previous presentation on how to overcome this using function dbms_xmlquery.newcontext(). Using this function, we were able to create multiple links inside the database:

Tip 2: If you have CREATE DATABASE LINK privilege, you can use it in a web based SQLi to brute-force/guess a user login and if successful run a query as that user:

Note that DBSNMP user does not have DBA role and the only ‘useful’ privilege this user has is ‘select any dictionary’. Now that we have the hashes, we can crack the hash for system user and create a link with the credentials of system user:

Now we can basically issue any query with system privileges. Those who have an account in SQliLab, should have seen a number of ways to execute OS code against Oracle with DBA role. Here is one of my favourite using function SYS.KUPP$PROC.CREATE_MASTER_PROCESS():