Research and Development

Security researchers love the new shiny and whilst some like playing games too, I am not one of those. That being said, I have researched UNIX like OS for a number of years and I’m constantly thrilled by the new uses people find for it. This security evaluation was performed against the beta tree of SteamOS, a new, “open” games platform from the developers at Valve.

Whilst we did contact them to ask about getting a physical system to look at, they weren’t forthcoming. Instead, I spent Friday night impatiently clicking refresh, waiting the release of their packages so that I could build a virtual machine and take it for a spin. It should therefore be noted that the system I evaluated is not an official release. Notably, the official image only supports EFI based hardware with an Nvidia graphics card. Since I opted to perform the install under VMware, certain hacks were needed to be performed to get it to function. Notably, I needed to bootstrap the install from an existing Debian system.

To explain how I performed my build, I took a base install of Debian wheezy, updated the sources.list file to point at Valve’s SteamOS repository and performed a dist-upgrade. I then installed all remaining packages available within the USB install image and ran the supplied post_install.sh script. Finally, I sanity checked and removed any packages not in the package list.

Having installed SteamOS, I decided to examine what packages were installed and whether any had known vulnerabilities. In the long run, Valve are going to have to deal with a constantly shifting target as new vulnerabilities are announced. Whilst they may well benefit from the work done by the Debian security team, this isn’t assured given Valve’s decision to rebuild all the packages. Having said this, it appears that Valve have, for now at least, published packages covering all known security updates that have been published by the Debian security team. Whilst we didn’t perform an exhaustive search, it appears that the last relevant security update that had been applied at the point where this evaluation was performed was DSA-2788. Readers should note however that it is unlikely that any non-Debian security team supported patches will have been applied. Packages of note, included:

  • apache-2.2-bin – appears unused at this time
  • bluez
  • iceweasel
  • netcat-traditional
  • openssh-server
  • openssh-client
  • steam-launcher
  • steam-autoupdate
  • steamos-compositor
  • valve-archive-keyring
  • valve-bugreporter
  • Firmware for various proprietary technology including NVidia and ATI graphics cards and Broadcom’s wireless NICs

As mentioned above, the Apache web server does not appear to be functional at this moment in time although it does pull in mod_dnssd which might give a clue as to its ultimate purpose. There are a limited number of services which do listen on all network interfaces, namely sshd, dhclient, avahi-daemon and ntpd. In fact, it’s probably just as well that the number of services is limited for now, since there is no host-based firewall configured.

In order to understand the threat models exposed by Valve’s design decisions, it is necessary to examine the contexts under which code can be executed. In addition to the traditional accounts found on UNIX like systems which are provided for the purposes of executing daemons and other system functions, the following accounts are present:

Username Password Access Privileges
root n/a No direct access
steam steam SSH, Steam desktop groups: desktop, audio, dip, video, polkit, plugdev, netdev, bluetooth; polkit: access NetworkManager based on netdev membership; sudo: run bugreport.sh as steam, run steamos-update as root
desktop SSH (once a password has been set), GNOME desktop sudo: run bugreport.sh as steam, run steamos-update as root, become root (once a password has been set)

As you can see, other than preventing direct access to the UNIX account, SteamOS takes a naive approach. All user access be performed as either the steam or desktop users, neither of which have strong passwords. This contrasts starkly with operating systems such as Android on which each and every user application executes within a different context. Whilst applications could still be executed within with isolated contexts through the use of a non-discretionary access control model such as that provided SELinux, as we will see later, Valve have not as yet enabled this. What this means in practice, is that if a user executes malicious code, either from Steam itself or by way of side loading, then access to the system as a whole is relatively uncontrolled. Given the expected user base, SteamOS may prove an attractive target for attackers in due course. In particular, you should note the steam account has a weak, predictable password set and is therefore available over the network via SSH with minimal effort.

In terms of privileged access, as you can see, there are two scripts which the desktop user can execute. bugreport.sh which can be run via sudo as the steam user and steamos-update which can be run as any user including root. In my experience such scripts are an obvious point of weakness in UNIX like systems, indeed, when testing our clients, it is rare that we do not find scripts such as these which cannot be exploited to escalate ones privileges. They therefore require further analysis.

