Keldagrim Write Up



Keldagrim is a medium level CTF room on TryHackMe created by Optional.

Can you overcome the forge and steal all of the gold!


I deployed the machine and was given the target IP I started a nmap scan to check the available ports.

└──╼ $sudo nmap -sC -sV -oN nmap/initial
Starting Nmap 7.80 ( https://nmap.org ) at 2021-03-06 13:03 GMT
Nmap scan report for
Host is up (0.030s latency).
Not shown: 998 closed ports
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 d8:23:24:3c:6e:3f:5b:b0:ec:42:e4:ce:71:2f:1e:52 (RSA)
|   256 c6:75:e5:10:b4:0a:51:83:3e:55:b4:f6:03:b5:0b:7a (ECDSA)
|_  256 4c:51:80:db:31:4c:6a:be:bf:9b:48:b5:d4:d6:ff:7c (ED25519)
80/tcp open  http    Werkzeug httpd 1.0.1 (Python 3.6.9)
| http-cookie-flags: 
|   /: 
|     session: 
|_      httponly flag not set
|_http-server-header: Werkzeug/1.0.1 Python/3.6.9
|_http-title:  Home page 
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.63 seconds

2 Ports open:

  • 22 - SSH - Banner is showing its an Ubuntu machine
  • 80 - HTTP - Werkzeug httpd 1.0.1

I also ran a full port scan but no additional ports were found.


I opened up my browser and started to have a look at the web page.


Nothing really stood out however when I looked at the source code I could see a disabled link to /admin

    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Buy Gold
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="/wow">World of Warcraft</a>
            <a class="dropdown-item" href="/OSRunescape">Old School Runescape</a>
            <a class="dropdown-item" href="/runescape">Runescape3</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item " href="/admin">Admin</a>

However the page looks pretty much the same. So I looked at cookies and found a session cooke with a base64 value.


There are lots of ways to change the base64 to plaintext but I really like CyberChef at the moment. Using CyberChef I was able to see the value was ‘guest’.


I used CyberChef again to encode ‘admin’ in to base64.


Simply changing the session cookie value to the base64 output and refreshing the page now allowed me to see - ‘Current user - $2,165’ and be provided with a sales cookie.


This was also base64 encoded, CyberChef has a great feature called ‘Magic’, if you are unsure how something is encoded use magic to suggest and test various operations.


This next bit took some time, I was able to base64 a string and input it in to the sales cookie and it would be displayed on the webpage, however I was unsure how I would be able to use this to get a foothold on the box. After some googling, I tried a technique called Server Side Template Injection (SSTI). This was not something I had tried to exploit before so I did some research on the technique to try and understand it and used PayloadsAllTheThings to see if I was on the right track.

I found a payload {{7*'7’}} and if I had SSTI that should result in 7777777. I encoded the payload in base64 and updated the sales cookie with the output.


Refreshed the page and confirmed I had SSTI in the sales cookie!


Initial Access

On the same PayloadsAllTheThings page was an example for remote code execution. I took the example for exploiting an SSTI by calling Popen without guessing the offset, changed the IP and port values and encoded again with base64.

I opened a nc listener and updated the sales cookie with the base64 output and got a shell!

└──╼ $nc -nvlp 4444
listening on [any] 4444 ...
connect to [] from (UNKNOWN) [] 36928
/bin/sh: 0: can't access tty; job control turned off
$ whoami

Priv Esc

Now to get root i checked ‘sudo -l’.

$ sudo -l
Matching Defaults entries for jed on keldagrim:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, env_keep+=LD_PRELOAD

User jed may run the following commands on keldagrim:
    (ALL : ALL) NOPASSWD: /bin/ps

I had a look at GTFOBins for ‘/bin/ps’ but as expected I didn’t find anything, I also noticed ‘env_keep+=LD_PRELOAD’. There is a great course by Heath Adams on udemy for Linux privesc techinques and this is covered as part of the course. There is also a great article which covers it.

I used the steps in the article to create a file called evil.c, compiled with GCC. Ran the sudo command with LD_PRELOAD and got root!

jed@keldagrim:/dev/shm$ sudo LD_PRELOAD=/dev/shm/evil.so ps
root@keldagrim:/dev/shm# id
uid=0(root) gid=0(root) groups=0(root)

Thanks for reading!