Didier Stevens

Sunday 20 December 2009

Quickpost: Read-Only USB Stick

Filed under: Forensics,Hardware,Quickpost — Didier Stevens @ 20:52

When someone asks me for a read-only USB stick, I recommend to use an SD card with a SD-to-USB adapter, because these are easier to find than USB sticks with write-protection. Most SD cards have a write-protection tab.

But last time I got a surprise: when testing a new SD card reader, I was able to write to the write-protected SD card. Turns out that this particular SD card reader doesn’t support the write-protection tab and always allows the OS to write to the SD card.


Quickpost info


Wednesday 9 September 2009

QuickPost: Arduino + Alcohol Gas Sensor + WiShield + LCD

Filed under: Arduino,Hardware,Quickpost — Didier Stevens @ 20:07

This is a little project I’m working on for Brucon:

20090909-212457

This is an Arduino with a WiFi adapter (WiShield), an LCD and a gas sensor (senses gases like ethanol).

What it does: the Arduino reads the sensor (uncalibrated for the moment), displays its value on line 1 of the LCD and also servers it on a web page (with an embedded webserver connecting to the WiFi network via the WiShield).
If the sensor read-out is 900 or more, a LED is turned on.
And I can send a message via the webserver to line 2 of the LCD.

The problem I had to solve: the LCD didn’t work when the WiShield was operating.

The cause: the WiShield library and the LCD library use some common pins.

Solution: change the pin assignment in the LCD library code (LCD4Bit.cpp):

// --------- PINS -------------------------------------
//is the RW pin of the LCD under our control?  If we're only ever going to write to the LCD, we can use one less microcontroller pin, and just tie the LCD pin to the necessary signal, high or low.
//this stops us sending signals to the RW pin if it isn't being used.
int USING_RW = false;

//RS, RW and Enable can be set to whatever you like
int RS = 1;
int RW = 11;
int Enable = 0;
//DB should be an unseparated group of pins  - because of lazy coding in pushNibble()
int DB[] = {3, 4, 5, 6};  //wire these to DB4~7 on LCD.

//--------------------------------------------------------

And don’t forget to delete LCD4Bit.o before recompiling the code. The Arduino IDE doesn’t check dependencies of libraries when compiling.

And yes, once calibrated, you should be able to use this alcohol gas sensor to prevent drunk e-mailing ;-) But you’ll need to add a sensor to verify you’re actually blowing into the alcohol gas sensor. For example a gas pressure sensor.


Quickpost info


Wednesday 26 August 2009

Yubikey, Trojans and Twitter

Filed under: Encryption,Hardware,Malware — Didier Stevens @ 11:33

Stina, Yubico’s CEO, gave me a Yubikey at RSA London last year. It’s a small keyfob simulating a USB keyboard. Each time you press the button while it’s inserted in a USB port, it generates a one-time-password.

20090825-221451

The Yubikey is a clever little two-factor authentication device.

But I’ve some issues using the Yubikey in a really secure system. As Twitter plays a role in this, and because lately Twitter started to be used by trojans as a communication channel, I decided it’s time to publish the issues I encountered together with mitigating actions.

Technical details

The OTP generated by the Yubikey is an AES-encrypted data stream. I’ve obtained the AES-key embedded in my Yubikey from Yubico and am able to decode the OTP with a simple Python program.

Insert Yubikey and start generating OTPs:

OTP: lkeuuuceeeivjgtbjcbevigeccerfufugdijuhflckrd
public_id = lkeuuuceeeiv
secret_id = ************
counter = 26
counter_session = 1
random_number = 13042
timestamp = 0x8321a8
  • public_id and secret_id identifies the Yubikey (notice that the public_id is the prefix of the OTP).
  • counter: this is a persistent register. It is increased with 1 each time the Yubikey is inserted in a USB port.
  • counter_session: this is a volatile register. It is set to 0 each time the Yubikey is inserted in a USB port, and increased with 1 for each OTP generation
  • random_number is what it says on the tin: a random number, different per OTP
  • timestamp is a volatile 32-bit register. It is set to a random value each time the Yubikey is inserted in a USB port, and is then increased with 1 by a 8Hz clock. Yubico specifies an average variation of 20% on the 8Hz clock per Yubikey. With the measurements I made, I calculate that the 8Hz clock of my key has a 32% deviation.

