Derailed
XSS + CSRF for foothold, followed by exploiting OMV via the SSH module after finding hidden credentials.
XSS + CSRF for foothold, followed by exploiting OMV via the SSH module after finding hidden credentials.
As usual, we start with an Nmap scan:
Port 3000 was found to be a HTTP port leading us to this Clipnotes page.
Wasn't much to play around with, as we had no credentials yet. Decided to run a directory scan to find if there are any endpoints. Eventually, I found this /rails endpoint, using dirsearch.
Interesting. This presented a lot of information for me and also tells me this is a Ruby on Rails project. Another interesting directory was the /administration panel which I could not view at all. This is the information from the info endpoint:
From here, we can try to fuzz out other information and endpoints on this /rail directory. I used feroxbuster for its recursive search function.
This directory basically shows us every single path there was in the website:
Earlier, we saw some form of clipnote function. Testing it shows us that each time we create a new one, it is stored on the server somewhere. Notice that this one I created was 110.
Using the /clipnotes/raw/:id format, I was able to view the first clipnote, submitted by a user called Alice. Visiting anything other than 1 was not possible.
I was interested in what other number is present, so I used wfuzz to enumerate out all other numbers. None are present it seems
I checked out the other endpoints, as there may be more interesting ones. The /report one looks good.
Submitting a report reveals tells us that an admin would look at it. This tells me that perhaps, there is a form of XSS present on the site.
When looking at the POST request for the report, we can see that it sends this authenticity_token:
However, the cookies have been set to HttpOnly, meaning that stealing cookies is pointless in this case. XSS on the administrator could either allow us to enumerate more about the /administration page, or simply to steal his cookie and impersonate him.
Because this is clearly an XSS challenge, I thought of first finding a potential XSS entry.
I messed around a lot with the clipnotes and tried all sorts of stuff, but it wasn't loading Javascript. Then I realised that the author of the clipnotes was something that I controlled. Perhaps, I could overflow the thing or try to register a malicious user. Since the page renders that username, this could potentially be vulnerable.
So I started a HTTP server, and attempted this:
The reason I did this was because I am aware that there is a potential limit to the username, and trying to overflow that may cause the end bit to be rendered as JS code. Then I created a clipnote:
The overflow kind of worked, managed to remove the last portion about the created bit. I then went to try various different payloads including <img> tags and stuff. DIdn't really work. I then suspected this has to do with some kind of CVE that was released recently (usual pattern of HTB, uses CVEs from 2022), and went hunting for Ruby + XSS related exploits that came out recently.
I eventually found CVE-2022-32209, which was a XSS exploit for Rails::Html::Sanitizer.
Seems that the <select> tag was being used maliciously. I then tried the same overflow trick with this payload:
This worked! I was able to get a callback as well:
Now, we just need to find a way to exploit this XSS.
Understanding that we now have XSS, I was thinking of using CSRF in order to retrieve more information about the /administration page. The reason CSRF is used is because CSRF tokens do not protect against XSS. We had a simple rails cookie that was HttpOnly, so XSS needs to do something else.
Since we can basically execute basic web requests using our username, we need to think of how to redirect the user somewhere. We can abuse the eval function to inject malicious JS code.
First, I made a simple script that would callback to our machine.
Then I encoded it using Base64, and wanted to see if I was able to get the callback I wanted using event attributes. The end username was this:
Base64 Encoding did not work, so I tried with Char Coding instead. What Char Coding does is basically translate all the characters within my script to become ASCII letters.
The payload becomes this:
This payload worked! I was able to retrieve two callbacks after creating the clipnote.
Now we can use a script from Hacktricks to steal the page content of the administration panel.
Then, we can send it via the same method and make sure to report the clipnote to make the administrator load the page.
Here is the page contents:
When analysing the contents of this, there is one form that is available on the page:
This form seems to download something and it has a value that is fixed. Since this is a POST request, we need to use CSRF to make the administrator send a request. The value
parameter looked rather suspicious because it seems exploitable to an LFI.
So when doing CSRF, our payload would first need to do this:
Retrieve the authenticity_token value because we need that to verify we are indeed the administrator
Send the POST request with an edited report_log
value.
Have a small delay to ensure that the page would load fully before attempting to find the elements required. I set the delay to 3 seconds.
I did some research around Ruby vulnerabilities, and found a few good articles:
Potentially, this form might be using the open
function, which is vulnerable to RCE because of a deserialization exploit. I wanted to test this first. As such, I created this quick script:
When waiting around, I eventually got a callback via the curl
command I injected.
With this, we can easily gain a reverse shell through this method. I used the mkfifo
shell, and it worked!
We can grab the user flag while we're here.
To establish persistence, we can put our public key within the ~/.ssh/authorized_keys
folder. Then I looked around the /var/www/
folder to find some credentials.
When checking the available stuff, I found this openmediavault
folder as well.
Within the rails-app
directory, there was a .git
repository.
I checked the logs for this using an SSH shell instead, and found credentials for an alice
user.
This password was rather useless.
WIthin the config file, we can find another password.
There was a sqlite3 file here. Within it, we can find this portion here with hashes for toby.
Checking the /etc/passwd
file, we can see that the openmediavault-webgui user is Toby Wright.
I extracted this hash and attempted to crack it.
WIth this, we can su
to the openmediavault-webgui user.
I saw earlier there was some omv
instance running on the machine. Running a netstat -tulpn
confirms this to be running on port 80.
Also, I saw this config file when re-running LinPEAS.
Open Media Vault is a network-attahced storage system, and I wanted to take a look into it. We can port forward this via chisel
.
I couldn't find the creds for this to login, so I was unable to exploit it.
I took a look at the config files that we had access to. There was one portion that was interesting.
There were user entries, and they seemed to accept a name
and an sshpubkeys
. Perhaps this could be used to update the SSH for the machine or something. Checking our id
, it seems we can edit this config file and update it as well.
The /usr/sbin
file contains loads of omv
related tools too:
This website on the OMV website was very helpful:
The vulnerability here is that the config.xml
file is owned by our current user and can be changed, allowing us to enable SSH access to any user within the machine using a public key of our choosing. This can be done by editing the config file within the machine.
There are 2 entries within the machine, one for rails
and one for test
. We can edit the test
one for the root user, and use ssh-keygen -t rsa; ssh-keygen -e -f ~/.ssh/id_rsa.pub
to generate the needed key in the right format.
Note that we need to add the <sshpubkey>
tag because we are specifying a new object. Then, we need to reset the OMV instance to read the new config file. From the OMV documentation, we can use the omv-confdbadm
file to do so.
Then, we need to make changes to edit the SSH module for the OMV instance. This can be done using omv-rpc
to force a config update for the SSH module.
Interesting root for this machine. OMV is something that I don't see around often.