I'm speaking at SecKC February 2017

Written 2017-01-13

Tags:DroneView Security WiFi SecKC KansasCity 

At SecKC's February 7th meeting, come see me present This one time, I bought a drone. I'll also introduce a new, ESP8266-based countermeasure, named DronePwn.


Written 2017-01-05

Tags:XML MadSax Expat BeyondThunderDom LoadWarrior 

Expat Sax Parsing

Expat is a SAX-Parser for XML documents. However, parsing documents directly with Expat is a little cumbersome - Expat triggers a callback for every start and end XML tag, along with a string belonging to that tag, but it is left to the developer to convert this stream of named tags into usable events for processing. Various methods exist for this, including keeping a list of known tag-identifying-strings in the program, and scanning this list per tag to see what should be done. Commonly, this results in a string table that maps to an enumeration, and a switch-case.

MadSax works a little differently.

MadSax sits directly between Expat and higher level logic. Instead of a callback API for arbitrary tags, MadSax is built at compile-time with a list of tags the application is interested in. These tags are used to compile a minimal perfect hashmap using gperf.

Example MadSax Usage

This MadSax Definition File:


Generates the following hash-indexed tag-handlers, which are used to trigger the higher-level application logic. These intentionally mirror the API of Expat, except that the element name need not be parsed, and may be removed in the future.

static void handle_tag_start__svg__rect(void *data, const char *el, const char **attr){}
static void handle_tag_end__svg__rect(void *data, const char *el){}
static void handle_tag_data__svg__rect(void *data, const char *content, int length){}
static void handle_tag_start__svg__circle(void *data, const char *el, const char **attr){}
static void handle_tag_end__svg__circle(void *data, const char *el){}
static void handle_tag_data__svg__circle(void *data, const char *content, int length){}

What comes after MadSax?

Two more XML-parsing related projects are planned after MadSax.

The Load Warrior

The first, The Load Warrior, will be a thin layer on top of MadSax, and will support tagging MadSax definition lines with types. For most cases, this will remove the abstract the current three-step parsing(start/data/end) into a simpler API consisting of a single callback for a single XML Element. Start and End callbacks will still be used to delineate more complex objects, but single callbacks will be used to represent simple tags that enclose a single value.

Beyond ThunderDom

Beyond ThunderDom will sit above The Load Warrior, and serve to aggregate objects converted by The Load Warrior into structures directly usable by higher level application logic. For example, our above example for rectangles becomes:

float x;
float y;
float width;
float height;
const char * style;

static void handle_object__svg__rect(void *data, const struct svg_rect * rect){}

DroneView Security Problems

Written 2017-01-01

Tags:DroneView Security 

WiFi Password

The WiFi uses an open network. This should be replaced with a default password printed on the device label.

Everything Runs as Root

This means any command-injection in the web UI would lend itself to immediate system compromise.

No Shadowfile Support

Password hashes are stored in /etc/passwd. If normal processes ran as something other than root, they would be restricted from fetching password hashes.

Telnet identifies non-users

If attempting to log in over Telnet with an invalid username, Telnet displays 'getpwnam returned null'. This allowed me to quickly exclude a list of common username and password combinations used in IP camera devices. Also telnet should be replaced with SSH.

Poor Password Choices

By sharing a short alphanumeric password, ev1324, across all drones, the compromise of a single drone(mine), combined with telnet, allows wireless bricking of devices.

Weak password hashing algorithms

The root password is hashed with MD5. This took only about 20 minutes to brute-force. Since it is not common for someone to log into this device, there is little downside to using a much slower algorithm.

Unlocked Bootloader

This one I have mixed feelings on, but a bootloader password would have prevented me from extracting password hashes from the firmware. However, if the bootloader were locked, I then would have extracted it from the SPI flash. And then you need disk encryption.

DroneView WiFi Camera, Part 3

Written 2017-01-01

Tags:DroneView UART Serial WiFi 

This one time, I just took the darned thing apart

A third pass at the previous two posts.

Serial Config

Felipe says the default baudrate for HiSilicon Hi3518 IP Cams is 115200 Baud, 8N1


Only connect RX, TX, and GND. Additionally, the PCB test points are not quite 0.1 inch pitch, so I had to bend some pins to get it to connect. Additionally, the 3.3V port does not seem very useful, as it appears the device will become confused if supplied directly with 3.3V without 3.7V from the lithium battery pack. I suspect the WiFi radio is powered from 3.7v. After a little solder and knifework, I have a functional serial port.

Serial Port Mod

Sadly I did not photograph it before reassembly. It is simply solder and hot glue for strain relief.

Rooting the Device Locally

Stop the device very early during startup, and append init=/bin/sh to the boot arguments, then do the normal SPI boot.

Hit any key to stop autoboot: 1 ^H^H^H 0
hisilicon #
hisilicon # setenv bootargs mem=42M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:1M(boot),2944K(kernel),10112K(rootfs),1280K(config),64K(key) init=/bin/sh
hisilicon # sf probe 0;sf read 0x82000000 0x100000 0x300000;bootm 0x82000000
...system boots here...
# cat /etc/passwd

Preparing a backdoor

In UNIX, a second user account may be added with the same user-ID. This is easily prepared using openssl

rsaxvc@x220:~$ openssl passwd -1
Verifying - Password:

Adding a backdoor

Previously, we created our backdoor, now we install it using pipes. I show a demo yoursalt - 1111 hash, but you should use the result from OpenSSL.

# cat /etc/passwd
# echo 'rsaxvc:$1$yoursalt$1111111111111111111111:0:0::/root:/bin/sh' >> /etc/passwd
# cat /etc/passwd
# mount / -o remount,ro
# sync

Cracking the network password

rsaxvc@rsaxvc:~/code/john-1.8.0/run$ nice nice ./john ~/passwd
Loaded 1 password hash (md5crypt [MD5 32/64 X2])
Will run 24 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
ev1324 (root)
1g 0:00:20:12 3/3 0.000824g/s 104157p/s 104157c/s 104157C/s ev199c..ev1r10
Use the "--show" option to display all of the cracked passwords reliably
Session completed
rsaxvc@rsaxvc:~/code/john-1.8.0/run$ telnet
Connected to
Escape character is '^]'.
ipc login: root
Welcome to HiLinux.
None of nfsroot found in cmdline.

Next Steps

DroneView WiFi Camera, Part 2

Written 2016-12-29

Tags:DroneView WiFi 

This one time, I recharged my drone

A second pass at the previous post.


Ran through Mirai password list. No luck.


This THTTPD does not appear to be vulnerable to directory traversal, or was appropriately jailed.


Only four screws. Remove microSD before starting teardown. Be careful not to damage flex cable to image sensor. Once ready to remove PCB, must follow plastic posts through PCB, similar alignment for reinstallation.

Top Case



Neatly tucked into top-case. A bit surprised they used a connector rather than a chip or PCB antenna here.

PCB Side A

This side has the HiSilicon Hi3518 CPU, as well as what appears to be a serial flash, and a four pin UART! I smell a local rootshell.

PCB Side B

This side has power components and the WiFi radio - a radio module design is interesting. It would be cheaper in bulk to integrate directly.

Next Steps