Pwn the Xiaomi Yeelight

The Yeelight

Bought on Amazon (20 euros).

Xiaomi Yeelight Smart LED bulb

The Yeelight (Xiaomi) bulb is fitted. Yeelight app is installed and launched on a android smartphone to set the Wi-Fi connection. The password is entered into the app and the bulb is finally registered.

Everything is fine. Light goes on.

Yeelight app showing the connected bulb

Time to focus on the hardware.

The teardown

I remove the white capsule. In the center, the wifi module (the interesting part), with the PCB integrated antenna:

The front side

I examine the Mi module on the rear side. And surprise, five test points with flying probes marks draw my attention…

The back side

Using the binocular to confirm that:

I think it is clear

The Setup

Time to set a JTAG connection:

Dirty, low-cost…

Jtagulator is able to identify the pins (first time of my life it works) :

But it works! God bless America (and Joe Grand)

Vulnerability N*1: JTAG is not disabled

OpenOCD and a FT2232H board are used together to connect to the target:

./gnu-mcu-eclipse/openocd/0.10.0-7-20180123-1217/bin/openocd -f ./mw.cfg

Here is the config file mw.cfg (a little bit modified to use the FTDI):

#
Copyright (C) 2008-2014, Marvell International Ltd.
All Rights Reserved.
#
OpenOCD config script for mc200 and mw300
interface ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x000b
ftdi_layout_signal nTRST -data 0x0200 -oe 0x0200
ftdi_layout_signal nSRST -data 0x0080 -oe 0x0080
transport select jtag
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME wmcore
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
Work-area is a space in RAM used for flash programming
By default use 16kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x4000
}
JTAG speed should be <= F_CPU/6. F_CPU after reset is 32MHz,
and it has been found not to work reliably at 5MHz,
so use F_JTAG = 3MHz
adapter_khz 3000
adapter_nsrst_delay 100
if {[using_jtag]} {
jtag_ntrst_delay 100
}
jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
if {[using_jtag]} {
set _CPUTAPID 0x4ba00477
}
if {[using_swd]} {
set _CPUTAPID 0x2ba01477
}
}
if {[using_jtag]} {
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
}
if {[using_swd]} {
if {[using_hla]} {
hla newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
} else {
swd newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
}
}
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x2001C000 -work-area-size $_WORKAREASIZE -work-area-backup 0
if { [info exists CONFIG_FLASH] } {
flash bank wm0.flash mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000
flash bank wm1.flash mrvlqspi 0x400000 0 0 0 $_TARGETNAME 0x46090000
}
gdb_report_data_abort enable
$_TARGETNAME configure -event gdb-attach {
echo "Limited Results is here"
$_TARGETNAME configure -rtos auto
}
$_TARGETNAME configure -event gdb-detach {
echo "Shutting down"
shutdown
}
if srst is not fitted use SYSRESETREQ to
perform a soft reset
if {![using_hla]} {
cortex_m reset_config sysresetreq
}

It offers full control of the device. Step in, dump and patch memory…. I mean it’s JTAG.

Vulnerability N*2: Wi-FI credentials stored in plaintext in SPI memory

The entire firmware is dumped via JTAG.

The Wi-FI credentials are stored in plaintext at multiple locations inside the Flash memory address range.

Oh, it’s not sooo good man…

Conclusion

The Yeelight Smart bulb (20 euros) designed by Xiaomi is a cool device.

Nevertheless, the security is too yeelight (sorry).

Two HW vulnerabilities have been reported:

  • JTAG interface not disabled.
  • Wi-FI credentials stored in plaintext.

Timeline

  • 16/09/2018: E-mail to Xiaomi Security team.
  • 26/09/2018: Xiaomi answers and confirms the vulnerabilities.
  • 24/10/2018: Posted.


4 Replies to “Pwn the Xiaomi Yeelight”

Leave a Reply

Your email address will not be published. Required fields are marked *