Validating an OTP is done by successfully decrypting the OTP. Replay attacks are mitigated by comparing the counters and timestamp with historical data.

When trying to design a website that uses the Yubikey to authenticate, I imagined the following attack and found a way to mitigate it.

Attack 1:

Assume a website that uses the Yubikey to logon (i.e. an OTP generated with your Yubikey is needed to log on to the site, possibly together with more classic credentials like a username/password combo).
Because this website has my AES key and can decrypt my OTP, my Yubikey authenticates me and I’m granted access to the site.
A web browser trojan could steal an OTP like this:

  1. I generate an OTP (OTP1) with my Yubikey
  2. The trojan intercepts and stores OTP1, doesn’t send OTP1 to the website, but makes the browser display a fake error message (404, server load too high, Yubikey error, …) prompting me to generate a second OTP
  3. I’m fooled by the fake error, and generate a second OTP (OTP2) with my Yubikey
  4. The trojan intercepts and stores OTP2, and sends OTP1 to the website
  5. The website grants me access, and the trojan stops interfering
  6. OTP2 can be used by the operators of the trojan to get access to the website, as long as I’m not first to access the website at a later time with a new OTP (OTP3). Twitter could be used as a channel to communicate the OTPs in real-time to the trojan operators.

Mitigation:

The website can detect this attack (the malicious use of OTP2) if the following algorithm is implemented:

  1. for every account, the last valid OTP is stored, together with a server-side timestamp (when it was received by the website)
  2. if a new OTP is received, the counter value of the previous OTP is compared with the counter value of the new OTP
  3. when both counters have the same value, the website knows that the OTPs were generated in the same session, and thus that it can compare timestamps.
  4. it calculates the delta of the timestamps of the OTPs, and also the delta of the server-side timestamps when it received the OTPs.
  5. if the 2 deltas differ too much (more than 20% margin), then it refuses the OTP and doesn’t grand access to the website

But now comes the second attack for which I have no mitigation, despite some help from the Yubico forum.

Attack 2:

Assume a website which uses the Yubikey OTP to 1) authenticate users and 2) validate transactions. A classic example of such a site is an online banking site. The user generates an OTP to logon, and then has to generate an OTP for each financial transaction.
A web browser trojan could insert its own transaction like this:

  1. I generate an OTP (OTP1) with my Yubikey
  2. The trojan intercepts and stores OTP1 together with a timestamp, doesn’t send OTP1 to the website, but makes the browser display a fake error message (404, server load too high, Yubikey error, …) prompting me to generate a second OTP
  3. I’m fooled by the fake error, and generate a second OTP (OTP2) with my Yubikey
  4. The trojan intercepts and stores OTP2 together with a timestamp, and sends OTP1 to the website
  5. The website grants me access
  6. After an amount of time equal to the delta between the 2 stored timestamps, the trojan starts a transaction (invisible to the user) and uses OTP2 to validate the transaction.
  7. When I start my own transactions, the trojan passes the OTPs on to the website, but delays them with the same timestamp delta to avoid post-exploitation detection.

I can’t device an algorithm to detect this fraud server-side, if the Yubikey is the only authentication and validation mechanism used. This attack would not work with a challenge-response token, because the keys generated by such a token are different for logon and transaction validation. Typically, these tokens generate one type of keys for logon, and another type of keys based on a challenge for transactions. The challenge encodes data of the transaction, so that a particular challenge can’t be used for another transaction.

One Yubico forum member suggests a type of CAPTCHA to ensure that each submitted OTP is submitted by a human (hence the CAPTCHA), but I don’t believe this is practical, as malware is able to defeat some CAPTCHAs and humans are unable to solve some CAPTCHAs.

Feel free to post a comment with your migitation suggestions, but please keep them practical ;-).

