module Msf module Exploit::Git::Lfs def generate_pointer_file(obj_data) return '' if obj_data.empty? <<-PTR_FILE version https://git-lfs.github.com/spec/v1 oid sha256:#{Digest::SHA256.hexdigest(obj_data)} size #{obj_data.length} PTR_FILE end # Generates a Git LFS response to a batch request # # @param request [Rex::Proto::Http::Request] The Git LFS request # @param server_addr [String] The URL of the Git server # @param repo_objects [Array] The list of objects in the Git repo # # @return [Msf::Exploit::Git::Lfs::Response] def get_batch_response(request, server_addr, repo_objects) server_addr = server_addr.to_s unless server_addr.kind_of?(String) server_addr = server_addr.gsub(/\/\w+\.git/, '') repo_objects = [ repo_objects ] unless repo_objects.kind_of?(Array) response = Msf::Exploit::Git::Lfs::Response.from_http_request(request, server_addr) return nil unless response unless response.valid_objects?(repo_objects) || response.code != 200 print_error('Client requested objects not in repository') return response end obj_data_arr = [] response.valid_objs.each do |obj| sha = Msf::Exploit::Git::Lfs::Response.obj_sha256(obj.content) time = Time.now + 3600 obj_data_arr << { 'oid' => sha, 'size' => obj.content.size, 'actions' => { 'download' => { 'href' => "#{response.base_addr}/#{sha}", 'expires_at' => time.strftime("%FT%TZ"), 'expires_in' => 3600 } } } end response.body = { 'objects' => obj_data_arr }.to_json response end # Generates a response to a Git LFS object request # # @param request [Rex::Proto::Http::Request] Git client request # @param repo_objects [Array] List of objects in Git repository # # @return [Msf::Exploit::Git::Lfs::Response] def get_requested_obj_response(request, repo_objects) repo_objects = [ repo_objects ] unless repo_objects.kind_of?(Array) response = Msf::Exploit::Git::Lfs::Response.from_http_request(request) return nil unless response unless response.valid_objects?(repo_objects) || response.code != 200 print_error('Client requested an object that is not in the repository') return response end response.body = response.valid_objs.first.content response end end end