Latest Tweets

RAVADA VDI 0.2.9: Issues and vulnerabilities

Preamble

The RAVADA VDI project is awesome. I already talked about it on a previous post (read it here), and I even wrote a 4-page tutorial for Linux User and Developer #181.  It is still great, of course, but it has some important security issues and flaws I will like to describe here. Most of these problems can be easily addressed by adding some sanity checks to the code. Let’s go then!

Broken Access Control

Every single issue I have found belong to the A4 – Broken Access Control security flaw described in The OWASP TOP-10. Going through the perl code in /usr/sbin/rvd_frontend, some HTTP GET requests can be found that process different aspects of the RAVADA VDI back-end’s functionality, such as enumerating users, virtual machines, and so on. Most of these requests have some sanity checks to ensure the user is either authenticated or is authenticated and has admin privileges; e.g:

any '/new_machine' => sub {
     my $c = shift; 
     return access_denied($c)    if !$USER->is_admin;  
     return new_machine($c);
};

The previous code-snippet would prevent any non-admin user from creating new domains. However, some other requests do not have this checkings set in place. It is easy to get a list of valid HTTP Requests coming from the web interface by running:

cat /usr/sbin/rvd_front |grep -E “^get|^any”

Then, you can go directly to every request and see whether it has some sanity checks or not. If not, then you can try to access to that resource directly from your web browser and see what happens. For example:

get ‘/list_machines.json’ => sub {
get ‘/list_users.json’ => sub {

After loging in as a non-privileged, non-admin user, you can open the following URLS:

http://RAVADA_SERVER/list_machines.json

http://RAVADA_SERVER/list_users.json

The first URL will give you a list of all the created virtual machines, no matter if you have enough privileges to see them or not. The second one will dump the entire user database (including password hashes for local accounts). By the way, passwords are hashed using MYSQL SHA-1 algorithm:

Getting a full list of available VMs in JSON format.

Dumping the whole user database in JSON format.

Playing with someone else’s VMS.

Apart from being able to dump the entire user database, thanks to the list of available VMs you can modify someone else’s domains by just accessing the following url (replace ID with the id:NUMBER obtained from navitating to /list_machines.json):

https://RAVADA_SERVER/machine/settings/ID.html

The VMs list also gives you the 4-char pseudo-random characters used as the spice session password. So, for every listed VM that is up (is_active:1), you can obtain its spice password (spice_password field) in case it is protected by an spice session password and try to connect to it. Besides, you will get the remote IP address that is now connected to the spice session (remote_ip field). A simple Bash-like script can parse the entirety of the list_machines.json file and then iterate trhough every spice password trying to establish a connection to the remote session:

#!/bin/bash
pwds=`./JSON.sh < ../list_machines.json -l -p -n|grep spice_password|grep -v null|awk '{print $2}'|tr -d "\""|xargs`
 
for p in $pwds;
do
/bin/cat <<EOM >sp.vv
[virt-viewer]
type=spice
port=PORT
host=HOST
...
EOM	
	echo "PWD=$p"	
	echo "password=$p">> sp.vv	
	remote-viewer sp.vv
done
exit 0

There are more things to consider, but suffice to say, the developers have already been told and they have fixed all these issues on release 0.2.10. Get it from here.