Skip to content

Commit

Permalink
Add check_setup to jenkins login scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelch-r7 committed Aug 12, 2024
1 parent 233f6dc commit 05f1f55
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
26 changes: 25 additions & 1 deletion lib/metasploit/framework/login_scanner/jenkins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Jenkins < HTTP

# (see Base#set_sane_defaults)
def set_sane_defaults
self.uri = "/j_acegi_security_check" if self.uri.nil?
self.uri = "/" if self.uri.nil?
self.method = "POST" if self.method.nil?

if self.uri[0] != '/'
Expand All @@ -25,6 +25,30 @@ def set_sane_defaults
super
end

# (see Base#check_setup)
def check_setup
login_uri = jenkins_login_uri
if login_uri.nil?
error_message = 'Unable to locate the Jenkins login path'
else
self.uri = normalize_uri(login_uri)
error_message = false
end

error_message
end

def jenkins_login_uri
res = send_request({ 'uri' => normalize_uri('login') })
if res&.code == 200 && res&.body =~ Msf::Exploit::Remote::HTTP::Jenkins::LOGIN_PATH_REGEX
login_path = Regexp.last_match(1)
ilog("Found jenkins login path: #{login_path}")
return login_path
end
wlog('Failed to identify the login resource.')
nil
end

def attempt_login(credential)
result_opts = {
credential: credential,
Expand Down
6 changes: 4 additions & 2 deletions lib/msf/core/exploit/remote/http/jenkins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Remote
module HTTP
# This module provides a way of logging into Jenkins
module Jenkins

LOGIN_PATH_REGEX = /action="(j_([a-z0-9_]+))"/
# Returns the Jenkins version.
#
# @return [String] Jenkins version.
Expand All @@ -15,7 +17,7 @@ def jenkins_version
res = send_request_cgi({ 'uri' => uri })

unless res
return nil
return nil
end

# shortcut for new versions such as 2.426.2 and 2.440
Expand All @@ -36,7 +38,7 @@ def jenkins_uri_check(target_uri, keep_cookies: false)
# if keep_cookies is true we get the first cookie that's needed by newer Jenkins versions
res = send_request_cgi({ 'uri' => normalize_uri(target_uri, 'login'), 'keep_cookies' => keep_cookies })
fail_with(Msf::Module::Failure::UnexpectedReply, 'Unexpected reply from server') unless res&.code == 200
if res.body =~ /action="(j_([a-z0-9_]+))"/
if res.body =~ LOGIN_PATH_REGEX
uri = Regexp.last_match(1)
else
fail_with(Msf::Module::Failure::UnexpectedReply, 'Failed to identify the login resource.')
Expand Down
10 changes: 8 additions & 2 deletions modules/auxiliary/scanner/http/jenkins_login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ def run_host(ip)
password: datastore['PASSWORD']
)

login_uri = jenkins_uri_check(target_uri)
scanner = Metasploit::Framework::LoginScanner::Jenkins.new(
configure_http_login_scanner(
uri: normalize_uri(login_uri),
uri: '/',
ssl: datastore['SSL'],
method: datastore['HTTP_METHOD'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
Expand All @@ -52,6 +52,12 @@ def run_host(ip)
)
)

msg = scanner.check_setup
if msg
print_brute level: :error, ip: ip, msg: msg
return
end

scanner.scan! do |result|
credential_data = result.to_h
credential_data.merge!(
Expand Down

0 comments on commit 05f1f55

Please sign in to comment.