Sunday 23 August 2009

Quickpost: Ardubot Programming

Filed under: Hardware,Quickpost — Didier Stevens @ 14:15

Here’s a small post with extra details on building an Ardubot; details I didn’t find online.

The missing info is which Arduino output lines control the 2 motors. Measuring with a multimeter reveals digital outputs 3, 5, 6 and 9.

I place and solder the motors like this:

The +-sign closest to the PCB:

ardubot-motor-plus-sign

Red wire soldered to + connector, black wire soldered to – connector:

ardubot-motor-wires

I defined left motor and right motor like this:

ardubot

And here’s the schema:

ardubot-schema

To power the left motor in a forward drive, set digital output 9 high and digital output 6 low.

To power the left motor in a reverse drive, do the oposite of a forward drive (9 low and 6 high).

To power down a motor, set both digital outputs low.

To power the right motor in a forward drive, set digital output 5 low and digital output 3 high.

To power the right motor in a reverse drive, do the oposite of a forward drive (5 high and 3 low).

Arduino code:

/*
	Ardubot motor-driving example program
	Version 0.0.1
	Source code put in public domain by Didier Stevens, no Copyright

https://DidierStevens.com

	Use at your own risk

	History:
	2009/08/21: Start development
	2009/08/23: refactoring
*/

unsigned char PIN_HBRIDGE_1A = 9;
unsigned char PIN_HBRIDGE_2A = 6;
unsigned char PIN_HBRIDGE_3A = 5;
unsigned char PIN_HBRIDGE_4A = 3;

void MotorLeftStop()
{
  digitalWrite(PIN_HBRIDGE_1A, LOW);
  digitalWrite(PIN_HBRIDGE_2A, LOW);
}

void MotorLeftForward()
{
  digitalWrite(PIN_HBRIDGE_1A, HIGH);
  digitalWrite(PIN_HBRIDGE_2A, LOW);
}

void MotorLeftReverse()
{
  digitalWrite(PIN_HBRIDGE_1A, LOW);
  digitalWrite(PIN_HBRIDGE_2A, HIGH);
}

void MotorRightStop()
{
  digitalWrite(PIN_HBRIDGE_3A, LOW);
  digitalWrite(PIN_HBRIDGE_4A, LOW);
}

void MotorRightForward()
{
  digitalWrite(PIN_HBRIDGE_3A, LOW);
  digitalWrite(PIN_HBRIDGE_4A, HIGH);
}

void MotorRightReverse()
{
  digitalWrite(PIN_HBRIDGE_3A, HIGH);
  digitalWrite(PIN_HBRIDGE_4A, LOW);
}

void setup() {
  pinMode(PIN_HBRIDGE_1A, OUTPUT);
  pinMode(PIN_HBRIDGE_2A, OUTPUT);
  pinMode(PIN_HBRIDGE_3A, OUTPUT);
  pinMode(PIN_HBRIDGE_4A, OUTPUT);
}

void loop(){
  MotorLeftStop();
  MotorRightStop();
  delay(2000);

  MotorLeftForward();
  delay(2000);

  MotorLeftStop();
  delay(2000);

  MotorLeftReverse();
  delay(2000);

  MotorLeftStop();
  delay(2000);

  MotorRightForward();
  delay(2000);

  MotorRightStop();
  delay(2000);

  MotorRightReverse();
  delay(2000);

  MotorRightStop();
  delay(2000);

  delay(5000);
}

One tip: if you use the large wheels, get a header kit to raise the Arduino Duemilanove, otherwise the wheel will block access to the power and USB connectors:

ardubot-header-kit


Quickpost info


Tuesday 21 July 2009

Quickpost: More Picture-Taking with Python

Filed under: Hardware,My Software,Quickpost — Didier Stevens @ 9:24

Per @TimelessP’s request, here’s so more Python code that can be used for time-lapse photography.

It’s code I wrote to take surveillance pictures from IP-cameras:

20090720-171815

You have to update 2 config files with the data of your IP-cameras: vs.config and credentials.config. Fields in the config files are tab-separated.

