10 July, 2018

Dangerous Reality Inside of VR headset: HTC Vive

Introduction

The subject of VR has become a modern trend bringing the neon visions of the masters of cyberpunk stories and novels closer to reality. So, it comes as no surprise that it has been lost only on very few. With years, VR headsets grew far more affordable than they had been at the start when first models were released to the market. No doubt, in future, VR devices will be as naturally found in any house and flat as desktop PCs now. According to IDC, the shipments of VR headset will reach 67 million devices by 2021.

That is why we decided to look inside a VR headset and find out how a cybercriminal can toy with it, and what harm can be done to a device owner.

We researched the following attack scenarios an adversary may use:

  1. Infect a headset and change its location coordinates, which may result in injuries to a user.
  2. Infect a headset and add some spooky visuals, causing psychological traumas and disorders.
  3. Infect a headset and block its screen with an ad banner.
  4. Turn a headset into a link in an infection chain that spreads a virus when connected to other devices.

If you find the topic at least half as amusing as we do, welcome to our short review of the HTC Vive security.

Researching HTC Vive

HTC Vive is one o the most wide spread VR devices on the market. It is also the one that provokes most research interest. Let’s start with analyzing components of the VR system and their functionality. HTC Vive consists of 4 major elements.

Headset

HTC_Vive

Fig 1. HTC Vive headset

The main purposes of the Headset are positional tracking of a user’s head and outputting image to the displays of the VR headset. It is both the most important and curious part of the system. It is equipped with a camera and 32 positional tracking sensors. It is also packed with four connectors:

  • 2xUSB 3.0;
  • power in;
  • Jack 3.5
  • HDMI

Three connectors are occupied right from the start to connect the device to a PC. There is only one USB connector vacant for peripherals devices.

The headset is the only component that is always connected to a PC while the system is working. By getting in the guts of the headset, we got access to its motherboard and, consequently, all the elements we were interested in.

There are main four components on the Side 1 of the motherboard:

  • 3 ARM processors;
    • NXP 11U35F;
    • 2xNordic nRF24LU1P
  • 32 Mb Micron N25Q032A13ESE40E

motherboard_1

Fig 2. Headset motherboard, Side 1

There are several important components of Side 2 as well:

  • 2 ARM processors;
    • STM32F072R8;
    • AIT8328;
  • USB Audio SoC CM108B;
  • USB-hub SMSC USB5537b
  • FPGA Lattice ICE40HX8K-CB132
  • 4 Mb Micron MP25P40
  • 32 Mb Micron N25Q032A13ESE40E

motherboard_2

Fig 3. Headset motherboard, Side 2

Base stations

Base_station

Fig 4. HTC Vive base stations

The primary purpose of the base stations is to track a user’s position. With a cycle of 60 times per second, they pass a synchronization impulse and then project a laser beam from top to bottom and from left to right of a room. The data is collected by the sensors and processed by the microcontrollers in the headset and controllers to track a user’s position.

The base stations are equipped with a power in and Jack 3.5 for synchronization. Each station also has a Bluetooth module used for sending notifications about the device being turned into/from the Sleep mode.

Inside the device, there is the NXP 11U37F (ARM Cortex-M0) chip, responsible for the main functionality of the device.

base_station_1

Fig. 5. Base station motherboard, Side 1

Broadcom BCM20736 (ARM Cortex-M0) ensures Bluetooth operation. There is also the RS-485/RS-422 transceiver that synchronizes both stations via Jack 3.5.

base_station_1

Fig. 6. Base station motherboard, Side 2

The interaction between the base station and a PC is close to zero (it is limited only to updating procedures). The headset, in its turn, is communicated with the help of laser beams on the hardware level. If there are any changes made in the way the beams work, the system will become simply inoperable.

Controllers

Controllers

Fig. 7. HTC Vive controllers

It is quite obvious that a controller is intended for tracking a user’s hand movements and ensuring you get full VR experience. As for connectors, they are equipped only with microUSB for charging and updating. But what is inside it? Well, there is the NXP 11U37F processor based on Cortex-M0 in there. It maintains primary functionality of a controller. There is also FPGA ICE40HX8K-CB132 there dealing with the sensors responding to laser beams projected by base stations; and a 4 Mb Micron M25P40 chip. At first glance, it is hard to spot the Bluetooth chip, because it is a wall-flower Nordic nRF24LU1P hiding under a metal screen.

controller

Fig. 8. HTC Vive controller motherboard

Link box

link_box

Fig. 9. Link box of HTC Vive

Link box is a hub between a desktop and the headset. It has four connectors on one of its sides:

  • power in;
  • USB 3.0 for connecting to a desktop;
  • display port;
  • HDMI.

On the other side, there are three headset connectors:

  • power out;
  • HDMI;
  • USB3.0.

One can easily find the its Bluetooth chip required for swift and convenient updating of some devices.

Watchman update and console

Having browsed through the SteamVR software folder, we managed to find two helpful programs: lighthouse_console.exe and lighthouse_watchman_update.exe. The first is a console for working with HTC Vive devices; the latter enables updating the headset devices.

By executing the help command in lighthouse_console, we could see the following commands listed:

lh> help
associatecontroller     Associated the attached controller to the attached puck
axis    Toggle VRC axis data dumping
battery Print battery status
button  Toggle button data dumping
clear   Clear the record buffer and accumulated statistics.
dump    Toggle all dumping to the console. You must also turn on the individual { imu, sync, sample } flags.
errors  Dump the lighthouse error/status structure.
event   Toggle lighthouse aux event dumping
eventmask       Select lighthouse aux events to report
isp     Enable In-System Programming
haptic [us]     Trigger haptic pulse
identifycontroller      Trigger haptic pulses on the active serial number to identify it
imu     Toggle IMU data packet dumping
imustats        Print IMU statistics
period  Print sync statistics
dis [<type=auto>]       Toggle disambiguation. types={ auto, tdm, framer, synconbeam }
syncd   Toggle sw sync detect
pose    Toggle static pose solver. Is 'dis' is not active, it will enable it.
poweroff        Turn off the active controller
record  Toggle event recording. You must also turn on the individual { imu, sync, sample } flags.
serial  Select a device to open by serial number substring
sensorcheck     Print out hits (and widths) per sensor
save [<filename="lighthouse_console_save.txt">] Save recorded events to a file on disk
sync    Toggle sync dumping
sample  Toggle sample dumping
trackpadcalibrate       Trigger trackpad recalibration on the active controller
uploadconfig [<filename>]       Upload the config file to the device
downloadconfig [<filename>]     Download the config file
reformatconfig <inputfilename> <outputfilename> Update the config to the latest json format
version Prints the firmware and hardware version on the Watchman board
userdata        Get a directory listing of the stored userdata
userdatadownload <name> Download the specified named userdata
userdatadownloadraw <addr> <size> [<filename>]  Download and store the user data at specified address
userdatasize    Display the size of the user data space (in bytes)
ispdiv <divisor>        Set the camera ISP sync signal divisor
quit    Quit

However, if the program is opened in IDA Pro, it becomes clear that there is much more of them.

if ((unsigned __int8)sub_402210(v11, "pair")){
    v173[1] = 0;
    if (*(_DWORD *)(v217 + 16) == 8449)
      sub_42EC30(10000, (char)v173[1]);
    else
      sub_42ED10((char)v173[1]);
    goto LABEL_497;
  }
  if ((unsigned __int8)sub_402210(v11, "pairall")){
    sub_40C4C0(15000, 0);
    goto LABEL_497;
  }
  if ((unsigned __int8)sub_402210(v11, "forcepairall")){
    sub_40C4C0(15000, 1);
    goto LABEL_497;
  }
  if ((unsigned __int8)sub_402210(v11, "unpair")){
    sub_42BA80(v217);
    goto LABEL_497;
  }
  if ((unsigned __int8)sub_402210(v11, "unpairall")){
    sub_40FEF0();
    goto LABEL_497;
  }
  if ((unsigned __int8)sub_402210(v11, "hmdhidtest") )

Here is the commands that are not listed by the help command. However, they are still in the program:

  • fpgareset
  • fixcalib
  • pair
  • pairall
  • forcepairall
  • unpair
  • unpairall
  • hmdhidtest
  • fpgaread
  • dongleinfo
  • donglereset
  • dongleresetall
  • eventrate
  • wait
  • capsensecalibrate
  • trackpaddebug
  • poweroff

With the help of this list, we could test the device in various ways. For example, check the button status. It was also possible to download the configuration file, upload it back, and perform other peculiar operations.

Thanks to the lighthouse_watchman_update.exe application, an attacker can easily update firmware of any of the devices. As you understand, it is the basis of each attack scenario mentioned above. Moreover, firmware of most microcontrollers is accessible through the neighboring directory, although it is not quite clear what each of them does.

Usage: lighthouse_watchman_update [OPTIONS] [args...]
Options:
  -h                       Prints this message
  -m<dev>                  Update main firmware (default)
  -f<dev>                  Update FPGA firmware
  -r<dev>                  Update radio firmware
  -j<dev> k1,f1 k2,f2 ...  Update user data {key,filename}. Multiple files supported. Erases prior user data.
  -u <dir>                 Update all devices with firmware in the specified directory
  -U <dir>                 Same as '-u' option but forces update
  -x                       Do not reset device after successful update
  -b<dev>                  Reset device into bootloader mode
  -i<dev>                  Reset bootloader device into ISP mode
  -R<dev>                  Reset into main firmware from the bootloader
  -B <num>                 Set board revision
  -l<dev> <num>            Set date/lot code
  -a<dev>                  Print bootloader attributes
  -c                       Print CRC128
  -d                       Update watchman dongle
  -D                       Update watchman dongles and/or convert Steam Controller dongles to watchman
  -g<dev>                  Update fuel gauge firmware
  -t <path>                Reads timestamp information from a watchman firmware image
  -s <serial num>          Update the device with matching serial number
  --via-dongle             Perform watchman firmware updates via a dongle radio connection
  --via-bootloader         (Watchman v3 devices only) Sends the update via the device's bootloader
  --via-application        (Watchman v3 devices only) Sends the update via the device's application interface
  --force-update           (Watchman v3 devices only) Forces an update onto a device
  --target=<target>        (Watchman v3 devices only) Sets the update target.  Available targets:
                               application, bootloader, ice40, max10, nrf52, bq27520, user, default (set by file)

 <dev> device     'w' for watchman 'w3' for watchman v3 'v' for VRC 'n' for NEO_VRC
                   (default is watchman)

Hardware analysis

The headset motherboard is the most interesting part here. A lot of crucial hardware elements are placed right on it. It also has a lot of debugging connectors. Fortunately, most microcontrollers are not put in the BGA case, that is why we have managed to find the SWD connectors of some chips. Fig. 10 shows the one of NXP LPC11U35F.

SWD

Fig. 10. SWD connector of NXP LPC11U35F

To understand the functions performed by each microcontroller and rebuild connections between the components we used a solderer and a multi-meter.

multimeter

Fig 11. Multi-meter and soldering station

We disassembled the motherboard, rang out the paths with our multi-meter, and made the scheme of connection between the components (see Fig. 12).

work_scheme

Fig. 12. Scheme of connection between the HTC Vive components

As we remember, the headset has USB-Hub SMSC USB5537B that connects up to 7 devices via 1 USB. 6 of the available ports are occupied by the main components of the headset, while the remaining external one is vacant for connecting additional equipment. The scheme illustrates that it is impossible to get into the video output processing from the headset side since it is a PC that is responsible for the procedures. The FPGA monitors the status of 32 headset sensors, processes all the data sent by them, and passes it via the UART to the NXP LPC11U35F/401 microcontroller.

What conclusions can be drawn here?

The first thing that came to our heads here is that the video stream cannot be affected in any way since it is processed by a PC, which sends the rendered image to the headset. Consequently, Attack Scenarios 2 and 3 are inapplicable.

Second, we found out that the chip (NXP LPC11U35F/401) is responsible for tracking the position of the headset and sends them via USB to a PC. Therefore, a cybercriminal can modify the system that process position data so that a user’s virtual position is different from the real one. This case corresponds to Attack Scenario 1.

Then, we had to find out what firmware was stored on the microcontroller. All microcontrollers and memory had been unsoldered. So, we needed to read data from them. With the help of our soldering station we soldered microcontrollers to the TQFP adapter (see Fig. 13):

arm_TQFP

Fig. 13. Chips connected to the TQFP adapter

Unfortunately, we could not find adapters for the SPI memory chips since it had fewer pins. So, we just soldered a pin header to them.

SPI_flash

Fig. 14. SPI memory with soldered pin connector for connecting to programmator

ChipProg481 and a bunch of wires came in handy for extracting firmware!

somewire

Fig. 15. ChipProg481 and STM32F072 connected to it.

We extracted data from a controller for a change. However, all the components there were all right, so we did not have to unsolder them. The procedure of extracting data from two microcontrollers was absolutely seamless, thanks to BlackMagick Probe v2 connected to SWDs.

BMP_SWD

Fig. 16. Black Magick Probe v2.1 connected to SWD on the board of a controller

According to the collected data, we built a table to make it clear what firmware was used and what functionality was performed on each microcontroller.

Dump source Firmware extracted from SteamVR software Additional information
Micron N25Q032A13ESE40E 32 Mb Micron N25Q032A13ESE40E 32 Mb Addresses from 0xF8000 to 0xF9C1DF were not found in the SteamVR firmware.
STM32F072 DisplayBin tools/lighthouse/firmware/htc/APP_0000000000200160.bin Addresses from 0x0 to 0x26c8 were not found in the SteamVR firmware.
Micron M25P40 4 Mb DisplayBin tools/lighthouse/firmware/htc/APP_0000000000200160.bin
nRF24LU1P DongleBin tools/lighthouse/firmware/vr_controller/archive/htc_vrc_dongle_1461100729_2016_04_19.bin
NXP 11U35F WatchmanBin tools/lighthouse/firmware/lighthouse_rx_watchman/archive/htc_watchman_1462663157_2016_05_07.bin Configuration archive.
Micron N25Q032A13ESE40E 32 Mb WatchmanFPGABin tools/lighthouse/firmware/lighthouse_rx_watchman/archive/htc_pre_watchman_262_fpga.bin PNG_1 Green_4A7A16BB004239_mura_analyzes.mc PNG_2 Green_4A8A16B8004487_mura_analyzes.mc.

Table 1. Comparison between extracted firmware and the one that was stored in the SteamVR software folder

Security aspect

The security problems of HTC Vive came to the spotlight quite early – at the updating stage. According to the microcontroller documentation, all microcontrollers support updating via USB. Judging by firmware files, it was clear for us that firmware is a binary file with no checksums. Therefore, adversaries can modify firmwares to their liking and upload them to the headset. Also, each microcontroller has sufficient space (45 Kb on average) for the modified code to be put in there. Change, upload, enjoy!

For example, in the NXP LPC11U35 documentation the following is stated:

- In-System Programming (ISP) and In-Application Programming (IAP) via on-chip bootloader software.
- ROM-based USB drivers. Flash updates via USB supported.
- ROM-based 32-bit integer division routines

and in the STM32F072 documentation:

The boot loader is located in System Memory. It is used to reprogram the Flash memory by
using USART on pins PA14/PA15, or PA9/PA10 or I2C on pins PB6/PB7 or through the USB
DFU interface.

nRF24LU1P says:

The nRF24LU1+ bootloader allows you to program the nRF24LU1+ through the USB interface. The bootloader
is pre-programmed into the nRF24LU1+ flash memory and automatically starts when power is
applied.

As it was written above, there is a special lighthouse_watchman_update.exe console tool available. A mere malicious code can use it to conduct an attack or implement the functionality of the tool in itself.

As seen from HTC_Vive_Tracker_Developer_Guidelines_v1.3, the commands below are used for updating the device:

- Update MCU’s firmware:
  - lighthouse_watchman_update -mnt tracker_mcu_filename.bin
- Update FPGA’s firmware:
  - lighthouse_watchman_update -fnt tracker_fpga_filename.bin
- Update RF’s firmware:
  - lighthouse_watchman_update -rnt tracker_rf_filename.bin

If it is possible to update the software of HTC Vive, an attacker can add malicious code that can affect the operation of the system and potentially lead to physical injuries of a device owner or cause other inconveniences.

HTC Vive Pro

Not so long ago, a renewed version of the device was released to the market. Unfortunately, we had no chance to check the Pro version yet. Nonetheless, the available information regarding HTC Vive Pro signifies that there were no fundamental changes made in relation to the basic version. Although some microcontrollers were indeed updated, the overall principles of operation of the device and interaction between its components remained the same. They just slightly changed the arrangement of motherboard (now, there are two of them), and the way debugging connectors are placed.

A really new feature is yet to come: the developers announced they are going to release an accessory that will free the device from wires and enable passing data via a wireless channel with the help of the WiGig technology. Apart from useful features, however, this novelty brings another attack vector.

Conclusion

All in all, we drew the list of following conclusions regarding the attack scenarios mentioned above:

  • Attack Scenario 1: An adversary can change the location and coordinates of the headset. Users may become one with their apartment wall before they can say “Jack Robinson” and before the software warns them about this dangerous proximity.

  • Attack Scenarios 2 and 3: It is not possible to use the scenarios because the headset does not process video stream.

  • Attack Scenario 4: Although, the scenario is accomplishable; it is still quite comparable to nail-biting since HTC Vive is a stationary device and rarely connected to other desktops but the one of its owner. An owner’s desktop computer will be already infected.

HTC vive is a high-tech device, but still it is obvious that its security was not a matter of priority for the developer.

An attacker can easily get access to firmware of each microcontroller used in HTC Vive, modify and upload them back to the headset. As a result, it is not only gaming experience that will be spoiled, but also an owner injured.

With years, VR and AR technologies will grow more advanced and developed, and so will the security problems of the technology. Unfortunately, the security issues of the technology will progress as well, getting more severe and dangerous.