Abhishek Rautela

Feb 13, 2021

9 min read

Hack The Box: Cronos Writeup [Laravel Cron Job Privesc]

Cronos was rated medium difficulty that required basic SQL injection to get a foothold and command injection to get a reverse shell. The box was actually an easy one. The privilege escalation part was interesting where I learned how to exploit Laravel cron job.

Let’s jump in.


I prefer running manual commands as they provide better control and prevent us from getting blocked by any firewall but due to time restrictions in the OSCP environment I decided to learn using autorecon.

You can run autorecon as follows:

Nmap Scan results:

We get only three ports as open.

  • Port 22 — SSH
  • Port 53 — DNS
  • Port 80 — HTTP

The UDP scan returns the following result:

We have only DNS listening on UDP.

Let’s begin our enumeration and try to understand the box better.


  • Port 22 — OpenSSH 7.2p2 Ubuntu.

One google search reveals that the box is probably Ubuntu Xenial.

SSH is considered to be a secure service and until we have any valid credentials, there is very low probability of it being an attack vector. Let’s move on to the next port for the time being.

  • Port 53 — DNS (TCP/UDP)

Let’s run NSLOOKUP to resolve the ip and find any possible hostname or nameserver.

We get a hostname ns1.cronos.htb. Great, this also provides us the base domain i.e. cronos.htb

Let’s try a DNS zone transfer and enumerate other subdomains.

Great. We now have two more subdomains to look at.

Lets add all the hosts to the /etc/hosts file.

  • Port 80 — HTTP

HTTP has the largest attack vector and I prefer to enumerate it at the end, when I have no other port/service to look at.

Visiting the ip reveals a default Apache webpage

Autorecon automatically runs gobuster for directory bruteforcing and we didn’t get anything interesting, so let’s move on for now.

As we have already added the hostnames to our /etc/hosts file we can visit them one by one.

We get a webpage with some links.

Inspecting the source code indicates that the webpage is probably built on Laravel.

The admin.cronos.htb subdomain reveals a login page.

The first thing I tried was using common credentials such as admin/admin, admin/password, root/root, root/password. No luck.

The application seems to be a custom one, so there is a very low chance of a default credential.

Let’s try a basic SQL injection.

We are in…!!!!

You can try other SQL payloads to bypass the Login form. One such list of payloads can be found here:

We get a welcome.php page which has a ping functionality. Let’s try to ping our ip.

We can listen on our local machine with tcpdump.

The above command enables tcpdump to listen on our tun0 interface and capture only ICMP packets. ICMP stands for Internet control message protocol. You can read about it here:


We get a hit. The ping functionality works…!!!!

Whenever I see a web app running system commands the first thing I want to check is OS command injection vulnerability, which allows an attacker to inject system commands in a legitimate web command using line terminator or special characters such as & | ; or $(whoami). If you are not familiar with it you can read this article.

Let’s try injecting a command as follows

Sweet. We have identified a vulnerability. It’s time to get a reverse shell.


Let’s intercept the request in burp as it provides better control and we can use repeater to get multiple shells easily.

Both the command and host field are vulnerable to command injection.

Change the command field to a bash reverse shell. Don’t forget to urlencode the reverse shell by highlighting the entire reverse shell command and pressing ctrl+u. You can decode the string by pressing ctrl+shift+u.

We get a shell as www-data user

Get an interactive shell with tty with following commands.

Hit ctrl+z to background the job.

Type fg(You will not be able to view the characters as you type) and hit enter twice:

Export the TERM variable:

In another window check the number of rows and columns:

Set the number of rows and columns in our reverse shell:

We now have a fully interactive shell with tab autocomplete.

Privilege Escalation

Before we run any automated tool let’s check the basic privesc vectors like SUID, SUDO and cron jobs.

We do not find anything interesting. Let’s check cron jobs.

Great. We get a php cron running in /var/www/laravel. For those who don’t know Cron jobs are scheduled tasks that run after every specific interval of time. In our case the cron job is running every minute as it has stars all across. The following diagram explains the functioning of a cron.

You can read more about cron here:

We could either leverage this by overwriting the cron file, but altering a legitimate cron file is a bad practice and can cause serious consequences if done in a production environment.

We’ll do it the “right” way by creating a scheduled task in Laravel.

Check the task scheduling section in laravel docs at following link:

The docs specify modifying the Kernel.php file and calling a system command within the schedule function.

We can now leverage the cron job to get a root shell.

Let’s navigate to /var/www/laravel/app/Console. We do have a Kernel.php file and thankfully we own the file and have write access to it.

Add a system call in the schedule function.

Save the Kernel.php file and create a netcat listener.

In a minute the cron runs and we get a shell as root.

For suggestions/queries you can contact me on twitter @accesscheck. Thank You.