vs.config contains the IP cameras, example:

Hall.jpg    http://192.168.1.1/IMAGE.JPG    -

First field is the prefix for the name when saving the picture (suffix is a timestamp). Second field is the URL to access the picture on the IP camera (depends on the model your using). Third field is a fixed name for the picture, use a hyphen (-) if not used.

credentials.config contains the passwords to access the IP-cameras, example:

192.168.1.1    admin    password

Download:

vs_v0_2.zip (https)

MD5: DB806B49705D544F4B928A8F76622125

SHA256: 042FA2CE1F5AEBD433D59B9D4755783E6CE58014FE59086C6A2A8E8781C63B45


Quickpost info


Monday 29 June 2009

Quickpost: Time Lapse Photography With a Nokia Mobile

Filed under: Hardware,My Software,Quickpost — Didier Stevens @ 2:20

Did you know Nokia mobile phones with the S60 platform can be programmed in Python? During my last holiday, I wrote a small program for time lapse photography with my mobile. Here is the result, showing tidal ebbs and flows in Saint-Vaast-la-Hogue and Cancale:

This is the Python program I wrote to take a picture every minute:

#!/usr/bin/python

__description__ = 'Tool to take pictures with a Nokia phone at regular intervals'
__author__ = 'Didier Stevens'
__version__ = '0.1.1'
__date__ = '2009/06/22'

"""

Source code put in public domain by Didier Stevens, no Copyright

https://DidierStevens.com

Use at your own risk

History:
 2009/06/17: start
 2009/06/22: refactoring

Todo:
 Get Threading to work
"""

import camera
import time
import os

timelapseFolder = 'e:\\timelapse\\'
sleepTime = 57

def TakeAndSavePicture():
    global timelapseFolder

    now = '%04d%02d%02d-%02d%02d%02d' % time.localtime()[0:6]
    pic = camera.take_photo()
    pic.save(os.path.join(timelapseFolder, now, '.jpeg'))
    print 'Picture taken: %s' % now

def Main():
    global timelapseFolder
    global sleepTime

    print 'Timelapse photography started'
    if not os.path.isdir(timelapseFolder):
        os.mkdir(timelapseFolder)
        print 'Timelapse folder created: %s' % timelapseFolder
    print 'Wait between pictures %d' % sleepTime
    while True:
        TakeAndSavePicture()
        time.sleep(sleepTime)

if __name__ == '__main__':
    Main()

And then I use Avisynth to combine the jpeg pictures in a movie like this (I join pictures 00001.jpg through 00197.jpeg, 5 per second and produce a 25 fps movie):

ImageSource("%05d.jpeg", 1, 197, 5).ChangeFPS(25)

Quickpost info


Monday 15 June 2009

Quickpost: Arduino XBee Shield Series 2 Configuration

Filed under: Hardware,Quickpost — Didier Stevens @ 8:08

I couldn’t get my 2 Arduinos with an XBee shield to talk to each other, despite the instructions on the Arduino site.

The XBee shields I obtained use a XBee series 2 module, while the instructions on the Arduino site are for the older XBee module.

20090606-111115

After configuring one of my XBee modules as coordinator, the XBee modules were able to communicate with each other.

You need the X-CTU configuration program to configure an XBee series 2 module as coordinator. To connect the XBee module to your PC, you’ve to:

1) remove the ATmega µp from the Arduino board (remember the orientation of the ATmega chip to put it back afterwards):

20090606-111211

2: set the jumpers on the XBee shield to USB:

20090606-111318

3) Connect the XBee shield to the Arduino, and then connect the Arduino via USB to your computer, run the X-CTU configuration program and read the configuration:

20090606-111328

4) Select the coordinator function set and write it to the XBee module:

20090606-111428

When the XBee module has restarted and if your other XBee module is powered on, you’ll see the LEDs of both modules starting to flash, indicating they formed a WPAN network.

