Bug 5730 - [CRITICAL]Arbitrary command execution in mercurial repo with a git submodule
Summary: [CRITICAL]Arbitrary command execution in mercurial repo with a git submodule
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: stable branch
Hardware: All All
: wish bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-11-03 02:30 UTC by Zhang Tianqi
Modified: 2017-11-30 21:26 UTC (History)
3 users (show)

See Also:


Attachments
evil poc hg repo to test this issue. (16.29 KB, application/x-zip-compressed)
2017-11-03 02:33 UTC, Zhang Tianqi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zhang Tianqi 2017-11-03 02:30:42 UTC
I found that using hg to track a crafted mercurial repo with a git submodule can lead to command execution on user's OS.

The root cause is that hg support to add a git submodule to a hg repo.And so that i can use hg to track .git directory and thus modify the git config file from the remote.I use ext helper protocol as a poc.I can modify the git config file to allow ext helper protocol which has been disallowed in the lastest version of git and then when victim do anything on the evil git submodule,ext protocol will be triggered and execute the os command.

Here is the reproduction steps:
1.Create a hg repo;
2.Create a git repo and make a commit to it.(The commit is a must.)
3.Now let us use hg to make a crafted hg repo first.
4.Using hg to checkout the hg repo and then add that git repo as it's submodule.
5.Modify the ./hgrepo/gitsubmodule/.git/config to sth like:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "pwn2own"]
    url = ext::whoami
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[protocol]
    allow = always
I modify two parts,change the remote url to "ext::whoami" and add a protocol section to allow ext protocol to be used.

Then commit all above changes and push to the remote.

When other victim using hg command to clone that crafted repo and pull,fetch,checkout,push,etc in the git submodule.Our command will be executed.As we already can control the git config file on the remote,lots of options we can use to execute command or do other things.

Mercurial accidently cover the .git folder with user applied .git folder during hg cloning so that give attacker a chance to modify the config file and lead to command execution.

This one i firstly reported to sourcetree but later i found the root cause was on the mercurial side,so i decided to double report it here.
Comment 1 Zhang Tianqi 2017-11-03 02:33:46 UTC
Created attachment 1984 [details]
evil poc hg repo to test this issue.
Comment 2 Gregory Szorc 2017-11-03 03:14:24 UTC
Thank you for reporting the problem. It is being looked at.

Given the potential security implications of this bug report, we'll likely be quiet until more is known.

Also, when reporting potential security bugs to *any* project, please try to avoid disclosing the issue on public forums (like this bug tracker) until the issue is addressed. Disclosing before a fix is ready gives more time to bad actors to exploit the problem before the good actors can fix it, release it, and install the fix. It also creates chaos on the good actors to fix the problem in an overly expedient manner in order to minimize potential impact. This can result in incomplete fixes and longer exposure to the issue. Not to mention it is highly disruptive for everyone involved. Search for "responsible disclosure" to learn more.

For the Mercurial project, instructions for responsible security disclosure are at https://www.mercurial-scm.org/wiki/SecurityDisclosureProcess
Comment 3 HG Bot 2017-11-07 13:25:19 UTC
Fixed by https://mercurial-scm.org/repo/hg/rev/071cbeba4212
Yuya Nishihara <yuya@tcha.org>
subrepo: disallow symlink traversal across subrepo mount point (SEC)

It wasn't easy to extend the pathauditor to check symlink traversal across
subrepos because pathauditor._checkfs() rejects a directory having ".hg"
directory. That's why I added the explicit islink() check.

No idea if this patch is necessary after we've fixed the issue5730 by
splitting submerge() into planning and execution phases.

(please test the fix)
Comment 4 HG Bot 2017-11-07 13:25:23 UTC
Fixed by https://mercurial-scm.org/repo/hg/rev/5e27afeddaee
Yuya Nishihara <yuya@tcha.org>
subrepo: add config option to reject any subrepo operations (SEC)

This is an alternative workaround for the issue5730.

Perhaps this is the simplest way of disabling subrepo operations. It does
nothing clever, but just aborts if Mercurial starts accessing to a subrepo.

I think Greg's patch is more useful since it allows us to at least check
out the parent repository. However, that would be confusing if the default
is flipped to checkout=False and subrepos are silently ignored.

I don't like the config name 'allowed', but I couldn't get any better name.

(please test the fix)
Comment 5 Bugzilla 2017-11-15 00:00:05 UTC
Bug was set to TESTING for 7 days, resolving
Comment 6 Zhang Tianqi 2017-11-30 00:38:34 UTC
Is this issue has been fixed? And can i request a cve id and a disclosure?

Thanks.
Comment 7 Gregory Szorc 2017-11-30 21:26:44 UTC
This was fixed in Mercurial 4.4.1. https://www.mercurial-scm.org/wiki/WhatsNew#Mercurial_4.4.1_.282017-11-07.29

Also, this bug has been public since the second it was filed. The vulnerability has been disclosed. Mercurial's various mailing lists (including its security announce list) were notified of this issue shortly after this bug was reported and after a release with a fix was made.