-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
Refactoring SPIP Modules for Windows Compatibility and Incorporating SPIP Mixin #19432
Conversation
The module's `check` method attempts to obtain the SPIP version via a simple HTTP | ||
GET request to the `/spip.php` page and fingerprints it either via the `generator` meta tag or the `Composed-By` header. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed.
# Determine Spip plugin version by name | ||
# | ||
# @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') | ||
) | ||
|
||
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 | ||
) | ||
|
||
return parse_plugin_version(config_res.body, plugin_name) if config_res&.code == 200 | ||
|
||
nil | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this update, I’ve added the spip_plugin_version
function to retrieve the version of a specified plugin from a SPIP instance.
Here’s what the new function does:
- Checks the
Composed-By
header: It parses this header to extract the plugin version, if available. - Fetches from
local/config.txt
: If a URL forlocal/config.txt
is provided in the header, the function retrieves the version from there. - Direct fallback to
local/config.txt
: If no version is found, the function attempts to directly access/local/config.txt
to fetch the plugin version.
Example with exploit/multi/http/spip_porte_plume_previsu_rce
:
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
[*] SPIP version is in the vulnerable range.
[+] The target appears to be vulnerable. The detected SPIP version (4.2.12) and porte_plume 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 1 opened (192.168.1.36:4444 -> 192.168.1.36:59732) at 2024-09-04 22:04:05 +0200
…on (avoiding confusion with cmdstager)
…ig.txt or Composed-By header
2e3f31e
to
43fabb0
Compare
Release NotesRefactor SPIP Modules for Windows Compatibility and Incorporating SPIP Mixin |
Hi Metasploit Team,
I've been working on refactoring the SPIP modules to ensure compatibility with Windows and to adapt them to the new module syntax. This work is aimed at enhancing integration and improving cross-platform compatibility.
Modules Affected:
exploit/multi/http/spip_rce_form
(Moved fromexploit/unix/webapp
)exploit/multi/http/spip_connect_exec
(Moved fromexploit/unix/webapp
)exploit/multi/http/spip_porte_plume_previsu_rce
Updates:
Unfortunately, I encountered some issues with the previous Pull Request #19406 due to mistakes I made with Git. As a result, I closed the old PR and have opened this new one. I've also made a specific update to the SPIP mixin to handle older SPIP versions that include extra information like
[number]
after the version number (e.g.,2.0.0 [14344]
). The new regex now correctly extracts just the version number, ensuring better accuracy with older versions.Tests:
I've conducted the following tests to verify the functionality of the refactored modules:
exploit/multi/http/spip_connect_exec
exploit/multi/http/spip_rce_form
exploit/multi/http/spip_porte_plume_previsu_rce