Reprogramming the Defcon 24 badge

badge3
This fucking badge.

The Defcon 24 badge is built around a Intel Quark D2000 microcontroller processor, and contains 5 LEDs and 8 buttons. By default, it is programmed to occasionally blink in a few different patterns, and spit out some encoded phrases via serial. These functions are critical to the Defcon Badge Challenge, which is a complex series of puzzles and challenges that can be solved by gathering clues from around the Defcon venue and also by being really smart (or at least clever). A writeup of this year’s challenge by the winners can be found here.

I’m not much of a puzzle solver, so my goal with the badge was to explore the functionality and see if I could reprogram it to do other things. I spent most of the weekend at Defcon struggling (and failing) to overwrite the badge’s firmware. It wasn’t until a few weeks after I got home from Vegas that I was finally able to reprogram it; this post will summarize that process (or, just skip to the step-by-step).

Connecting to the badge via serial

badge_ftdiIf all you want to do is see the encoded messages that the badge spits out, then you’re in luck. That’s the easy one. Take any USB FTDI adapter (such as the Sparkfun 3.3v FTDI Basic Breakout) and connect the TX to pin 4 and RX to pin 5, as shown in the image below (you will need to bridge the two pads below pin 5 with solder).  I soldered pin headers into the holes, but that’s really just for convenience sake. For bonus points, you can even power the badge via the Ground and 3.3v pins. IMPORTANT: be positive (heh) that you are using 3.3v! 5 volts will fry your D2000.

badge_serialOnce connected, fire up your favorite serial program and connect to the board at 115200 baud. On a mac or linux, you can just use screen:

screen /dev/<device ID> 115200

Alternatively, you could use the serial monitor in the Arduino IDE to connect to the badge as well.

The badge outputs the codes intermittently, so you might not see anything right away. If you want to force some output, try using the buttons to enter the Konami code (Left buttons: up, up, down, down; then right buttons: left, right, left, right) and you should see a message pop up saying “Konami Code unlocked!”.

Connecting to the badge via JTAG

If you want to reprogram the badge, you’re gonna need to use JTAG. There are two issues here, however: 1) connecting to the JTAG headers, and 2) finding the right JTAG adapter.

1) Connecting to the JTAG headers:

badge_sheetOn the badge, the JTAG headers are located on the chin, below the battery holder. “But wait a second,” you might be thinking, “the chin of my badge looks like it was torn off.” And you are not far off. The badges came from the fabricator in sheets of 4 badges per sheet with the chin holes/headers being used as a break point, as shown to the right (image used without permission from here).

The sheets have JTAG headers broken out along the edge; if you look on the right side you can see 4 sets of 8 pins. These are connected to the badges and were used to load the firmware; once the firmware was loaded, the badges were snapped out of the sheets. According to a goon friend, only about 5,000 badges came from the fabricator with the firmware loaded; 15,000 badges needed to be flashed and removed from the sheets, which was a process that went on all night Wednesday and into the day on Thursday. Understandably, that means that little attention was paid to ensuring the chin JTAG headers were snapped cleanly enough to still be useable. But hey, what’s a Defcon badge without some challenge?

badge_jtagSome people were unfortunate enough to not have any copper to work with on their badge’s JTAG header. My badge had some copper at each of the 8 holes; enough to be able to carefully solder on some wires. This was a very tedious and delicate process. First, I tinned whatever copper existed for each pin/trace, making sure to not accidentally bridge any of them together. Next, I took 8 pieces of solid core wire, stripped and tinned the ends, held the wires one at a time next to the bits of exposed copper, and applied heat with the soldering iron. Naturally, i bridge a few of them, so I had to do some rework to reattach all of the wires.  Once soldering was complete, I used a hot glue gun to make sure the wires would be durable enough to be worn around my neck (it’s still a conference badge, after all…). Even with that, I still had to remove some hot glue later and resolder some of the connections. In the end, I had 8 wires that could be used to connect to the badge via JTAG. Now to find a JTAG adapter.

Once the JTAG wires are soldered, you will need to connect Pin 4 to Ground (at the top of the skull) in order to boot the badge into JTAG mode; leave it connected for as long as you are flashing or programming.

2) Finding the right JTAG adapter:

This is where I wasted all of my time during Defcon 🙁

To program the badge, my plan was to use Intel’s System Studio for Microcontrollers SDK, which is specifically designed to support the D2000. This SDK uses OpenOCD as it’s underlying debugger to program the chip via JTAG. The default options for compatible JTAG programmers in ISSM were USB-onboard, USB-JTAG Flyswatter2, and USB-JTAG Olimex, none of which I had on hand.

According the Google, OpenOCD can be compiled to support JTAG via FTDI chip. After many hours of frustration, I learned that the FTDI chip must support MPSSE (Multi-Protocol Synchronous Serial Engine), typically found in the FT2232 chips, which I didn’t have. I tried using a Sparkfun FTDI breakout and also an Arduino, but turns out they use the FT232RL chip, which is not compatible.

@notreallygeoff had a buspirate available, which OpenOCD can allegedly be compiled to support. However, we were completely unsuccessful in overwriting the firmware; turns out there a bug in the OpenOCD implementation of the buspirate.

Determining the incompatibility of our JTAG programmers took pretty much the whole weekend. I took some solace in the fact that I didn’t see a single badge doing anything that it wasn’t preprogrammed to do; at least I wasn’t the only one who couldn’t hack it.

A few weeks after Defcon, I finally got my hands on the solution. Intel makes a $15 Quark dev board, which has JTAG onboard, and conveniently that JTAG interface can be decoupled and used on external chips, not just the onboard D2000. Plus, since it’s the officially supported JTAG used to program the onboard D2000, that means that it’s compatible out of the box with Intel System Studio for Microcontrollers. No more recompiling OpenOCD bullshit for this guy! So let’s do this!

Programming the Defcon 24 badge

  1. Looking at the front of the badge, solder wires from left to right to the following positions on the header below the chin:

    Position JTAG Pin D2000 Pin
    1 3.3v 3.3v
    3 TCK 14
    4 TMS 15
    5 TDI 16
    6 TDO 18
    8 GND GND

    badge_jtag_pinout

    If your badge doesn’t have any copper exposed at the chin snap point, it might be possible to scrape away the solder mask between the break and the battery holder and solder there, but that would be extremely delicate and difficult.

  2. To use the badge JTAG, you need to put the badge into JTAG mode. Remove power from the badge (battery or other). Connect Pin 4 to Ground (indicated in the image below). How you do this is up to you; I soldered pin headers into the holes and used a jumper wire.

    badge_serial

    Now when you apply power the badge JTAG should be active and ready to receive commands.

  3. On the Quark dev board, remove the JTAG jumpers
    remove_jtag_jumpers

  4. Connect the badge to the Quark dev board JTAG headers, using the center row of pins. Connect the badge’s ground and 3.3v to the dev board’s ground and 3.3v (NOT 5v!!).img_1833 Note: the color of wires pictured as connected to the dev board do not correspond to the color of wires shown soldered to the badge

  5. On an Ubuntu 14.04 machine, go to www.intel.com/quark/mcu/d2000. Follow the instructions to download and install Intel System Studio for Microcontrollers (ISSM). Go as far as you can into the Getting Started guide, including updating the microcontroller ROM.

    Also, make sure you are running ISSM using sudo:

    sudo /opt/intel/issm_2016.1.057/iss_mcu_ide_eclipse-launcher

    Note: you can do this on Windows, but this writeup uses Linux. Sorry (not really).

  6. At this point, it gets a little unclear how to properly proceed. As I was doing this, the solder connection broke on one of my badge wires. So, I don’t know if the issues I was having was because of the loose wire, or because of a ROM write-protection bit set by 1o57. And unfortunately, I only have one badge, so I couldn’t retest my methodology. If you were able to follow all of the Getting Started instructions at the URL in step 3C, including updating the badge ROM image without errors, then you should be good to skip to step 8. Else, go to step 7.

  7. If you weren’t able to update the badge ROM in step 5, check your JTAG connection, and check out this post by Adam Laurie. By running the following command you can just bypass ISSM and just use OpenOCD directly:

    sudo /opt/intel/issm_2016.1.057/tools/debugger/openocd/bin/openocd -f /opt/intel/issm_2016.1.057/tools/debugger/openocd/scripts/board/quark_d2000_onboard.cfg -c init -c 'reset halt' -c 'load_image dc24.bin 0x00180000' -c 'reset halt' -c 'load_image /opt/intel/issm_2016.1.057/firmware/bsp/1.1/soc/quark_d2000/rom/quark_d2000_rom.bin 0x0' -c 'reset run' -c shutdown
  8. Your badge SHOULD now have a fresh firmware on it. However, the original 1o57 code is still in memory, so let’s replace it with our own. Fire up ISSM on your Ubuntu 14.04 box.

  9. In ISSM, select “File > New > Intel Project for Microcontrollers”step1

  10. Select a developer board: Intel Quark D2000 Developer Boardstep2

  11. Select a project type: Intel QMSI 1.1step3

  12. Connection type: USB-Onboardstep4

  13. Give it a name, and under Examples select LED_Blinkstep5

  14. Click Finish

  15. A project window will open with the LED_Blink code

  16. By default, the blink speed is .25 seconds. We need to slow it down so it’ll actually register on the multimeter. Find the following line:

    #define DELAY 250000UL /* 0.25 seconds. */

    and add a zero to change it to:

    #define DELAY 2500000UL /* 2.5 seconds. */
  17. Click the Build button (hammer icon)build

  18. Click the Run button and select <project_name> (flashing)run

  19. Once complete, remove power from the badge and remove the Pin 4-to-Ground jumper installed in step 2.

  20. Connect the negative lead of a multimeter to the badge ground, and the positive lead to the unused pin/wire next to the badge’s JTAG ground connection (the second to last one as listed in step 1 above. Apply power to the badge and you should see the voltage alternate between 0v and 3.3v every 2.5 seconds.

  21. At this point, you can just throw your badge in a box and forget all about it. Or… you could make it blink in a manner different than that which 1057 programmed it to blink. Yeah, let’s do that instead.

  22. Note: The badge LEDs are connected to a power enable pin, Pin 9. For example, to turn on the left eye LED (pin 18), you need to bring both pin 9 and 18 high using qm_gpio_set_pin. The LED pinout is as follows:

    #define LED_BOTTOM_LEFT 6
    #define LED_BOTTOM_MIDDLE 0
    #define LED_BOTTOM_RIGHT 1
    #define LED_EYE_LEFT 18
    #define LED_EYE_RIGHT 2
    #define LED_ENABLE 9
  23. I wrote some code to turn the LEDs on and off one at a time (as shown at the top of this page):

    #include "clk.h" 
    #include "qm_gpio.h" 
    #include "qm_pinmux.h" 
    
    #define LED_BOTTOM_LEFT 6 
    #define LED_BOTTOM_MIDDLE 0 
    #define LED_BOTTOM_RIGHT 1 
    #define LED_EYE_LEFT 18 
    #define LED_EYE_RIGHT 2 
    #define LED_ENABLE 9 
    #define DELAY 60000UL /* 2 seconds. */ 
    
    int main(void) 
    { 
       static qm_gpio_port_config_t cfg; 
       /* Set the GPIO pin direction to out and write the config. */ 
       cfg.direction = BIT(LED_BOTTOM_LEFT) | BIT(LED_BOTTOM_MIDDLE) | BIT(LED_BOTTOM_RIGHT) | BIT(LED_EYE_LEFT) | BIT(LED_EYE_RIGHT) | BIT(LED_ENABLE);
       qm_gpio_set_config(QM_GPIO_0, &cfg); 
       /* Turn on the power enable pin */
       qm_gpio_set_pin(QM_GPIO_0, LED_ENABLE); 
       /* Loop indefinitely while blinking the LED. */ 
       while (1) { 
          qm_gpio_set_pin(QM_GPIO_0, LED_EYE_LEFT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_clear_pin(QM_GPIO_0, LED_EYE_LEFT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_set_pin(QM_GPIO_0, LED_EYE_RIGHT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_clear_pin(QM_GPIO_0, LED_EYE_RIGHT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_set_pin(QM_GPIO_0, LED_BOTTOM_RIGHT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_clear_pin(QM_GPIO_0, LED_BOTTOM_RIGHT); 
          clk_sys_udelay(DELAY); 
          qm_gpio_set_pin(QM_GPIO_0, LED_BOTTOM_MIDDLE); 
          clk_sys_udelay(DELAY); 
          qm_gpio_clear_pin(QM_GPIO_0, LED_BOTTOM_MIDDLE); 
          clk_sys_udelay(DELAY); 
          qm_gpio_set_pin(QM_GPIO_0, LED_BOTTOM_LEFT); 
          clk_sys_udelay(DELAY);   
          qm_gpio_clear_pin(QM_GPIO_0, LED_BOTTOM_LEFT); 
          clk_sys_udelay(DELAY); 
       } 
    }

At this point, I’m way out of my comfort zone. I’m an arduino fan, so this is all more or less new to me. So, your journey into the great “what’s next? ” is up to you.

Resources

I found a program for the badge on github by cktben; while I wasn’t successful in making it run (honestly I didn’t try very hard), it was a great help in understanding how a bit about programming for the Quark D2000.

Also, there is a ton of info on this Reddit thread about the badge. Most of it focuses on the code-breaking part of the challenge, but there is some discussion of the electronics as well.

What Worked

What Didn’t Work

  • BusPirate JTAG
  • FT232RL FTDI Adapter for JTAG programming
  • Powering the badge with 5v

Thanks to @notreallygeoff for figuring out the hard parts and supplying the hardware.

One thought on “Reprogramming the Defcon 24 badge”

  1. Brilliant instructions that you’ve written up there. I couldn’t make it this year, but I purchased a goody bag with everything that people could possibly get their hands on/neglect to hand-in (room key) etc. Just waiting for it to arrive. Thanks for the info

leave it: