[libvirt] Possible security hole? unprivileged user can use virsh to overwrite sensitive system file

I found there's a way for a unprivileged user to overwrite sensitive system file with virsh, here's how: 1. (as an unprivileged user) start virsh and connect to the r/w socket of libvirtd: virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock 2. start a guest, then issue 'save' or 'dump' command, giving a sensitive system file path as the <file> parameter, for example, '/etc/passwd'; 3. the sensitive system file will be overwritten; Attached is a test log. I'm using libvirt-0.8.7 on a OpenClient for RHEL 6.1. And latest libvirt code shows the same symptom. BTW, virsh expands the <file> parameter in step to an absolute path if user-provided is not, and libvirtd interprets it as a local file. IMHO it does not look quite right, especially when the virsh-to-libvirtd connection is remote. -- Thanks. Hong Xiang

On 10/12/2011 11:57 AM, Hong Xiang wrote:
[hxiang@T420 ~]$ cat /etc/redhat-release Red Hat Enterprise Linux Workstation release 6.1 (Santiago) [hxiang@T420 ~]$ cat /etc/openclient-release Open Client RHEL 64 3.10 (Gold Master) [hxiang@T420 ~]$ libvirtd --version libvirtd (libvirt) 0.8.7 [hxiang@T420 ~]$ virsh -V Virsh command line tool of libvirt 0.8.7 See web site athttp://libvirt.org/
Compiled with support for: Hypervisors: QEmu/KVM LXC ESX Test Networking: Remote Daemon Network Bridging Netcf Nwfilter VirtualPort Storage: Dir Disk Filesystem SCSI Multipath iSCSI LVM Miscellaneous: SELinux Secrets Debug DTrace Readline [hxiang@T420 ~]$ ls -l /etc/precious.* -rw-r--r--. 1 root root 2 Oct 12 11:38 /etc/precious.1 -rw-r--r--. 1 root root 2 Oct 12 11:38 /etc/precious.2 [hxiang@T420 ~]$ virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands 'quit' to quit
virsh # start fc15 ^_ _ _ it seems you're using privileged user to login virsh, I remembered that it should be "virsh >" not "virsh #" when use unprivileged user, I assume you hadn't any modification in libvirtd.conf, in addition, for unprivileged user, as usual, libvirt will raise the following information if you're trying to connect hypervisor:
Tested it on libvirt-0.8.2-22.el5: $ virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock --readonly error: unable to connect to '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: Permission denied error: failed to connect to the hypervisor Tested it on libvirt-0.9.4-16.el6.x86_64: $ virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock --readonly error: authentication failed: authentication failed error: failed to connect to the hypervisor Regards, Alex
Domain fc15 started
virsh # dump fc15 /etc/precious.1 Domain fc15 dumped to /etc/precious.1
virsh # save fc15 /etc/precious.2 Domain fc15 saved to /etc/precious.2
virsh # [hxiang@T420 ~]$ ls -l /etc/precious.* -rw-r--r--. 1 root root 253777159 Oct 12 11:42 /etc/precious.1 -rw-r--r--. 1 root root 257745683 Oct 12 11:42 /etc/precious.2 [hxiang@T420 ~]$

On Wed, Oct 12, 2011 at 11:57:25AM +0800, Hong Xiang wrote:
I found there's a way for a unprivileged user to overwrite sensitive system file with virsh, here's how: 1. (as an unprivileged user) start virsh and connect to the r/w socket of libvirtd: virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock
Unless you have turned off authentication, this requires you to provide your root password via PolicyKit. Thus you can no longer be considered an 'unprivileged' user after this point.
2. start a guest, then issue 'save' or 'dump' command, giving a sensitive system file path as the <file> parameter, for example, '/etc/passwd'; 3. the sensitive system file will be overwritten;
There's no security hole. If you have successfully authenticated to the privileged libvirtd daemon over the read-write socket, then you are considered to have a privilege level equivalent to a root shell. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

It turned out that in my environment the user 'hxiang' I was testing with is in group 'desktop_admin_r' and PolicyKit takes all users in that group as administrators. That's why I could connect without authentication. Sorry for the false alarm. On 10/12/2011 04:22 PM, Daniel P. Berrange wrote:
On Wed, Oct 12, 2011 at 11:57:25AM +0800, Hong Xiang wrote:
I found there's a way for a unprivileged user to overwrite sensitive system file with virsh, here's how: 1. (as an unprivileged user) start virsh and connect to the r/w socket of libvirtd: virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock
Unless you have turned off authentication, this requires you to provide your root password via PolicyKit. Thus you can no longer be considered an 'unprivileged' user after this point.
2. start a guest, then issue 'save' or 'dump' command, giving a sensitive system file path as the<file> parameter, for example, '/etc/passwd'; 3. the sensitive system file will be overwritten;
There's no security hole. If you have successfully authenticated to the privileged libvirtd daemon over the read-write socket, then you are considered to have a privilege level equivalent to a root shell.
Regards, Daniel
-- Thanks. Hong Xiang
participants (3)
-
Alex Jia
-
Daniel P. Berrange
-
Hong Xiang