Tuesday, December 02, 2014

esp8266 firmware upgrade, odd baudrate in bootloader?

So, I also got one of those ESP8266 wifi/serial modules, which are pretty neat. Unfortunately mine seemed to come with an ancient firmware on it, and pretty unconveniently those didn't want to be re-flashed with newer software.

From Chris’ Miscellanea

The bootloader seems to initialize the modules' serial port to the pretty insane value of 76923 bps, so that in "programming" mode, the stupid windows-utility (or, for that matter, any program expecting standard-baudrates) will fail to communicate with the module.

From Chris’ Miscellanea

If you have a suitable serial cable (a FTDIchip FT2232 is what I used), you can calculate "custom dividers" for most uncommon baudrates, and use those instead of 38,4kBps (the "magic" baudrate indicating that the custom one should be used).

Base-frequency for the ft2232 is 60 Mhz, so we'll use a custom divisor of 780 (60Mhz/76923).

$ setserial /dev/ttyUSB0 spd_cust divisor 780     
$ cu -l ttyUSB0 -s 38400

 ets Jan  8 2013,rst cause:1, boot mode:(7,7)

waiting for host

 ets Jan  8 2013,rst cause:1, boot mode:(7,7)

waiting for host

 ets Jan  8 2013,rst cause:1, boot mode:(3,7)

load 0x40100000, len 24444, room 16 
tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12 
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4 
tail 8
chksum 0xbd
csum 0xbd

Interestingly, that seems to be only the bootloader of the module, after this, the device switches to the more common 115200kbps and responds to AT-commands, given that GPIO15=GND, GPIO2=Vcc, GPIO0=Vcc and CH_PD=Vcc. (pullups to Vcc via ~5kΩ resistor)

So, to get the windows-only updater to run successfully, we...
  • connect GPIOs and CH_PD as listed above (AT-Mode)
  • power up module
  • module will start bootloader with 77kbps, then change into AT-command mode, at 115200 bps
  • connect GPIO0 to GND (firmware download mode)
  • pulse CH_PD to LOW to restart module
  • firmware will restart, but bootloader does NOT go back to 77kbps
  • run firmware-upgrade in windows

From Chris’ Miscellanea

Now I'm upgraded to version 170901 (whatever that means).


Tuesday, August 26, 2014

Building pyqwt 5.2.0 by manually installing the pyqtconfig.py module.

For playing with GNU radio I had to install quite a lot of dependencies to get all the modules to build, unfortunately there's currently a build issue with PyQwt, which are the Python bindings for Qwt, the Qt Widgets for Technical Applications.

Installation of PyQwt-5.2.0 fails with an error message of...
Requires at least PyQt-4.2 and its development tools.
==> ERROR: A failure occurred in build().
...and this is because of the configuration script of PyQwt that tries to import PyQT's pqtconfig.py, that no longer is installed by PyQt 4.11.1!

There are a few bugreports to be found on the web, e.g.

To fix this, get yourself the pyqt-x11 source, then run the configure script as appropriate for your particular Linux installation...
[optiplex …/chris/AUR/python2-pyqt4/src/Py2Qt-x11-gpl-4.11.1]
python2 configure.py -v /usr/share/sip --qsci-api -q /usr/bin/qmake-qt4 Determining the layout of your Qt installation...
This is the GPL version of PyQt 4.11.1 (licensed under the GNU General Public
License) for Python 2.7.8 on linux2.
Type '2' to view the GPL v2 license.
Type '3' to view the GPL v3 license.
Type 'yes' to accept the terms of the license.
Type 'no' to decline the terms of the license.
Do you accept the terms of the license? yes
Found the license file pyqt-gpl.sip.
Checking to see if the QtGui module should be built...
Checking to see if the QtHelp module should be built...
Checking to see if the QtMultimedia module should be built...
Checking to see if the QtNetwork module should be built...

