Hi everyone, i think we have another exploit path.
1. Create some normal server and login to it
2. Create an empty volume (on the backend the volume must be created as raw and not as qcow2)
3. Attach the volume to the server
4. Write a malicious qcow2 file to the volume from the VM (so that qemu-img info /dev/vdb works)
5. Create a snapshot from the volume
6. Create a new volume from the snapshot
7. Attach the new volume to the same VM
On our side this fails with the following traceback, but it just need the backing file to be writeable.
I'll try to find out why the volume is not attached as raw, but maybe someone knows more.
Traceback (most recent call last):
File \"/usr/local/lib/python3.10/dist-packages/oslo_messaging/rpc/server.py\", line 165, in _process_incoming
res = self.dispatcher.dispatch(message)
File \"/usr/local/lib/python3.10/dist-packages/oslo_messaging/rpc/dispatcher.py\", line 309, in dispatch
return self._do_dispatch(endpoint, method, ctxt, args)
File \"/usr/local/lib/python3.10/dist-packages/oslo_messaging/rpc/dispatcher.py\", line 229, in _do_dispatch
result = func(ctxt, **new_args)
File \"/usr/local/lib/python3.10/dist-packages/nova/exception_wrapper.py\", line 65, in wrapped
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/exception_wrapper.py\", line 63, in wrapped
return f(self, context, *args, **kw)
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/utils.py\", line 1439, in decorated_function
return function(self, context, *args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 211, in decorated_function
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 201, in decorated_function
return function(self, context, *args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 7338, in attach_volume
do_attach_volume(context, instance, driver_bdm)
File \"/usr/local/lib/python3.10/dist-packages/oslo_concurrency/lockutils.py\", line 414, in inner
return f(*args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 7335, in do_attach_volume
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 7333, in do_attach_volume
return self._attach_volume(context, instance, driver_bdm)
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 7355, in _attach_volume
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/compute/manager.py\", line 7352, in _attach_volume
bdm.attach(context, instance, self.volume_api, self.driver,
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/block_device.py\", line 46, in wrapped
ret_val = method(obj, context, *args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/block_device.py\", line 734, in attach
self._do_attach(context, instance, volume, volume_api,
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/block_device.py\", line 719, in _do_attach
self._volume_attach(context, volume, connector, instance,
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/block_device.py\", line 662, in _volume_attach
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/block_device.py\", line 657, in _volume_attach
virt_driver.attach_volume(
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/libvirt/driver.py\", line 2182, in attach_volume
with excutils.save_and_reraise_exception():
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 227, in __exit__
self.force_reraise()
File \"/usr/local/lib/python3.10/dist-packages/oslo_utils/excutils.py\", line 200, in force_reraise
raise self.value
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/libvirt/driver.py\", line 2167, in attach_volume
guest.attach_device(conf, persistent=True, live=live)
File \"/usr/local/lib/python3.10/dist-packages/nova/virt/libvirt/guest.py\", line 340, in attach_device
self._domain.attachDeviceFlags(device_xml, flags=flags)
File \"/usr/local/lib/python3.10/dist-packages/eventlet/tpool.py\", line 193, in doit
result = proxy_call(self._autowrap, f, *args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/eventlet/tpool.py\", line 151, in proxy_call
rv = execute(f, *args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/eventlet/tpool.py\", line 132, in execute
six.reraise(c, e, tb)
File \"/usr/lib/python3/dist-packages/six.py\", line 719, in reraise
raise value
File \"/usr/local/lib/python3.10/dist-packages/eventlet/tpool.py\", line 86, in tworker
rv = meth(*args, **kwargs)
File \"/usr/local/lib/python3.10/dist-packages/libvirt.py\", line 716, in attachDeviceFlags
raise libvirtError('virDomainAttachDeviceFlags() failed')
libvirt.libvirtError: internal error: unable to execute QEMU command 'blockdev-add': Could not open '/etc/passwd': Permission denied
Hi everyone, i think we have another exploit path.
1. Create some normal server and login to it
2. Create an empty volume (on the backend the volume must be created as raw and not as qcow2)
3. Attach the volume to the server
4. Write a malicious qcow2 file to the volume from the VM (so that qemu-img info /dev/vdb works)
5. Create a snapshot from the volume
6. Create a new volume from the snapshot
7. Attach the new volume to the same VM
On our side this fails with the following traceback, but it just need the backing file to be writeable.
I'll try to find out why the volume is not attached as raw, but maybe someone knows more.
Traceback (most recent call last): local/lib/ python3. 10/dist- packages/ oslo_messaging/ rpc/server. py\", line 165, in _process_incoming .dispatch( message) local/lib/ python3. 10/dist- packages/ oslo_messaging/ rpc/dispatcher. py\", line 309, in dispatch dispatch( endpoint, method, ctxt, args) local/lib/ python3. 10/dist- packages/ oslo_messaging/ rpc/dispatcher. py\", line 229, in _do_dispatch local/lib/ python3. 10/dist- packages/ nova/exception_ wrapper. py\", line 65, in wrapped save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/exception_ wrapper. py\", line 63, in wrapped local/lib/ python3. 10/dist- packages/ nova/compute/ utils.py\ ", line 1439, in decorated_function local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 211, in decorated_function save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 201, in decorated_function local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 7338, in attach_volume attach_ volume( context, instance, driver_bdm) local/lib/ python3. 10/dist- packages/ oslo_concurrenc y/lockutils. py\", line 414, in inner local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 7335, in do_attach_volume save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 7333, in do_attach_volume volume( context, instance, driver_bdm) local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 7355, in _attach_volume save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/compute/ manager. py\", line 7352, in _attach_volume attach( context, instance, self.volume_api, self.driver, local/lib/ python3. 10/dist- packages/ nova/virt/ block_device. py\", line 46, in wrapped local/lib/ python3. 10/dist- packages/ nova/virt/ block_device. py\", line 734, in attach _do_attach( context, instance, volume, volume_api, local/lib/ python3. 10/dist- packages/ nova/virt/ block_device. py\", line 719, in _do_attach _volume_ attach( context, volume, connector, instance, local/lib/ python3. 10/dist- packages/ nova/virt/ block_device. py\", line 662, in _volume_attach save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/virt/ block_device. py\", line 657, in _volume_attach driver. attach_ volume( local/lib/ python3. 10/dist- packages/ nova/virt/ libvirt/ driver. py\", line 2182, in attach_volume save_and_ reraise_ exception( ): local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 227, in __exit__ force_reraise( ) local/lib/ python3. 10/dist- packages/ oslo_utils/ excutils. py\", line 200, in force_reraise local/lib/ python3. 10/dist- packages/ nova/virt/ libvirt/ driver. py\", line 2167, in attach_volume attach_ device( conf, persistent=True, live=live) local/lib/ python3. 10/dist- packages/ nova/virt/ libvirt/ guest.py\ ", line 340, in attach_device _domain. attachDeviceFla gs(device_ xml, flags=flags) local/lib/ python3. 10/dist- packages/ eventlet/ tpool.py\ ", line 193, in doit self._autowrap, f, *args, **kwargs) local/lib/ python3. 10/dist- packages/ eventlet/ tpool.py\ ", line 151, in proxy_call local/lib/ python3. 10/dist- packages/ eventlet/ tpool.py\ ", line 132, in execute lib/python3/ dist-packages/ six.py\ ", line 719, in reraise local/lib/ python3. 10/dist- packages/ eventlet/ tpool.py\ ", line 86, in tworker local/lib/ python3. 10/dist- packages/ libvirt. py\", line 716, in attachDeviceFlags 'virDomainAttac hDeviceFlags( ) failed') libvirtError: internal error: unable to execute QEMU command 'blockdev-add': Could not open '/etc/passwd': Permission denied
File \"/usr/
res = self.dispatcher
File \"/usr/
return self._do_
File \"/usr/
result = func(ctxt, **new_args)
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
return f(self, context, *args, **kw)
File \"/usr/
return function(self, context, *args, **kwargs)
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
return function(self, context, *args, **kwargs)
File \"/usr/
do_
File \"/usr/
return f(*args, **kwargs)
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
return self._attach_
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
bdm.
File \"/usr/
ret_val = method(obj, context, *args, **kwargs)
File \"/usr/
self.
File \"/usr/
self.
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
virt_
File \"/usr/
with excutils.
File \"/usr/
self.
File \"/usr/
raise self.value
File \"/usr/
guest.
File \"/usr/
self.
File \"/usr/
result = proxy_call(
File \"/usr/
rv = execute(f, *args, **kwargs)
File \"/usr/
six.reraise(c, e, tb)
File \"/usr/
raise value
File \"/usr/
rv = meth(*args, **kwargs)
File \"/usr/
raise libvirtError(
libvirt.