Bug 1053600 - VUL-1: libvirt: ssh command injection
VUL-1: libvirt: ssh command injection
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P4 - Low : Normal
: ---
Assigned To: Security Team bot
Security Team bot
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2017-08-14 06:40 UTC by Marcus Meissner
Modified: 2019-12-26 16:59 UTC (History)
3 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcus Meissner 2017-08-14 06:40:34 UTC
from the libvirt security list

(not directly, just indirectly exploitable)

Date: Fri, 11 Aug 2017 17:23:18 +0100
From: "Daniel P. Berrange" <berrange@redhat.com>


On Fri, Aug 11, 2017 at 05:17:49PM +0100, Daniel P. Berrange wrote:
> On Fri, Aug 11, 2017 at 04:46:29PM +0100, Dr. David Alan Gilbert wrote:
> > (Originally reported as
> > https://bugzilla.redhat.com/show_bug.cgi?id=1480337 )
> > 
> > virsh isn't sanitising the address parameters before they end up at ssh:
> > 
> > $ virsh -c 'qemu+ssh://root@-help/system' list
> > error: failed to connect to the hypervisor
> > error: Cannot recv data: unknown option -- h
> > usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
> >            [-D [bind_address:]port] [-E log_file] [-e escape_char]
> >            [-F configfile] [-I pkcs11] [-i identity_file]
> >            [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
> >            [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
> >            [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
> >            [user@]hostname [command]: Connection reset by peer
> > 
> > I came to this from CVE-2017-1000117 which git/etc just announced -
> > I bet there's a load of other similar places
> > 
> > I'm marking this security given where the idea came from, I'm not sure I
> > can think of an exploit though, so it might be OK to clear it? The worst
> > case I think of are places where the guest or remote qemu can specify
> > a path, how about something like the spice transparent hand off?
> 
> The git flawed showed using -oProxyCommand to trick spawning a process.
> 
>    $ git clone ssh://-oProxyCommand=gnome-calculator/wat
> 
> would launch gnome-calculator.
> 
> The only time libvirt exec's SSH is with the libvirt URIs.
> 
> SPICE or migration URIs aren't impacted as they're exclusively
> plain sockets.
> 
> The Phyp driver uses ssh, but not via the binary, instead
> via libssh. So the '-oProxyCommand=gnome-calculator' getts
> interpreted as a hostname by libssh and thus fails.
> 
> 
> The libvirt URIs are used by the libvirt client library to connect
> to a remote libvirtd. This is run by the client app when connecting
> to libvirt, or by the source host libvirtd when connecting to a
> target host libvirtd during migration, when PEER2PEER flag is
> set.
> 
> I think I'd argue that virDomainMigrate() is a command which
> implies elevated privileges, since you can pass arbitrary
> XML into the API. This would let you exploit the target host
> libvirtd via malicious XML. The target host could then do
> the reverse to attack the source host again.  IOW virDomainMigrate
> should be considered equivalent to having root privs on source
> and target hosts.  As such, if we were able to trick libvirt
> to run a command via SSH, you'd not be getting privileges
> you did not alrady have.
> 
> 
> Now, testing with the specific exploit shown, we normally run
> 
>   ssh '$HOSTNAME'  'sh' '-c' '"a bit of shell script to run nc"'
> 
> With
> 
>   virsh -c  qemu+ssh://-oProxyCommand=gnome-calculator/system
> 
> we end up running
> 
>   ssh '-oProxyCommand-gnome-calculator'  'sh' '-c' '"a bit of shell script to run nc"'
> 
> ssh interprets '-oProxyCommand-gnome-calculator' as an arg. It
> then interpets 'sh' as a hostname to connect to.
> 
> Crucially it interprets '-c' as a *local* flag, which makes it then
> intepret   '"a bit of shell script to run nc"'  as a cipher name.
> It exits at this point. So despite parsing -oproxycommand-gnome-calculator,
> it never gets as far as trying to run it.
> 
> Due to the way libvirt execs ssh, you can't trick it using whitespace
> in the URI
> 
> eg
> 
>   virsh -c  qemu+ssh://-oProxyCommand=gnome-calculator realhostname/system
> 
> will make ssh see   "-oProxyCommand=gnome-calculator realhostname" as a
> single argument still, so it would try to exec 'gnome-calculator realhostname'
> as a command which would fail. It
> 
> So, I think we safe on multiple levels here.
> 
> 
> None the less, I suggest we change to running SSH using
> 
>   ssh -- '$HOSTNAME'  'sh' '-c' '"a bit of shell script to run nc"'
> 
> which forces SSH to intepret "-oProxyCommand=gnome-calculator" as a hostname
> and not a local argument.
IOW, I'll propose

>From 62b24570d9656c4a1c930606c5c0955ad620f11d Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Fri, 11 Aug 2017 17:19:53 +0100
Subject: [PATCH] rpc: avoid ssh interpreting malicious hostname as arguments

Consider the URI:

  virsh -c qemu+ssh://-oProxyCommand=gnome-calculator/system

In this case, the hosname "-oProxyCommand=gnome-calculator"
will get interpreted as an argument to ssh, not a hostname.
Fortunately, due to the set of args we have following the
hostname, SSH will then interpret our bit of shell script
that runs 'nc'  on the remote host as as cipher name. This
makes it exit and so it never tries to run gnome-calculator.

We are lucky this time, but lets be more paranoid, by using
'--' to explicitly tell SSH when it has finished seeing
command line options. This forces it to interpret
"-oProxyCommand=gnome-calculator" as a hostname, and thus
see a fail.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 src/rpc/virnetsocket.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index d228c8a8c..23089afef 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -868,7 +868,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
     if (!netcat)
         netcat = "nc";
 
-    virCommandAddArgList(cmd, nodename, "sh", "-c", NULL);
+    virCommandAddArgList(cmd, "--", nodename, "sh", "-c", NULL);
 
     virBufferEscapeShell(&buf, netcat);
     if (virBufferCheckError(&buf) < 0) {
-- 
2.13.3



Regards,
Daniel
Comment 1 Johannes Segitz 2017-08-14 11:09:33 UTC
Hardening -> VUL-1
Comment 2 James Fehlig 2017-08-14 14:17:49 UTC
The code in question has been around forever, so the libvirt package in all maintained products is affected.
Comment 3 James Fehlig 2017-08-29 22:47:29 UTC
Fix hit the public repo today, so definitely not embargoed :-)

http://libvirt.org/git/?p=libvirt.git;a=commit;h=e4cb8500810a310a10a6cb359e1b53fac03ed597

I've added it to the libvirt packages in our SLE12 SP{2,3} devel repos. Will finish the rest tomorrow...
Comment 4 James Fehlig 2017-08-30 20:21:54 UTC
Removing "EMBARGOED" from summary since the fix is in a public repo.

I think I'm done with this bug. Fix is queued for a future maintenance update of SLE12 SP{2,3}, which also feeds Leap 42.{2,3}. Fix also submitted for Factory/SLE15 - SR#519736.

Mr. Maintenance: I've collected quite a few fixes for the SLE12 SP2 libvirt package. Should I submit it for a maintenance update?
Comment 5 Marcus Meissner 2017-08-30 20:42:13 UTC
making bug public.
Comment 6 James Fehlig 2017-08-31 22:29:42 UTC
Opps, forgot about SLE11 SP4. I now have the fix queued for a future maintenance update of the SP4 libvirt package as well.
Comment 7 Leonardo Chiquitto 2017-09-06 17:39:00 UTC
> Mr. Maintenance: I've collected quite a few fixes for the SLE12 SP2 libvirt
> package. Should I submit it for a maintenance update?

Sounds good. Please submit to SUSE:SLE-11-SP4:Update, SUSE:SLE-12-SP2:Update SUSE:SLE-12-SP3:Update.
Comment 8 James Fehlig 2017-09-15 21:16:27 UTC
(In reply to Leonardo Chiquitto from comment #7)
> Please submit to SUSE:SLE-11-SP4:Update, SUSE:SLE-12-SP2:Update
> SUSE:SLE-12-SP3:Update.

Thanks. The submissions are done now.

I'm finished with the bug. Reassigning to security team.
Comment 10 Swamp Workflow Management 2017-09-29 13:08:04 UTC
SUSE-SU-2017:2598-1: An update that contains security fixes can now be installed.

Category: security (moderate)
Bug References: 1045693,1049505,1051017,1053600
CVE References: 
Sources used:
SUSE Linux Enterprise Software Development Kit 12-SP3 (src):    libvirt-3.3.0-5.3.1
SUSE Linux Enterprise Server 12-SP3 (src):    libvirt-3.3.0-5.3.1
SUSE Linux Enterprise Desktop 12-SP3 (src):    libvirt-3.3.0-5.3.1
Comment 11 Swamp Workflow Management 2017-10-06 16:08:45 UTC
openSUSE-SU-2017:2653-1: An update that contains security fixes can now be installed.

Category: security (moderate)
Bug References: 1045693,1049505,1051017,1053600
CVE References: 
Sources used:
openSUSE Leap 42.3 (src):    libvirt-3.3.0-6.1
Comment 12 Swamp Workflow Management 2017-10-09 10:11:07 UTC
SUSE-SU-2017:2660-1: An update that contains security fixes can now be installed.

Category: security (moderate)
Bug References: 1025340,1026236,1053600
CVE References: 
Sources used:
SUSE Linux Enterprise Software Development Kit 11-SP4 (src):    libvirt-1.2.5-23.3.1
SUSE Linux Enterprise Server 11-SP4 (src):    libvirt-1.2.5-23.3.1
SUSE Linux Enterprise Debuginfo 11-SP4 (src):    libvirt-1.2.5-23.3.1
Comment 13 Swamp Workflow Management 2017-10-10 19:14:49 UTC
SUSE-SU-2017:2697-1: An update that contains security fixes can now be installed.

Category: security (moderate)
Bug References: 1012143,1017189,1031056,1036785,1048783,1049505,1051017,1052151,1053600
CVE References: 
Sources used:
SUSE Linux Enterprise Workstation Extension 12-SP2 (src):    libvirt-2.0.0-27.20.1
SUSE Linux Enterprise Software Development Kit 12-SP2 (src):    libvirt-2.0.0-27.20.1
SUSE Linux Enterprise Server for Raspberry Pi 12-SP2 (src):    libvirt-2.0.0-27.20.1
SUSE Linux Enterprise Server 12-SP2 (src):    libvirt-2.0.0-27.20.1
SUSE Linux Enterprise Desktop 12-SP2 (src):    libvirt-2.0.0-27.20.1
Comment 14 Swamp Workflow Management 2017-10-11 22:13:14 UTC
openSUSE-SU-2017:2708-1: An update that contains security fixes can now be installed.

Category: security (moderate)
Bug References: 1012143,1017189,1031056,1036785,1048783,1049505,1051017,1052151,1053600
CVE References: 
Sources used:
openSUSE Leap 42.2 (src):    libvirt-2.0.0-13.9.1
Comment 15 Marcus Meissner 2017-10-25 16:59:37 UTC
released