Firstly, I looked at bugreport.sh. This script takes a screenshot and then calls valve-bugreport. The latter is a Python GUI application which allows users to report their issue to Valve via a web exposed API. The script allows users to send Valve a fair bit of additional information about the bug including the software that has been installed, the contents of /tmp/dumps and ~/.steam/logs. The API is secured using SSL and basic authentication however it appears that the users Steam credentials are cached in ~/.valve-bugreporter.cfg:

g_configFile = os.path.expanduser('~/.valve-bugreporter.cfg')
g_config = ConfigParser.SafeConfigParser({'username':'', 'password':'', 'steamid':''})

Note: It appears a bug has already been opened for this “feature”.

Screenshot filenames are constructed using mktemp which is of course (in principal*) vulnerable to TOCTOU attacks.

Given the hassle Canonical have had with their privacy invading tweaks, I wonder whether similar concerns will be raised around SteamOS, however it is worth bearing in mind that this data is only sent when you file a bug report and it is sent over SSL to Atlassian. SSL Labs gives Atlassian a B for their current configuration.

Secondly, I looked at steamos-update which is used to update SteamOS. This script makes use of the standard Debian update tools to update the main OS. Again, we see a potential* TOCTOU attack in the creation of /tmp/steamos-update.pid, which is of concern because steamos-update can be run as the root user, but as with the screenshots, the attack is thwarted due to the mitigations present in the Linux kernel. The script also calls steam which is Valve’s Steam client application. There are more TOCTOU of use violations with steam itself, but since they’re not exploitable we’ll leave them be except to point out that /tmp/dumps probably doesn’t want to be created “777″.

Speaking of kernel level exploit mitigations, I observed that the following settings are set:

Kernel mitigation Value Implication
kernel.kptr_restrict 0 Kernel symbols can be trivially resolved
kernel.randomize_va_space 2 ASLR applied to all parts of process memory layout
vm.mmap_min_addr 65536 Prevents processes mapping near-to-NULL pages as part of an in-kernel privilege escalation
SELinux not configured no process context isolation
kernel.yama.ptrace_scope 0 Process owners can debug processes
fs.suid_dumpable 0 SetUID processes are not dumpable
fs.protected_symlinks 1 Symlink TOCTOU attacks (such as *) limited as described in commit
fs.protected_hardlinks 1 Hardlink TOCTOU attacks limited as described in commit
kernel.modules_disabled 0 Kernel modules can be loaded
kernel.modprobe /sbin/modprobe Kernel module loading helper enabled
kernel.poweroff_cmd /sbin/poweroff Poweroff helper enabled
net.*.conf.*.accept_redirects 1 ICMP redirects are accepted
net.*.conf.*.secure_redirects 1 ICMP redirects should only come from the default nexthop router
net.ipv4.tcp_syncookies 1 TCP syncookies are enabled

Examining the 72 userland processes running at the time these stats were collected, there is practically no use of any compile time mitigations:

Kernel mitigation In use in Implication
PIE 14 Only programs built as Position Independent Executables (PIE) can take advantage of the exec ASLR which protects against return-to-* during memory corruption attacks
RELRO 13 Only programs built with RELRO can benefit from their relocation table being marked as read-only which protects against GOT-overwrites
Stack Smashing Protection 17 Only programs compiled with Stack Smashing Protection utilise a randomized stack canary that protects against stack overflows

As an aside, the permissions on /usr/local are still as I described in my “Breaking the linker: Exploiting the linker paper”. Whilst SteamOS doesn’t utilise the staff group, which limits this as an avenue for attack, it’s interesting to see that Valve didn’t make any attempt to audit the permissions they inherited from Debian.

This concludes our evaluation of SteamOS’s security posture. SteamOS has not been significantly hardened by Valve. With respect to both kernel and userland hardening, it largely appears unchanged from stock Debian, something I believe is a missed opportunity. Whilst Debian needs to be all things to all people (it runs on 11 different hardware architectures for a start), this is clearly not the case for Valve and it would therefore have been nice to see them improve the security boundaries of the offering. In a future article, I hope to examine the Steam client application and hopefully shed some light on Valve’s Security Development Lifecycle.


Request to be added to the Portcullis Labs newsletter

We will email you whenever a new tool, or post is added to the site.

Your Name (required)

Your Email (required)