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

THM Writeup โ€“ VulnNet: Node

April 11, 2022

THM Writeup - VulnNet: Node

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

Room: VulnNet: Node

Difficulty: Easy

Operating System: Linux

Author: SkyWaves

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/

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 here โ€“ 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