Creating pyrcc4 Makefile...
Creating Qt Designer plugin Makefile...
Creating pyqtconfig.py...
At this point, the proper pyqtconfig.py script has been created, install to the python site-package directory.
[optiplex …/chris/AUR/python2-pyqt4/src/Py2Qt-x11-gpl-4.11.1]
$ sudo install -m644 pyqtconfig.py /usr/lib/python2.7/site-packages/PyQt4/pyqtconfig.py 
Now, the pyqwt bindings can be built, e.g. by using ArchLinux's makepkg utility, using the AUR package.
[optiplex /home/chris/AUR/pyqwt]
$ makepkg
==> Making package: pyqwt 5.2.0-10 (Tue Aug 26 21:37:07 CEST 2014)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Starting build()...
patching file qt4lib/PyQt4/Qwt5/qplt.py
patching file configure/configure.py
patching file configure/configure.py
Command line options:
{'debug': False,
 'disable_numarray': False,
cp -f ../../qt4lib/PyQt4/uic/widget-plugins/qwt.py /home/chris/AUR/pyqwt/pkg/pyqwt/usr/lib/python2.7/site-packages/PyQt4/uic/widget-plugins/qwt.py
make[1]: Leaving directory '/home/chris/AUR/pyqwt/src/PyQwt-5.2.0/configure/qwt5qt4'
==> Tidying install...
  -> Purging unwanted files...
  -> Removing libtool files...
  -> Removing static library files...
  -> Compressing man and info pages...
  -> Stripping unneeded symbols from binaries and libraries...
==> Creating package "pyqwt"...
  -> Generating .PKGINFO file...
  -> Generating .MTREE file...
  -> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: pyqwt 5.2.0-10 (Tue Aug 26 21:40:25 CEST 2014)

Tuesday, August 12, 2014

Controlling USB device access on Linux (e.g. BADusb defense)

So, there was a lot of fuzz about a recent talk by Karsten Nohl et al. at BlackHat about the the unsecurity of current USB implementations (on the computer side) which happily load drivers for all kinds of devices as soon as a (potentially malicious) USB stick is connected.

I completely agree that, as shipped, most computer systems will be susceptible to this attack, and assume that all of their attacks will work as advertised. What I don't agree with at all is their conclusion, which boils down that no effective defenses exist.

While I haven't made my homework to develop a defense, I want to at least show the mechanism in current Linux kernels to limit binding of potentially dangerous drivers to specific devices, so that e.g. a inserted USB-stick would only be mounted as a block device, and its malicious keyboard interface be ignored.

Binding of Drivers

A linux-module can claim ownership of certain usb vendor/device ids or device classes. Those are visible when looking at the modinfo of a kernel module, to facilitate autoloading of modules, but are also registered in internal kernel structures, so that drivers compiled in statically directly can be mated with the proper devices:

$ modinfo snd-usb-audio
filename:       /lib/modules/3.15.8-1-ARCH/kernel/sound/usb/snd-usb-audio.ko.gz
license:        GPL
description:    USB Audio
author:         Takashi Iwai
alias:          usb:v*p*d*dc*dsc*dp*ic01isc01ip*in*
alias:          usb:v0D8Cp0103d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v*p*d*dc*dsc*dp*ic01isc03ip*in*
alias:          usb:v200Cp100Bd*dc*dsc*dp*ic*isc*ip*in*
This information currently comes from the MODULE_DEVICE_TABLE of sound/usb/card.c, stored in an array called usb_audio_ids. The bold one is the "default class", the others all are included in the "quirks table", which includes all exceptions from the default class.
static struct usb_device_id usb_audio_ids [] = {
#include "quirks-table.h"
       .bInterfaceClass = USB_CLASS_AUDIO,
       .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
     { }                                         /* Terminating entry */
MODULE_DEVICE_TABLE(usb, usb_audio_ids);
On connection of a USB device, the kernel will look through all its currently registered modules that claim to support USB devices (by registering those tables with the kernel) and bind devices to drivers (and if it doesn't succeed, it will call udev/hotplug to load a module that does). 

The Vulnerability

So, if you connect a particular USB headset, the electronics of which I have laying around... you get a new sound device in ALSA...
[root@optiplex devices]# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 1: Headset [Logitech USB Headset], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
But also a new keyboard! (the mute/volume buttons on the headset, but those could be arbitrary buttons entering text, too).
[root@optiplex devices]# xinput
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse         id=8 [slave  pointer  (2)]
⎣ Virtual core keyboard                   id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard             id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Power Button                             id=7 [slave  keyboard (3)]
    ↳ Das Keyboard                             id=9 [slave  keyboard (3)]
    ↳ Logitech Logitech USB Headset           id=10 [slave  keyboard (3)]
If you look in the sysfs filesystem, you can see, that the USB headset (usb device 5-1) has 4 distinct functions (.0 -- .3) on configuration :1.
[root@optiplex /sys/bus/usb/devices/5-1]# ls
5-1:1.0     bcdDevice    maxchild
5-1:1.1     bmAttributes   port
5-1:1.2     busnum    power
5-1:1.3     configuration  product
authorized     descriptors    quirks
avoid_reset_quirk    dev    removable
bConfigurationValue  devnum    remove
bDeviceClass     devpath    speed
bDeviceProtocol      driver    subsystem
bDeviceSubClass      ep_00    uevent
bMaxPacketSize0      idProduct    urbnum
bMaxPower     idVendor    version
bNumConfigurations   ltm_capable
bNumInterfaces     manufacturer
And those are described by the (very lengthy) lsusb -v output, which I'll not reproduce completely here, just try it for yourself on any USB device.

Bus 005 Device 006: ID 046d:0a0b Logitech, Inc. ClearChat Pro USB
Device Descriptor:
  bNumConfigurations      1
  Configuration Descriptor: (configuration #1 starts here)
    bLength                 9
    Interface Descriptor: (interface 1:0)
       bDescriptorType         4
       bInterfaceNumber        0

    bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      AudioControl Interface Descriptor: (detailed info about audio capabilities)
        bLength                10
    Interface Descriptor: (interface 1:3)
      bInterfaceNumber        3
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 

So, here you have it, one device that (legitimately) is both a soundcard and a keyboard/mouse (e.g. an human interface device). Given enough motiuvation, code could be written for the controller inside the soundcard that enters arbitary text to my computer. And that's basically the vulnerability presented in the Black Hat Presentation by Nohl et al.


But, you can easily turn off this automatic binding, at least on Linux, with one single command:
[root@optiplex ~]# echo 0 >/sys/bus/usb/drivers_autoprobe 
Now, whenever you connect a USB device to your computer, it will not automatically connect the usb-soundcard to the ALSA subsystem and the volume buttons to the hidraw/keyboard driver. If I now connect the aforementioned soundcard, I'll not get a new keyboard in xinput, nor a soundcard in ALSA (and also not a network- or block-device for a network card or USB disk).

The only thing I'll get in my dmesg is the message, that an USB device has been connected:
[13399.092113] usb 5-1: USB disconnect, device number 6
[13405.245389] usb 5-1: new full-speed USB device number 7 using uhci_hcd
And to manually bind this device, you first have to choose the appropriate USB configuration...
# echo 1 >/sys/bus/usb/devices/5-1/bConfigurationValue 
...and tell the usb audio driver to bind to that device.
# echo 5-1:1.0 >/sys/bus/usb/drivers/snd-usb-audio/bind
Now you have the USB audio interface, but not the keyboard, yet... If you wanted, you'd just bind usb-hid to interface 3.
# echo 5-1:1.3 >/sys/bus/usb/drivers/usbhid/bind 
To verify that your keyboard presses aren't registed from the connected device before, and are registered after binding, you can run "xev" and press the volume buttons (note: those, in principle, could enter arbitrary text to your computer, depending on the programming of the controller in the device).
KeyRelease event, serial 38, synthetic NO, window 0x3800001,
    root 0x1dc, subw 0x3800002, time 13880057, (41,58), root:(2384,618),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
The most often quoted use-case if obviously connection of a usb-storage device, e.g. an external harddrive or flash-stick.

[14567.888596] usb 6-1: new high-speed USB device number 4 using ehci-pci
# echo 1 >/sys/bus/usb/devices/6-1/bConfigurationValue
# echo 6-1:1.0 >/sys/bus/usb/drivers/usb-storage/bind
[14667.692717] usb-storage 6-1:1.0: USB Mass Storage device detected
[14667.692936] scsi7 : usb-storage 6-1:1.0
[14668.696482] scsi 7:0:0:0: Direct-Access     TOSHIBA  MK4309MAT        G5.0 PQ: 0 ANSI: 0 CCS
[14668.698461] sd 7:0:0:0: [sdd] 8452080 512-byte logical blocks: (4.32 GB/4.02 GiB)
(yes, it's a very, very crappy and old USB harddisk)

Proper user-interface, current lack thereof.

To convert all this sysfs poking into a proper user-friendly software, one will have to...

  • On computer startup, disable  autoprobe (probably there's a kernel command line for that).
  • Statically configure the minimal interfaces used (e.g. the main usb keyboard, trackpad/mouse, ...).
  • During normal operation, watch hotplug-events or poll the sysfs filesystem for newly inserted usb devices.
  • Verify presented configurations of USB devices and their interfaces with a policy (e.g. enable only usb-storage devices, e.g. "thumbdrivers"
  • Ask the user, if he's happy with this device.
  • On successful verification, only bind the single necessary driver (e.g. usb-storage) to the proper interface of the device.

Of course, for certain devices more sophisticated verification schemes could be envisioned, checking certificates, downloading firmware for verification (which, again, might be forged, ...).

The "Authorized" Mechanism

There's a second mechanism to disable/enable communication with USB device using the "authorized" property of USB controllers. It's described in the kernel documentation.


There seems to be a group policy for that... Local Computer PolicyComputer Configuration,Administrative TemplatesSystemDevice Installation, and Device Installation Restrictions

Monday, March 24, 2014

Stairville DJ-X 16, voided my warranty

The DJ-X 16 is a very basic DMX controller, which I used to test out DMX controlled (d'uh...) LED lights. I cannot recommend it, it lacks a lot of features, and the buttons/faders have a very flimsy feeling. Nevertheless: Because I was pondering if it was worthwhile to modify its firmware, I decided to void the warranty (yeah!) and here are few pictures documenting the insides of this device.

What I found pretty interesting is the fact that, even though I bought it new only a few months ago, and it's still being manufactured exactly like that, it uses pretty antique components, and is an all-through-hole PCB, not a single SMD to be found.

The main controller is a Atmel AT89C55WD, a 8051 compatible 8-bit microcontroller. It's meagre 256 bytes of internal RAM is extended by 8k of High-Speed (120ns...) SRAM. A 29EE010 EEPROM takes care of the 8051's lack of long-term memory. Everything else is 80s-style design, with a lot of 47hc's.

There's a second, smaller, PCB which is home of the SN57176 RS485 driver/receiver, an optocoupler (MIDI out/through), connectors and a 7805 voltage regulator. The flat-ribbon cable connecting this connection-PCB to the main board is nicely labeled on the silkscreen, very convenient.

K1    1   2  COM
K2    3   4  Audio2
K3    5   6  Audio1
k5    7   8  MIDI in
+5V   9  10  +5V
NC    11 12  MIDI through
GND   13 14  GND
+5V   15 16  +5V
NC    17 18  DMX out
+12V  19 20  +12V

From Chris’ Miscellanea

From Chris’ Miscellanea

From Chris’ Miscellanea

Sunday, March 09, 2014

Playing with a AM2302 Temperature/Humidity Sensor & LUFA

I played around with a Adsong AM2302 Temperature/Humidity sensor today which has a pretty neat serial interface.

From Chris’ Miscellanea

I wrote some code to read in the data using the input-capture mode of the Timer/Counter1 in a AVR ATmega32u4 (way overpowered, but it's handy on a Olimexino 32U4 board) to learn about using the LUFA USB library a little, maybe someone can put it to actual use?

$ cu -l ttyACM0
Triggering conversion.
AS2302 raw bytes: recv cnt=0 01 76 00 fa 71

status: 0, temp=250 (*0.1 dC), rh=374 (*0.1%)

Thursday, March 06, 2014

Get /dev/spidev on an Raspberrypi running under Archlinux ARM working again.

Currently, when running a raspberry-pi with the latest kernel available for Archlinux, access to the SPI bus via /dev/spidev no longer works. Bugs have been filed, but apparently the late-binding logic available via spi_register_board_info just seems to be broken right now.

I've written a small kernel module that doesn't fix the initial bug, but just does the binding of spidev to the first two chipselects of the first spi master. It's available on github.

$ ls -la /dev/spidev*
zsh: no matches found: /dev/spidev*

$ sudo insmod rpi_add_spidev_module/rpi_add_spidev_module.ko 

$ dmesg
[  245.299487] spi_master spi0: ...is the master for device #0.
[  245.299709] spi spi0.0: ...is the device #0.
[  245.299734] spi_master spi0: ...is the master for device #1.
[  245.304763] spi spi0.1: ...is the device #1.

$ ls -la /dev/spidev0.*
crw------- 1 root root 153, 0 Mar  6 16:47 /dev/spidev0.0
crw------- 1 root root 153, 1 Mar  6 16:47 /dev/spidev0.1

# cd /sys/bus/spi/drivers/spidev
# ls -l
total 0
--w------- 1 root root 4096 Jan  1 00:03 bind
lrwxrwxrwx 1 root root    0 Jan  1 00:02 module -> ../../../../module/spidev
lrwxrwxrwx 1 root root    0 Jan  1 00:03 spi0.0 -> ../../../../devices/platform/bcm2708_spi.0/spi_master/spi0/spi0.0
lrwxrwxrwx 1 root root    0 Jan  1 00:02 spi0.1 -> ../../../../devices/platform/bcm2708_spi.0/spi_master/spi0/spi0.1
--w------- 1 root root 4096 Jan  1 00:00 uevent
--w------- 1 root root 4096 Jan  1 00:02 unbind

Using software to talk to a proprietary SPI gyro/accelerometer module works again.

$ sudo ./rpi_gyro /dev/null  
Opened gpio25 direction as fd 5.
Opened gpio25 value as fd 6.
Opened /dev/spidev0.0 as fd 7 (0x03, 8, 0).
Opened /dev/spidev0.1 as fd 8 (0x03, 8, 0).
lsm330dlc_dump_regs: dumping accelerometer registers.
$00: $00 $00 $00 $00   $00 $00 $00 $ff
$08: $00 $00 $00 $00   $00 $00 $00 $33
$10: $86 $16 $a6 $26   $48 $25 $21 $1e
$18: $1b $a3 $50 $65   $c0 $00 $50 $00
$20: $27 $00 $00 $80   $40 $00 $00 $ff
$28: $00 $2d $c0 $01   $40 $27 $80 $9e
$30: $00 $00 $00 $00   $00 $00 $00 $00
$38: $00 $00 $00 $00   $00 $00 $00 $00
lsm330dlc_dump_regs: dumping gyro registers.
$00: $d3 $66 $a8 $cc   $4d $d0 $11 $f1
$08: $20 $06 $ff $18   $02 $83 $00 $d3
$10: $90 $2b $19 $44   $0c $e0 $61 $60

Sunday, February 09, 2014

Riso Kagaku Corp Webmail Notifier Redux: Kernel Module Cleanup

Trying to clean up this code, so that it's usable without too much friction...

I put up my slightly modified version of the usbled.c kernel module on github. It includes support for one of the cheapest incarnation of USB-led devices, the Riso Kagaku Corp. Webmail Notifier. It can now be built out-of-tree easily (trying to forward to the kernel guys to merge it eventually) and includes udev rules and a script to automate the re-binding of device from usbhid to the usbled driver).

Movie hosted by instagram: