Diebold AccuVote-TSx Election Machine Hacking
Annually at the DEFCON summer camp, groups of hackers gather to hack in the Voting Village[0] against a test bed of electronic voting machines. You may have seen a popular video where a Defcon attendee highlighted how a generic supervisor card and default PIN could be used after picking a lock to modify election settings [1]. A security paper has also been written by three researchers and presented at the USENIX conference that shows how a supply chain attack might be performed, documenting a number of vulnerabilities [2]. Hacker House were supplied with a Diebold Accuvote-TSx system, surplus from these public hacking demonstrations and decided it would be a fun hacking project to expand on the existing research efforts to enhance our voting experience. This is a post about democracy, hardware hacking and how we successfully reprogrammed an electronic voting machine to play space invaders amongst other things. We will document the necessary steps for you to follow along and modify a voting machine at home! We rediscovered several known issues along the way, such as the existence of a JTAG header, and also observed more security relevant issues in relation to the flash memory used by Diebold.
What follows is a technical tear-down of the Diebold AccuVote-TSx with the goal of obtaining code execution over the voting system to highlight risk. During 2016 at least 15 states were found to be using AccuVote-TSx or similar Diebold systems for local state and county elections. The Diebold machines have widely been used as stock art for vulnerable elections since 2016 with the system making a frequent occurrence in news articles discussing the failed state of electronic voting security systems. Fundamental insecure engineering practices combined with a mediocre security implementation on the OS means that unless serious consideration is given to re-engineering and hardening both hardware and software then these machines are not fit-for-purpose and cannot be relied upon to store or hold information in a secure means.
Device Internals
By opening and investigating the various components on the PCB of the Diebold AccuVote-TSx we were able to learn several key things – the existence of a JTAG interface – along with the type of CPU (PXA255). The interface JP-16 is clearly labelled on the PCB as a “CPU JTAG Interface” and can be seen at the top right of the PCB photographs on our repository[3]. There is an additional JTAG interface for a CPLD (FPGA) device towards the middle of the board. As well as these features the system also boasts a PIC16F MCU to the middle left of the board[3] which can be associated with a keypad entry device available separately. There exists a number of supporting chips such as the SM501 for multimedia/graphics, numerous frequency xtal’s, DRAM & SDRAM components as well as a Flash chip and components for the battery charging and power management. The JTAG interface has been identified as a standard 20-PIN ARM JTAG interface, a JTAGulator[4] was used to confirm that the pin layout was standard. Review of the components identified that the CPU is an Intel PXA255 processor, this allowed for us to connect a TinCanTools Flyswatter 2[5] which supports Intel X-Scale processors and is also usable with open-source programming tool OpenOCD[6]. If you are not familiar with this particular JTAG programmer, it comes highly recommended, as it offers a FT2232 based interface for working with a number of common SBC devices (Raspberry Pi, Beaglebone etc.) and supports many popular ARM devices. By booting the device and doing some cursory memory analysis we were able to learn that the unit runs a custom version of Windows CE .NET 4.1. Information of this nature can be learned by browsing the device menus and reading through memory dumps (more on this in a moment). The following software versions were learned.
Windows CE Kernel for ARM (Thumb Enabled) Built on May 24 2002 at 21:34:01
OS Rev: 4.10 (Build 908)
BallotStation Version: 4.7.8
I hooked up our JTAG programmer and set the “openocd.cfg” file to make use of a PXA255. You can find a working configuration for OpenOCD in our code repository[7] with comments.
CPU Manipulation
Once we had connected our programmer to the device, we were able to establish a JTAG debugging interface to perform on-chip debugging. The following output can be seen using our configuration file[7] when launching openocd.
Info : pxa255.cpu: hardware has 2 breakpoints and 2 watchpoints
adapter speed: 300 kHz
trst_and_srst separate srst_nogate trst_push_pull srst_open_drain connect_deassert_srst
Info : clock speed 300 kHz
Info : JTAG tap: pxa255.cpu tap/device found: 0x69264013 (mfg: 0x009 (Intel), part: 0x9264, ver: 0x6)
We can see from the above that the manufacturer code and device details matched our expected PXA255 configuration. OpenOCD provides a “gdb” interface on TCP port 3333 and a console CLI session on TCP port 4444. First we connected to the CLI to “halt reset” the system.
> reset halt
adapter speed: 300 kHz
JTAG tap: pxa255.cpu tap/device found: 0x69264013 (mfg: 0x009 (Intel), part: 0x9264, ver: 0x6)
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x600000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
(processor reset)
This places the device at the start of it’s boot sequence, allowing us to debug the bootloader and manipulate the OS from a privileged position. The openocd output indicates that we are executing in Supervisor mode. We now connect to the device using “gdb”. We specify that the device is using the Intel XScale architecture and then use the gdb remote debugging port provided through OpenOCD.
(gdb) set arch xscale
The target architecture is assumed to be xscale
(gdb) target remote localhost:3333
Remote debugging using localhost:3333
0x00000000 in ?? ()
(gdb)
We are now able to manipulate the running code on the device. This required some understanding of how the PXA255 memory maps connected chips. The flash chip is wired to PXA255 “chip select 0” which has a memory region of 0x00000000 to 0x04000000. This is a flash memory region and cannot be written to using traditional “gdb” commands, trying to hot patch the boot loader will fail. DRAM and SDRAM are mapped above this range and it is possible to read and write to the running OS from gdb by accessing the pages at 0x08000000 and up. However, a trick was inserted to prevent debugging of the OS by Diebold, causing an exception. To access the host OS we will first need to handle this exception gracefully and let the OS boot, once Ethernet Boot (eBoot – the Windows CE boot loader) has output the “Launching OS” message, the system will appear to hang as this exception is raised. Interrupt the execution and walk through the exception to boot to the OS simply using “stepi”.
Program received signal SIGINT, Interrupt.
0xffff0018 in ?? ()
(gdb) x/i $pc
=> 0xffff0018: ldr pc, [pc, #984] ; 0xffff03f8
(gdb) stepi
0x841047a8 in ?? ()
(gdb) x/i $pc
=> 0x841047a8: sub lr, lr, #4
(gdb) cont
Continuing.
This allows for full read and write of memory inside the host OS and can be used to manipulate the election software to now do anything you like. Our goal was to run our own code and binaries. Windows CE .NET 4.1 images can be built manually using an antiquated tool released by Microsoft called Platform Builder 4.1. Using this and legacy versions of Visual Studio it is possible to define an ARMv4 thumb mode BSP (board support package) and compile stand-alone executables and programs that will run on Windows CE .NET 4.1. This came in handy when we began to explore the OS and learned that many core components had been removed.
BallotStation & Windows CE
Once we had achieved the ability to debug the AccuVote-TSx, the first thing we did was dump the flash memory chip region 0x00000000 – 0x04000000. This contained the boot loader, OS image as well as a filesystem used for storing encrypted election data. By downloading and saving a backup of this memory region, you will be able to restore the machine at a later date – it is important that you take such a backup as rebuilding the OS from scratch is not for the faint of heart. The OS contains a minimal bare-bones environment with many core executable functions disabled, further hardening of Windows CE has been done in the registry preventing access to the taskbar and familiar interfaces. However there does exist a number of common DLL’s that enable networking functionality and support for hardware devices. Once we had obtained the flash image we were able to extract both the boot loader and the Windows CE image, which stores DLL’s and EXE’s in a Table of Contents[8] that are then mapped to RAM. Using binwalk and some Windows CE specific utilities [9] it is possible to extract and manipulate a Windows CE nk.bin file and explore the OS build contents. The following executable binaries are available to an attacker for use in subsequent attacks.
6/24/2009 23:46:13 275456 nk.exe - OS kernel
6/24/2009 23:46:45 198656 filesys.exe - File system support
6/24/2009 23:46:45 704512 gwes.exe - graphical environment
6/24/2009 23:42:38 26624 device.exe - internal windows stuff
6/24/2009 23:46:45 108544 connmc.exe - connection manager, opens networking dialog
6/24/2009 23:46:45 33280 rnaapp.exe - remote network access, for dialup networking
6/24/2009 23:46:07 10752 taskman.exe - not an actual task manager, just taskman for CE
6/24/2009 23:46:07 6144 dst.exe - diebold ??
6/24/2009 23:46:09 563200 avinstaller.exe - assure security umbrella
6/24/2009 23:46:08 3584 elova.exe - ??
You can find extracted copies of the boot loader and ROM in our code repository[9]. With this memory layout it is possible to begin exploring the device using GDB and manipulating the software for instance to change voting behaviour or other neat hacks. However we wanted to load our own binaries into the OS and overwriting EXE’s in RAM whilst viable, is certainly painstakingly difficult to do reliably.
Third-Party Hardware
It is possible to use a range of 3rd party hardware in lieu of the rather expensive Diebold supported components. We discovered that a number of DLL’s in the OS[8] were for common LAN networking equipment, particularly those using a NE2000 chipset. There exists also support for some common 3rd party hardware which is available by default in Windows CE 4.1 based OS builds, as we witnessed by attempting to build our own ROM using Platform Builder. By obtaining a Compact Flash card and PCMCIA adapter[10], we were able to add 64MB to 1GB of storage for $20 (the Diebold storage cards are expensive at $350 or more) and also we added a 100m/bit Ethernet adapter using the NE2000 chipset. Plugging in the Ethernet adapter showed the device made DHCP requests indicating the adapter was working. We port scanned the unit and found nothing of Interest[11] however we suspect that the Windows CE 4.1 DHCP client likely suffers from many known DHCP weaknesses that have been patched in more recent versions of Windows CE (now known as Windows Mobile). Additionally once we booted the OS with a working storage card, the option to “Download Election” was no longer greyed out and we could see that the unit had identified the storage as it’s main storage. If you are a government on a budget, you can save money using 3rd party hardware instead of Diebold certified equipment which uses the same chip sets.
Flash Memory Weaknesses
The flash memory chip in use was identified as a “Numonyx® Axcell™ P30-65nm” 64-Mbit device, originally made by Intel until it was acquired by Numonyx. This process was painstakingly difficult for a number of reasons, the least of those being that we could not locate the flash chip on the PCB easily. We discovered that the flash memory chip in use did not set one-time-programmable (OTP) fuses, the chip still had the ability to be User Programmable despite offering security features that would have protected this ROM memory against manipulation. There had been no security codes set and nothing stood in our way of reading and writing to the flash chip once we did some calculations to ascertain the chip depth (16bits), bus width (32bits) and bus clock rate (200MHz) from the PXA255 CPU. It is important when programming flash memory over JTAG to learn the correct memory geometry and clock rate for communicating with the flash chip, we discovered that by programming at the wrong clock speed the programmer would often introduce NULL bytes or cause corruption of the flash image resulting in a bricked unit until reprogrammed correctly. Our OpenOCD configuration file contains comments for adjusting the file from working with the CPU in gdb to using the “flash” commands in OpenOCD, the main change is the JTAG clock speed must be adjusted to communicate with the flash chip bus. Once we had correctly setup the flash memory bank in OpenOCD we were able to interrogate the flash using “flash info 0”.
Flash Manufacturer/Device: 0x0089 0x891c
expected one protection register field, but found 2
#0 : cfi at 0x00000000, size 0x04000000, buswidth 4, chipwidth 2
# 0: 0x00000000 (0x10000 64kB) protected
...snip snip...
#258: 0x03fc0000 (0x40000 256kB) protected
CFI flash: mfr: 0x0089, id:0x891c
qry: 'QRY', pri_id: 0x0001, pri_addr: 0x010a, alt_id: 0x0000, alt_addr: 0x0000
Vcc min: 1.7, Vcc max: 2.0, Vpp min: 8.5, Vpp max: 9.5
typ. word write timeout: 256 us, typ. buf write timeout: 512 us, typ. block erase timeout: 1024 ms, typ. chip erase timeout: 1 ms
max. word write timeout: 512 us, max. buf write timeout: 1024 us, max. block erase timeout: 4096 ms, max. chip erase timeout: 1 ms
size: 0x2000000, interface desc: 1, max buffer write size: 0x40
intel primary algorithm extend information:
pri: 'PRI', version: 1.4
feature_support: 0x1e6, suspend_cmd_support: 0x1, blk_status_reg_mask: 0x3
Vcc opt: 1.8, Vpp opt: 9.0
protection_fields: 2, prot_reg_addr: 0x80, factory pre-programmed: 8, user programmable: 8
Immediately we noticed that the flash chip has a user programmable state and does not make use of effective protections to deter manipulation of the code installed on the device. This opens the unit upto bootkit attacks which we demonstrated on the bootloader by changing commonly seen strings and reflashing the modified binary image onto the device. Before flashing such a device you must first disable the write protection (enabled at boot) using “flash protect 0 0 last off” in OpenOCD. Once you have disabled the protection, the flash chip must be erased using “flash erase_sector” or similar commands. A properly erased flash chip will have it’s data set to all 1’s and show 0xffffffff when read through gdb. We noticed that if we enabled “–debug” with OpenOCD this operation tended to be more successful and often required multiple attempts to successfully erase and subsequently use “flash write_image” to upload a new or modified ROM onto the device. We are now able to permanently bootkit the Diebold AccuVote-TSx system without leaving additional evidence such as a visible smart card. This improves on existing supply chain attack methods by allowing the introduction of malware without the need for additional hardware, an attacker just needs to be able to have physical access to the machine for re-flashing over JTAG. We were able to make modifications to the eBoot boot loader without any complications, allowing to disable and subvert any additional security checks on the device.
Injecting Binaries
With the ability to re-flash the device, added networking capabilities, removable storage and debugging of the device in supervisor mode it was now time to complete our hack by executing our own binaries in-place of the BallotStation 4.7 software. An attacker could use these same methods to run malware or further extend the work for nefarious purposes. By adding a Compact Flash card with the “invaders.exe” binary[8] in a FAT32 formatted partition, we were able to execute this binary by overwriting the startup binary path in memory through our gdb interface. By Reverse Engineering the ROM and doing debugging we found that the executable path is stored as a unicode string at memory address 0x845bb440. By overwriting this with our own “\Storage Card\invaders.exe” string, it was possible to execute a Windows CE Space Invaders game in place of the BallotStation software. Thanks to a lack of ASLR and shared binary components, we found that this address was consistent across our units. The payload to achieve this in gdb can be found here and in our repo. Simply interrupt the execution of the OS after the boot loader has launched and the chime has played.
(gdb) set {char}0x845bb442 = 'S'
(gdb) set {char}0x845bb444 = 't'
(gdb) set {char}0x845bb446 = 'o'
(gdb) set {char}0x845bb448 = 'r'
(gdb) set {char}0x845bb44a = 'a'
(gdb) set {char}0x845bb44c = 'g'
(gdb) set {char}0x845bb44e = 'e'
(gdb) set {char}0x845bb450 = ' '
(gdb) set {char}0x845bb452 = 'C'
(gdb) set {char}0x845bb454 = 'a'
(gdb) set {char}0x845bb456 = 'r'
(gdb) set {char}0x845bb458 = 'd'
(gdb) set {char}0x845bb45a = '\\'
(gdb) set {char}0x845bb45c = 'i'
(gdb) set {char}0x845bb45e = 'n'
(gdb) set {char}0x845bb460 = 'v'
(gdb) set {char}0x845bb462 = 'a'
(gdb) set {char}0x845bb464 = 'd'
(gdb) set {char}0x845bb466 = 'e'
(gdb) set {char}0x845bb468 = 'r'
(gdb) set {char}0x845bb46a = 's'
(gdb) set {char}0x845bb46c = '.'
(gdb) set {char}0x845bb46e = 'e'
(gdb) set {char}0x845bb470 = 'x'
(gdb) set {char}0x845bb472 = 'e'
(gdb) set {char}0x845bb474 = '\x00'
Once this memory is overwritten with our own path to an executable, we could also run many of the built-in EXE’s of the diebold system (or indeed load in other Windows CE based applications such as file exploring utilities). The built-in executable’s do not provide much in the way of interest and it was not possible to use the base OS to access a file explorer without use of clever ROP, custom application building or registry modifications, it is much easier to load an executable from a Compact Flash card than it is to try and insert your own into RAM (although this is entirely possible). The device could also be used now to port Linux as the main-line kernel has support for the SM501 chip which has been a hindrance when building our own Windows CE based ROM’s. The SM501 device was not supported by default in Windows CE .NET 4.1 so device drivers for eBoot are not as readily available. A screen shot below shows what happens when a failed execution occurs (i.e. the binary does not exist at the path specified).
FFX Election Data Encryption Keys
Whilst conducting this research we discovered the device contained a number of password protected RSA private keys and certificate files that are used for encrypted file system purposes. These keys have been extracted and are available in our repository. The machines have been found to hold previous election data protected by the use of these keys. We are continuing our research into how information is stored securely in the device (spoiler, it’s 2003 secure).
Conclusion
The Diebold Accuvote-TSx provides security through obsoletion, it makes use of what was cutting edge technology in 2003 – Windows CE .NET – and has a number of serious hardware security issues that would be unexpected in a device being produced for production purposes of this nature. The ability to JTAG the system in Supervisor mode gives an attacker full reign over the device with moderate ease – allowing the boot loader to be manipulated and any protections in the OS bypassable. An attacker could infect the machine with a bootkit that would be unnoticed as does not require the changing of dip switches or additional hardware adding to the unit for deployment, thus offering a viable and stealthy means to perform a supply chain infection attack. The OS used offers very limited security protections against modern exploitation techniques and what little OS security does exist can be easily bypassed with such privileged debugging interfaces. The flash memory chips used for storing the ROM offer security protections and OTP fuses which were neglected to be enabled, allowing an adversary to manipulate and flash custom code. The device is essentially an over-sized Windows CE .NET 4.1 tablet making use of engineering and design practices common in 2003 but which are wholly insufficient for security purposes today. In short, the TL;DR, the device is not fit-for-purpose when used as an electronic voting system, however we feel it makes an excellent table top arcade system for playing classic video games.
References
[0] Voting Village Defcon.
[1] Rachel Tobac Twitter post
[2] Security Analysis of the Diebold AccuVote-TS Voting Machine
[3] PCB photograph
[4] JTAGulator homepage
[5] TinCanTools FlySwatter 2 JTAG programmer
[6] OpenOCD homepage
[7] OpenOCD configuration for Diebold AccuVote-TSx
[8] Windows CE .NET 4.1 binaries and executables in Diebold AccuVote-TSx
[9] Hacker House repository for openocd, ROM & tools
[10] Windows CE Hardware Compatibility List
[11] Nmap port scan results