VulnNet: Node (Node.js deserialization + /npm privesc and services privesc)

THM Writeup – VulnNet: Node

April 11, 2022arrow-up-right

THM Writeup - VulnNet: Node

After the previous breach, VulnNet Entertainment states it won’t happen again. Can you prove they’re wrong?

Room: VulnNet: Nodearrow-up-right

Difficulty: Easy

Operating System: Linux

Author: SkyWavesarrow-up-right

VulnNet Entertainment has moved its infrastructure and now they’re confident that no breach will happen again. You’re tasked to prove otherwise and penetrate their network.

This is again an attempt to recreate some more realistic scenario but with techniques packed into a single machine. Good luck!

Add IP address to your hosts file:

Scan the target machine – find open ports first:

Get more details about open ports:

Enumeration

Explore the web application – browse to http://node.thm:8080/arrow-up-right

webapp on port 8080

I viewed the page source, but found nothing interesting, then I noticed a cookie, that looks like Base64 encoded:

base64 encoded cookie

Grab the cookie and paste it e.g. to the BurpSuite’s Decoder – first URL decode it and then Base64 decode it:

burpsuite decoder decoding

This looks great – a JSON that says the app what user are we – let’s try to bypass authentication completelly.

Take the JSON, modify it, Base64 encode it and finally URL encode it:

burpsuite decoder encoding

Now take the encoded text and modify the cookie via developer console, then refresh the page:

webapp admin page

Do you see the difference? There is β€œWELCOME, ADMIN” instead of β€œWELCOME, GUEST”, however the app still asks us for credentials. Hm nevermind, I remember I did a box few weeks ago where I exploited nodejs deserialization vulnerability. This app definitely uses deserialization, otherwise how would it know we changed the cookie to be Admin? We can even prove it…

Change the cookie again, but this time set the cookie value to some gibberish (random text) and refresh the page:

nodejs deserialization error

Here we have the proof.

Use this script to generate a payload:

You can find the original script herearrow-up-right – the above is modified version so it can be run with python3 and the output is Base64 encoded.

Save it to a file e.g. nodejsshell.py

Generate the payload:

Copy generated payload, paste it to the BurpSuite’s Decoder and URL encode it:

burp suite url encoding

Run a listener on your attacking machine:

Now take the URL encoded payload, paste it as value of the cookie and refresh the page:

webapp modified cookie

And we received a reverse connection – simple shell.

User flag

We need to stabilize the shell:

Look around a little bit:

Ok, we are www user and we are in its home directory, there is no user flag and we don’t have permissions even to look into serv-manageβ€˜s home directory.

Let’s try to find how to escalate our privileges:

We can run npm as serv-manage user.

Check GTFOBins how to exploit it:

gtfobins sudo npm

Now exploit it:

As you can see we need to set full permissions before we run sudo npm as serv-manage user.

Read the user flag:

Root flag

Spawn a shell:

Let’s find a privilege escalation vector to root user:

We can start and stop vulnnet-auto.timer service as root without password.

Find the vulnnet-auto.timer service location and check the permissions:

This is great – as user serv-manage we have write permissions to vulnnet-auto.timer

Check the content:

Hm, this service calls other service named vulnnet-job.service every 30 minutes.

First we have to check if we have write permissions also to vulnnet-job.service:

Great, so we’ll use this misconfigurations to escalate our privileges to root – actually it is a combination of misconfigurations:

  • we can restart (start/stop) the vulnnet-auto.timer service

  • we have write permissions to both services: vulnnet-auto.timer and vulnnet-job.service

  • we can reload the daemon (systemd files) – we need to do this after we change the services definitions

See the content of vulnnet-job.service:

Here we need to change ExecStart parameter.

Ok, first change the content of vulnnet-auto.timer:

We change only OnCalendar value – so the services runs every minute.

Now change the content of vulnnet-job.service:

Now stop vulnnet-auto.timer service, reload systemd files and start vulnnet-auto.timer:

Wait a minute and check if /tmp/bashroot was created.

If it was, execute and you’re root now:

Our effective permissions are root…

Read the root flag:

Last updated