After configuring the XBee module, revert to the original hardware configuration: disconnect the Arduino board from your PC, set the jumpers on the XBee shield back to XBee and reinsert your ATmega µp in the Arduino board (watch out for the polarity of the chip).

Now I’m able to run the simple example successfully.


Quickpost info


Tuesday 19 May 2009

Another Lowcost RFID Detector

Filed under: Hardware,RFID,smart card — Didier Stevens @ 21:30

Patrick Gueulle published a logging program (French article) for BasicCards. A BasicCard is a smartcard programmable in a variant of the BASIC language. Patrick’s BasicSPY program logs all APDU requests to a file stored on the smartcard. After using the BasicCard programmed with BasicSPY in a reader, you can retrieve the log file and observe the commands send by the reader to the card.

Patrick’s terminal program to manage the internal file (I translated the menu to English):

20090519-220442

A new type of BasicCard was announced in January: the Dual Interface BasicCard. This smartcard also has a contactless ISO14443/A interface. In other words, this smartcard has a HF RFID interface!

This smartcard is handy to make another lowcost RFID detector: I install BasicSPY on my Dual Interface BasicCard and hold it against an (unknown) RFID reader. When the reader supports ISO14443/A , it will send APDUs to the BasicCard which will log them in the internal file. Later retrieval of the internal file reveals the APDUs send to the smartcard:

20090519-220614

20090519-221114

Monday 4 May 2009

Quickpost: Using Your Poken as a Lowcost LF RFID Detector

Filed under: Hardware,Quickpost,RFID — Didier Stevens @ 0:01

Here’s an alternate use for your Poken: use it to detect 125 kHz RFID readers. Its led will blink red when you bring it next to a LF RFID reader (125 kHz). It will not react with a 13.56 MHz reader; and I haven’t tested with a 134.2 kHz reader.

20090503


Quickpost info


Monday 12 January 2009

A Hardware Tip for Fuzzing Embedded Devices

Filed under: Hardware,WiFi — Didier Stevens @ 21:22

Phidgets are hardware interfaces that let your computer interact with the environment. In this first blogpost of a new series, I explain how to automatically power-cycle a crashed embedded device.

I’ve been playing with Phidgets over the holiday season. Phidgets are inexpensive hardware interfaces for your computer. You connect them via USB, thus extending your machine with digital inputs/outputs and analogue inputs.

There are several aspects I like about the API-software:

  • it’s available for Windows, Linux and Mac
  • the Linux version is open-source (in a next post, I’ll show it running on my nslu2)
  • there’s support for many programming languages, even Python
  • input changes can trigger events (avoids polling loops)

One problem with automated fuzzing of embedded devices (for example a WiFi AP) is that you’ve to power-cycle a device when it crashed. And that’s a problem when you let it run unattended (i.e. overnight). So it would be handy to have your fuzzer power-cycle the device each time it detects the device became unresponsive.

This Phidget Interface Kit with 4 relays lets you do this. Connect the power supply of the embedded device to the NC (Normally Closed) connector of the relay. This way, the un-powered relay will let the current flow through the power-supply and feed the embedded device. To power-cycle the device, activate the relay for a second or two. This will open the circuit and shutdown the embedded device.

Activating a relay for a second is very easy with the Phidgets sofware, here is a Python example for an Interface Kit:

    oInterfaceKit = Phidgets.Devices.InterfaceKit.InterfaceKit()
    oInterfaceKit.openPhidget()
    oInterfaceKit.waitForAttach(10000)

    oInterfaceKit.setOutputState(0, True)
    time.sleep(1)
    oInterfaceKit.setOutputState(0, False)

    oInterfaceKit.closePhidget()

setOutputState is the actual command used to control the relay on output 0. The other statements are necessary to setup the interface.

Before OSes took full control over the input and output ports, a popular solution was to connect a relay to a Centronics printer port and control the output of the port directly from your program. But nowadays, OSes like Windows take full control over the Centronics port (if your machine still has one…), making it much harder to control from user software.

Phidgets were used (but not hurt) for my TweetXmasTree:

20090112-220040

« Previous PageNext Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 223 other followers