Robust - Proving Grounds, Practice
Thursday 15th September 2022
I never planned to do a write-up or walkthrough for every box I did, just ones that stood out. That could be for a number of reasons, from the level of complexity or ingenuity involved, to simply how frustrating it was. The case with Robust was definitely the latter.
OffSec rates this box as 'Easy', which means you score a minimal 10 points for accessing both flags, but the community rating is 'Hard', which in my opinion is much more accurate. I found this box frustrating for a couple of reasons. Firstly, as a software engineer, I should have spotted the first roadblock, and secondly, the Privilege Escalation was downright obscure. For me it felt like, how would I know that was there...if I didn't already know it was there sort of thing. So as usual, let us kick off with an Nmap scan to see the lay of the land.
It looks like we have SSH, a Web Server and something on 7680 open.
Port 80
Let's have a look at what the web server is hosting.
It looks like we're being blocked based on our IP address. After taking way too long on this section I can across the X-Forwarded-For header. This can be used for multiple legitimate reasons, such as a proxy/CDN appending the original server's IP address so clients can verify where the content came from. If we start routing our requests through Burp, and send this one to the Repeater, we can add our own header.
If we forward this request with the fake IP address we should get access to the login page.
At this point, I thought about trying to brute force it with Hydra, but with no idea of any users, or any passwords to try password-spraying I had another rethink. I had a bit of difficulty using `gobuster` with the custom headers so I, but chance really, stumbled across `wfuzz`.
With the forwarded-for header added and a successful status code of 302(Redirect), we could look for what other files possibly existed on the server. I originally stuck with a 200 status code but it returned nothing.
wfuzz -H "X-Forwarded-For: 10.10.10.10" --sc 302 -u http://192.168.163.200/FUZZ.php -w /usr/share/wordlists/wfuzz/general/big.txt
We get lucky, with one other file appearing present which is home.php. Hitting this in the browser just redirects to the login page so it was time to run it through Burp and see what headers are involved on this page.
As we can see there is a Location: login.php redirect on the response to our request for home.php. If we simply delete this we can get access to the home page!
Automating Burp Headers
To save the hassle of manually adding all of these request & response headers each time we want to access some of the protected web content, we can get Burp Suite to do this for us. Under Proxy -> Options, there is a section for Match & Replace of headers. This section covers both headers added to a request and any we want to be appended to the response.
To make sure we get access to every request, we can add the X-Forwarded-For header to every request we send to the server. Simply click the 'Add' button and enter the header details.
Next, below shows an example of how to clear a header that the server has sent as part of a response. This Location header will now be empty when the browser receives it.
So now, those IP restrictions and redirects might as well not even be there in the first place!
Getting Shell
With access to a web application that is serving up Employee information, it might be time to start messing with the search fields to see if we can get any more data from the backend. This, it seems, was one of the few more straightforward parts of the box. A simple UNION-based SQL injection string gave us a crucial piece of data.
' UNION select * from employees'
Running this in the 'First Name' search box returns us the same set of data but with one additional entry for Mr Jeff Hills. It turns out his Birth Date is a bit different to the rest and looks more like a password.
Before we move on, I personally find SQL injection a bit confusing at times so if you'd like some further reading on why the above query works read up more on the UNION operator and this type of injection.
So, going back to our original Nmap scan, we can see that SSH is open for us to try. Lets give Jeff/###### a go and see if we can get some kind of shell.
We can! This means we can get our first flag, local.txt
Privilege Escalation
Now, this is where I had to resort to hints from the Proving Grounds, as this escalation vector, in my opinion, was deep in the land of obscurity.
After quite some time doing the usual enumeration:
Searching the Registry
Checking Service Paths
Program Files etc...
User Privileges.
I caved and used the hint from OffSec. It led me to an obscure package in Jeff's AppData directory. After drilling down through all directories within Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe I came across a plum.sqlite.
C:\Users\Jeff\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState>
If we go ahead and just type plum.sqlite we can get out final set of credentials needed for the box.
With these credentials we can now go ahead and SSH into the box again, but as Administrator, which gives us our final flag! 🙌🏼
So, my lack of experience here let me down, but that last PrivEsc vector was one needle in a haystack! Most importantly though, as with all boxes, I did learn a fair bit.