Deja Vu
Last updated
Last updated
Room Link: https://tryhackme.com/r/room/dejavu
After our initial port scan, we find two open ports. As usual, SSH is not much use without credentials as it's up to date. This just leaves us with a web application to explore.
From Nmap's service version detection, we know that the backend is built in Golang. This hopefully means dynamic content that we can explore.
The first step in exploiting a webapp, like exploiting anything else, is reconnaissance. Exploring the webapp to discover functionality is critical for gaining a basic familiarity with the webapp and potentially how it works. Navigating the webapp without actively trying to exploit the functionality is called walking the happy path. You can learn more about this technique (and a lot more) in this room: Walking An Application.
Open up Burp Suite with your browser of choice (I like the integrated Chromium) and we can start exploring the site.
Setup Burp to track the site
Click around the website. Can you find any developer comments?
Can you find the page that gives more details about a dog photo?
Perform an Nmap scan of the target. What version of SSH is in use?
Kali
After we've gained a basic familiarity with the site, we can start some more active enumeration. A directory brute force scan can help us discover content that's otherwise unreachable through normal browsing, like admin pages or old versions that haven't been removed. With admin pages leading to more application features that might not be hardened, or unmaintained code from outdated versions, we're more likely to find vulnerabilities.
Run a gobuster scan with dirb's big.txt
wordlist. What can you find? Other tools and wordlists are available.
With an API driven webapp like this, we can see how the application retrieves data to make it dynamic. A great way to do this is Burp Suite, which can automatically map out the target site's structure as we explore.
Burp Suite's target site map should have discovered 2 API routes that the website uses to retrieve information about the dog pictures. One retrieves the title and caption, and the other is used to retrieve the date and author. The full paths have been redacted, so that you find them yourself.
It appears the API route used to retrieve the date and author does so with EXIF data, and uses Exiftool from the response. It appears the output of the command is simply serialised into JSON and sent to the client. This gives us a lot of information, notably the ExifTool version number. This is considered a vulnerability under the OWASP API Top 10, more specifically API3:2019 Excessive Data Exposure
. Usually, exposing version numbers would be considered a low or informational rated issue but as we will discover it can have more serious consequences.
What page can be used to upload your own dog picture?
/upload/
What API route is used to provide the Title and Caption for a specific dog image?
/dog/getmetadata
What API route does the application use to retrieve further information about the dog picture?
/dog/getexifdata
What attribute in the JSON response from this endpoint specifies the version of ExifTool being used by the webapp?
ExifToolVersion
What version of ExifTool is in use?
12.23
What RCE exploit is present in this version of ExifTool? Give the CVE number in format CVE-XXXX-XXXXX
CVE-2021-22204
Now that we've discovered a potential method of exploiting the box, we should try it!
Turning our version disclosure into remote code execution massively increases the severity of the issue.
In the Microsoft ecosystem, there's a concept called "Patch Tuesday"; security patches for Microsoft products are often released on Tuesdays. Practically immediately after these patches are released, work begins on creating exploits for the vulnerabilities as many systems will not be immediately updated.
Exiftool follows a similar story here. In early 2021, an exploit was discovered in Exiftool that could lead to arbitrary code execution. The exploit was quickly patched before public proof of concept code started to appear, however many security enthusiasts began to reverse engineer the patch to create an exploit.
Researching the vulnerability, we can see it was assigned CVE-2021-22204. Looking at the NVD CVE page for the flaw shows that it was patched in 12.24. The page also has a link to the patch, which is very useful here because we can see how they fixed the vulnerability. The git diff is copied below.
The dangerous function here is the call to eval on line 233. Eval is used to run Perl code that's contained in a variable, and the variable comes from EXIF data in our image. Control over code that's executed is our goal, so it currently seems like the only barrier between us and arbitrary code execution is the filter found on line 231.
It's worth explaining the =~
that's used here. It's a Perl operator usually used with regular expressions, and it can be very very complicated. Importantly for us, the first character after the ~ is 's'. This means that the operator will perform a search and replace with the regular expression that follows.
That regular expression is also very complicated, unfortunately. There's a helpful comment explaining the intent, escaping special characters in the string. Another unfortunate discovery, if we look at the source code surrounding our filter which wasn't captured in the diff, is that this filter also relies on quote marks delimiting the ends of fields.
Combining all this information, we can see how a code injection vulnerability would arise if we can bypass the filter and have Perl eval
our own code. As this filter is irritating and the exploit is somewhat complex to engineer, we'll simply use Metasploit to craft our exploit. Articles describing how an exploit was created manually are included later.
To create our exploit, we need to first find the Metasploit module for this vulnerability. If you're unfamiliar with locating exploits in Metasploit, try the TryHackMe Metasploit Intro room.
We then need to set our options appropriately for a reverse shell payload. As it's a Perl command injection vulnerability, we want a command payload rather than a binary payload. Make sure your LHOST is correct and make sure you start a netcat listener!
More information
If you didn't like my explanations, want to learn more, or you want to see how the proof of concepts were created, please see the links below.
Generate an image payload with Metasploit
Kali
Kali(msfconsole)
Kali
Get code execution on the target machine
Kali
Now that we have code execution, our goal should be rooting the box. Fortunately, something should immediately catch your attention if you run ls -lah from the current working directory. A SUID binary! The presence of one of these in a home directory is quite unusual, but it looks like we have a file left by the server administrator to help manage the webserver. It also looks like we have the source code for this C program, very useful for exploiting it.
SELinux improves security by essentially setting out rules that processes are made to follow. While SELinux can make hacking a box more difficult, it can also make administering a server more difficult.
Rather than trying to configure SELinux to allow the webserver to bind to port 80, the system administrator just disabled it. This is a somewhat common approach, but is by no means the "correct" approach which would be learning the fundamentals of SELinux and configuring it correctly. With the command getenforce
we can verify whether SELinux is enforcing its rules (the command prints disabled).
While SELinux doesn't affect the privesc we use here, it is worth bearing in mind in real pentests or harder rooms.
You can read more about SELinux at these links:
https://selinuxproject.org/page/FAQ https://www.redhat.com/en/topics/linux/what-is-selinux
A SUID binary has special permissions, allowing the program to use the setuid
system call. The setuid
call allows the process to set its user id. If you call setuid(0)
and the process has the correct permissions, then the program will then run as root.
When a program may need to run parts of the code as root but does not want to run the whole program as root, SUID is often used. An example of this would be the webserver Apache2, which initially runs as root to bind to port 80 and then subsequently drops these elevated privileges.
SUID binaries can only set their UID to the owner of the binary's UID unless the binary is owned by root, in which case they can set it to any UID. You usually don't have to call setuid
yourself, the program will usually do this.
A more modern alternative to setuid binaries is Linux Capabilities, which offer much more granular control over permissions such as CAP_NET_BIND_SERVICE
which allows programs to bind to low (privileged, under 1024) ports without running as root. The capability CAP_SET_UID
is equivalent to suid permissions, allowing the program to call setuid
If we run the binary, with ./serverManager
, we get a choice of operations.
Selecting 0 gives us the status of the webserver service, and 1 allows us to restart it. Restarting the service would usually require root privileges, so it makes some sense that the binary is SUID.
Reverse Shell
As we have the source code of the application, we can more easily see the vulnerability.
serverManager.c - vi
The vulnerability comes from calling system() without providing a full path to the binary. This means that we can create a fake systemctl binary which will run as root, and escalate our privileges.
We can also use a program called ltrace which allows us to see system and library calls, although this is not installed on the machine. Pay close attention to the system() seen earlier that provides systemctl without its full path.
james@centos
The PATH variable tells the shell where to look for binaries that you call by name, so for example ls is actually /bin/ls. It consists of a sequence of directories, separated by colons. Your shell will run the first binary that matches, looking in each directory left to right. This direction is important.
We're exploiting a combination of two things here.
Firstly, the binary runs as root due to SUID.
Secondly, the binary calls systemctl
with an incomplete path (eg not /usr/bin/systemctl
, just systemctl
on it's own.)
Because the system will run the first binary it finds from PATH that matches systemctl here, we can make our own fake systemctl
to run instead, which will be ran as root (as it inherits the UID and GID of the parent process).
Our fake systemctl
can be as simple as /bin/bash
in plaintext to start a new shell - Linux treats executable text files as shell scripts.
Let's create a fake systemctl
, add it to path, and get root.
Reverse Shell
Let's break this down:
[dogpics@dejavu ~]$ echo '/bin/bash' > systemctl
- We're creating a plaintext file with the contents /bin/bash
which will start a shell when executed.
[dogpics@dejavu ~]$ chmod +x systemctl
- We need to make our fake systemctl
executable, otherwise it will be ignored.
[dogpics@dejavu ~]$ export PATH=.:$PATH
- here, we add .
(our current working directory) to the beginning of PATH. This means the system will look in our current working directory for binaries before searching the rest of PATH, and find our fake systemctl
before the genuine one.
[dogpics@dejavu ~]$ which systemctl
- To check that our fake systemctl
will run if the command systemctl
is used, we use which
. which
essentially does the PATH lookup for us and prints the results.
[dogpics@dejavu ~]$ ./serverManager
- Run the vulnerable binary!
From there, you should have a root shell. As a warning, your HOME variable is still /home/dogpics
rather than /root
so you will need to cd /root
. Then just grab the flag.
https://www.hackingarticles.in/linux-privilege-escalation-using-path-variable/