Hack The Box: Node Walkthrough

Welcome to another fun Hack the Box walkthrough. Today, we’ll be talking about Node. This was one I really enjoyed working on and taught me a lot about single page applications and the MEAN (Mongo, Express, Angular, Node) stack. Anyway, enough blabbing, let’s get hacking.

Reconnaissance

First things first, we need to try understand what we’re targeting. We’ll start off with a full TCP nmap scan to see what types of services are running.

Even with a pretty intensive nmap scan we don’t see many services. Seems only port 22 for SSH and port 3000 for some kind of application. For some reason it says hadoop even though we see http-title, so we’ll need to take a look and see which is which. A quick check of this shows that it’s a single-page javascript application.

Validate what the service is before continuing

Looks interesting, but because the application is an AngularJS single-page application (SPA), our primary web discovery tools such as gobuster, dirb, and nikto are not effective. Because of our limited toolset which supports JavaScript applications, we’re going to want or need to leverage a proxy such as Burp Suite or ZAP to analyze and record URL’s the web application called to. We can do this for example by opening up node.htb and telling Burp to spider the host for us. As we’re not logged in, I’m not concerned about the spider trying to delete something randomly. If we were logged into an application, we probably wouldn’t want to spider the host.

When we take a look through the URLs that have been found, we quickly find something interesting within the API:

The user API is returning password hashes in it’s responses

So the users API endpoint is returning password hashes to us, which could be useful if we can crack them. Looking at the /api/users/ endpoint we get back:

Nice! Looks like one of the users is an administrator. Let’s format this for John the Ripper and see if we get any hits back. We can do this by using a little bash loop and using jq to help us process the JSON.

So with that let’s try out our new credentials on the website and see what we get. Upon logging in, we get a single new option, download backup. Potentially this will give us a copy of the website which may contain sensitive information such as usernames or passwords.

When we download the file, we get something called myplace.backup which Firefox tells us is a plaintext file. Taking a look at it, it looks like it’s encoded. The equal sign at the end hints that it may be base64 encoded. Sometimes we’ll find things like images or files base64 encoded for easier transmission or to embed them into a website. Let’s decode it and save it to a new file to try to figure out what we have.

With our password, lets extract this. We quickly see as unzip runs that it seems to have been a full web application backup. Moving down into the ./var/www/myplace/ subdirectory, we get to the application root. When I am going to examine a web application, I try to start at the application entrypoint and then branch out depending on what I find. In this case, Express.js applications usually start with the app.js file. Looking into this, we see that the application connects to a MongoDB instance using a username and password. First thing this should make us wonder is whether the user re-used their normal user password for database access.

Perfect! We successfully logged in. Sadly though, it doesn’t seem this is the user we want to be as there is no user.txt flag:

mark@node:~$ ls
mark@node:~$ pwd
/home/mark

Guess we’ll need to take a look around and see if we can either escalate our privileges directly to root or if we need to consider pivoting to another user on the machine. To determine this, we should try to understand more about the application we were able to exploit. For example, is it running as Mark or as another user? If it’s Mark, there may not be much of interest with it, but if it’s another user there may be an opportunity to escalate privileges using the user running the application. Since this is a Node.JS application, we can quickly check for it by running:

Hm, seems that the application is running as Tom. Also, seems there is some type of scheduler application which is also running. Let’s take a look at that and see what it is. May be interesting as from the name of it, we may be able to execute something every so often with it, similar to a cron job.

Looking at that, it seems like we have a MongoDB connection, we look for all the items in the tasks collection, then we execute whatever is in the cmd field. It seems to also require an _id field when saying what it’s doing. Based on the underscore, if it’s like Elasticsearch, I’m going to assume that this is not something we need to enter but an automatically created ID. We’ll see though. Let’s try to add a command job though and see what happens.

Here there is one binary which stands out: /usr/local/bin/backup. Depending on how closely you examined the app.js for the myplace application, you may also recognize it. If we go back and view that file, you’ll notice:

So backup is something that the web application is using to generate our backups on the system and it’s a set UID file meaning that it’s running with escalated privileges. Let’s try to backup the root directory and see what happens:

So it seems that isn’t the right way to reach it. Wonder why we aren’t able to get it… Let’s try to understand what it’s doing by tracing the application. We’ll start with the ltrace utility which is used to trace the library calls used by the application. We’ll want to run it against a successful backup to see the full execution.

Looking at this, we see that the binary is actually doing a comparison against things like /etc, /root, etc. and if it’s set, seems to change something to nil. That could be what we’re hitting, something filtering what we’re doing.

Let’s see if we can bypass this restriction using some bash tricks for expansion. Specifically, let’s take advantage of the fact that ~username can be used to expand to a particular directory. For example:

Author Kevin Kirsche

Kevin is a Principal Security Architect with Verizon. He holds the OSCP, OSWP, OSCE, and SLAE certifications. He is interested in learning more about building exploits and advanced penetration testing concepts.