Reversing a Japanese Wireless SD Card
From Zero to Code Execution
Guillaume VALADON - @guedou

?
2015

2018

2

?

?
3

Get the slides athttps://goo.gl/oijvdN

4

Toshiba FlashAir

5

See https://www.flashair-developers.com/en/documents/api/config/

Main Features
access files over Wi-Fi
SSID: flashair_{MAC address}
PSK: 12345678

provide some services
DHCP, DNS, HTTP

configured with SD_WLAN/CONFIG
6

See https://flashair-developers.com/en/documents/api/lua/ &https://connpass.com/event/78343/

FlashAir Extended Features
Lua script executed on the cardon boot, write events, or over HTTP

specific FlashAir API
interface with SPI, I2C, Wi-Fi …
bitcoin rate display with I2C

7

Four Generations

2012

2013

2015

2017

25$

55$
8

Game Plan

☐ memory dump
☐ architecture☐ Operating System☐ execution vector

9Inspecting Firmwares Updates

10

v3.00.00

October 2014v3.00.01

August 2015v3.00.02

August 2016

See https://web.archive.org/ &https://www.toshiba.co.jp/p-media/english/download/wl/updatetool02_w03.htm

Firmwares Versions

11

This talk focuseson v3.00.00

12Extracting the Firmware
download the Mac OS zip fileunzip the .app
explore Contents/Resources
CONFIG files
fwupdate.fbn (~1MB)

13

Operation of The Software Update Tool
copy fwupdate.fbn to the card
add the following line to SD_WLAN/CONFIG
COMMAND=update -f fwupdate.fbn -rm -reboot

eject & insert the card14

$ r2 fwupdate.fbn[0x00000000]> px 512- offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00000000 464c 4153 4841 4952 4d41 494e 3200 0000
0x00000010 0102 0304 1c7e 1f00 250f c200 10fc 0f00
0x00000020 08d8 0101 28d8 0000 5b7c 101c 597c 0000
0x00000030 0270 0000 0000 0000 0000 0000 0000 0000
0x00000040 0000 0000 0000 0000 0000 0000 0000 0000
0x00000050 0000 0000 0000 0000 0000 0000 0000 0000
0x00000060 0000 0000 0000 0000 0000 0000 0000 0000
0x00000070 0000 0000 0000 0000 0000 0000 0000 0000
0x00000080 0000 0000 0000 0000 0000 0000 0000 0000
0x00000090 0000 0000 0000 0000 0000 0000 0000 0000
0x000000a0 0000 0000 0000 0000 0000 0000 0000 0000
0x000000b0 0000 0000 0000 0000 0000 0000 0000 0000
0x000000c0 0000 0000 0000 0000 0000 0000 0000 0000
0x000000d0 0000 0000 0000 0000 0000 0000 0000 0000
0x000000e0 0000 0000 0000 0000 0000 0000 0000 0000
0x000000f0 0000 0000 0000 0000 0000 0000 0000 0000
0x00000100 0000 0000 0000 0000 0000 0000 0000 0000
0x00000110 0000 0000 0000 0000 0000 0000 0000 0000
0x00000120 0070 2859 5979 0059 5879 03eb a041 b5cc
0x00000130 0010 b5cb 2000 2a6b 5a6c c01b 30eb 5b00

fwupdate.fbn content

0123456789ABCDEF
FLASHAIRMAIN2...
.....~..%.......
....(...[|..Y|..
.p..............
................
................
................
................
................
................
................
................
................
................
................
................
................
................
.p(YYy.YXy...A..
.... .*kZl..0.[.
15

Searching Strings with radare2
b 32k
p=z

s 0xc80000
psb

0x000cfa8f %03d%03d%03d%02d%08x%08x
0x000cfaae int_udf
0x000cfab7 exc_udf
0x000cfac0 sys_dwn 0x%08x
0x000cfad0 *** abort ***0x000cfadf !!!!!!!!! dp_bridge entry error
0x000cfb0c set IP=%d:%d:%d:%d0x000cfb20 Error6 Initial firmware not found
0x000cfb46 Error5 Firmware update failed
0x000cfb65 Error4 WLAN not established
0x000cfb82 Error3 WLAN not established
0x000cfb9f Error2 SSID not setup
0x000cfbb6 Error1 MAC ID invalid
0x000cfbcd !!!!!!!! ctrlIMsgBufInit no memory
0x000cfbf1 !!!!! ctrl_snd_mbx no memory
0x000cfc0f wait wps button
0x000cfc20 detect wps button
0x000cfc33 The AP may be configured MAC address filtering.
0x000cfc64 802.11 Key Descriptor length is too short (%d,%d)0x000cfcb1 802.11 Key Descriptor length is inconsistent
0x000cfcde Key Data Enccapsulation '%d' duplicated0x000cfd09 discard EAPOL-Key due to invalid Key MIC
0x000cfd32 discard EAPOL-Key due to failure of Key Data
decryption
0x000cfd6a EAPOL-Key Replay Counter is smaller than expected
0x000cfd9c pktsa
0x000cfda4 %02x0x000cfdaa ek
0x000cfdb2 %02x0x000cfdb8 EAPOL-Key Replay Counter is not same as
16transmitted

“/eva.cgi”

access it over HTTP
http://192.168.0.1/eva.cgi

looks like the output buffer
information, warnings ...

> f_SCAN CH=1
SCAN CH=2
SCAN CH=3
SCAN CH=4
SCAN CH=5
SCAN CH=6
SCAN CH=7
SCAN CH=8
SCAN CH=9
SCAN CH=10
SCAN CH=11[SEC] (info) Authenticator Mode
[SEC] (warning) PSK passphrase length is too short[SEC] (info) InitializeSecTask
set ap.group_cipher[SEC] (info) Group Cipher = CCMP[SEC] (info) check SSID and its length ... OK
DHCP server task start[NB] Registered successful (FLASHAIR)

17

“TELNET”

edit SD_WLAN/CONFIG withTELNET=1

telnet daemon on 23/tcp
character per character> f_TELNET start
SCAN CH=1
SCAN CH=2
SCAN CH=3
SCAN CH=4
SCAN CH=5
SCAN CH=6
SCAN CH=7
SCAN CH=8
SCAN CH=9
SCAN CH=10
SCAN CH=11[SEC] (info) Authenticator Mode
[SEC] (warning) PSK passphrase length is too short[SEC] (info) InitializeSecTask
set ap.group_cipher[SEC] (info) Group Cipher = CCMP[SEC] (info) check SSID and its length ... OK
DHCP server task start[NB] Registered successful (FLASHAIR)

18

$ telnet 192.168.0.1
Telnet escape character is '^]'.
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
Welcome to FlashAir
ESC R4539 built 15:37:44, Aug 28 2015>
telnet> mode character> version
version
FA9CAW3AW3.00.01> exittelnet character mode
19

Asking for Help

COMMAND=help in CONFIG
restart & check /eva.cgi

TELNET=1 in CONFIG
type help in telnet session

20

help
version
mod
fdump
dump
-- >8 --

show help
show version
Modify Memory
Memory dump to file
Dump Memory

32
commands

21

Inspecting the Card

22

See https://fccid.io/ZVZP42

Getting Inside
1. opening the card

2. searching FCC applications

using a sharp blade

FlashAir FCC ID: ZVZP42350FA3

23

bonus information
chips markings

See https://fccid.io/ZVZP42350FA3/Internal-Photos/Internal-photo-2388053

Pictures From the FCC Application

24

FlashAir W-03 Innards
Toshiba TC58TFG7DDLTAID: Flash memory
Toshiba 6PJ8XBG: Flash Memory controller
SPI - USON-8 4x4 mm - 2MB
Macronix - MX25L1606E
Winbond - Q16DVUZIGAiroha AL2238: 802.11 b/g - RF transceiverToshiba TC90535XBG: ?

25

the SoC
802.11n MAC
32-bit RISC
released in 201326

See https://www.toshiba.co.jp/tech/review/2011/high2011/high2011pdf/1103.pdf &http://toshiba.semicon-storage.com/design_support/exhibition_seminar/exhibition/pdf/car14_bt_wifi.pdf

Toshiba TC90535XBG

Dumping Memory27Software Based Dump

CONFIG & TELNET commands
fdump - write memory to files
dump - print memory content

dump 0x0 -l 0x100
address=0x00000000 length=0x100
0001d808 0008df18 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
address=0x00000080
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
28

flashre Tools - https://github.com/guedou/flashre
simplify reversing FlashAir cards
telnet, update, xref ...

automate useful tasks
dump, naming ...

Docker image available$ docker pull guedou/flashre29

Dumping Memory with flashre$ flashre dump dump_w03.txt

dump$ flashre dump --convert dump_w03.txt > dump_w03.bin$ ls -alh dump_w03.bin-rw-rw-r--. 1 guedou guedou 2.0M Aug 08 13:30 dump_w03.binconversion
30

Game Plan

☐ memory dumpX☐ architecture☐ Operating System☐ execution vector

31

Identifying the CPU

32

Magic Format Strings

R%-2d:%08x

R%-2d:%08x

R%-2d:%08x R%-2d:%08x\n

PSW:%08x LP:%08x NPC:%08x EXC:%08x EPC:%08x\n
print registers contents

33

See https://sourceware.org/cgen/gen-doc/mep.htm

34cgen - MeP architecture description in guileDisassembling the Dump
compile binutils with MeP support
tar xzf binutils-2.31.tar.gz && cd binutils-2.30 && ./configure --target=mep && make$ mep-objdump -m mep -b binary -D dump_w03.bin
dump_w03.bin:file format binary

Disassembly of section .data:
00000000 <.data>:
0:08 d8 01 00
4:
18 df 08 00
8:
00 00

jmp 0x100
jmp 0x8e2
nop35

Where is it Used?

Gigabeat U Info

Image Recognition

Sony PlayStation Vita

36

Get in on http://www.datasheetarchive.com

37

MeP manual in English

Toshiba Media-embedded Processor
MIPS likeload/store, ...

16 general-purpose registers
33 control/special registers~200 instructions
2 or 4 bytes eachno privileged modecalling convention
first four registers then stack

32 bits addresses
up to 4GB

Little-Endian or Big-Endian
LEND field in the CFG register38

*REPEAT Instructions
REPEAT and EREPEAT
E stands for Endless

three dedicated registers
RPB, RPC, RPE

0x00c7fb84
0x00c7fb88
RPB> 0x00c7fb8c
RPE> 0x00c7fb8e,=< 0x00c7fb90`-> 0x00c7fb92
0x00c7fb94
0x00c7fb96

loop over a block
two instructions executed at RPE

ADD3 R12, R1, 0x1
EREPEAT 0x6
LB R11, (R1)ADD R1, 1
BEQZ R11, 0xC7FB92
MOV R0, R1
SUB R0, R12
RET

strlen()39

Memory Map

flash likely located at 0x00000
boot program
reset and NMI handlers

40Guessing The Main Base Address
BSR use signed offset!
offset related to PC

calls can go to lower or higher addresses$ mep-objdump -m mep -b binary -D dump_w03.bin-- >8 -fd27a:
69 d9 26 00 bsr 0xff8a6

incorrect BSR address
41

brute-force base address
in Python2, C++, Ruststeps
1. get string offsets
2. use all words as pointers
3. subtract base from pointers
4. score valid pointers$ rbasefind dump_w03.bin
Located 3843 strings
Located 180087 pointers
Scanning with 8 threads...
0x00c00000: 348
0x00b8b000: 45
0x00b89000: 44
0x00b87000: 41
0x00b8a000: 37
0x00b88000: 37
0x00b84000: 36
0x00c07000: 34
0x00bfe000: 34
0x00c04000: 32

See https://github.com/sgayou/rbasefind

basefind42

Disassembling Using the Main Base Address$ mep-objdump -m mep -b binary -D dump_w03.bin-- >8 -fd27a:
69 d9 26 00 bsr 0xff8a6$ mep-objdump -m mep -b binary -D dump_w03.bin --adjust-vma=0xC00000-- >8 -cfd27a:
69 d9 26 00 bsr 0xcff8a6

correct BSR address
43

Game Plan☐
X memory dump☐
X architecture☐ operating System☐ execution vector

44~6500
BSR-based functions

45

MeP Tools

46

Wish List
disassembly with semantics
split basic blocks

instructions emulation
validate functions behavior

graphical interface
navigate call-graphs, analyse functions, ...
47

Python-based reverse engineering frameworkassemble & disassemble x86, ARM, MIPS, ...
symbolic execution using intermediate languageemulation using JIT

simplify defining new architectures

See http://miasm.re & https://github.com/cea-sec/miasm

miasm2

assembling & disassembling
expressing semantics

48

MOV Rn,Rm

0000_nnnn_mmmm_0000 (Rn=nnnn, Rm=mmm)

MeP manualreg04 = bs(l=4, cls=(mep_reg,))
addop("MOV", [bs("0000"), reg04, reg04, bs("0000")])arch/mep/arch.py@sbuild.parsedef mov(regn, regm):
regn = regm

arch/mep/sem.py

See https://github.com/cea-sec/miasm/tree/master/miasm2/arch/mep

miasm2 - Adding the MeP MOV Instruction

49

discover functions using jitters
emulate functions and verify their side effects

See https://github.com/cea-sec/Sibyl

Sibyl

an API bruteforcer$ sibyl find -j gcc -a mepl -m 0xC00000 dump_w03.bin $(cat top_100_addresses.txt)
0x00c7fb84 : strlen
0x00c7cd58 : strcmp
0x00c7c094 : strcat
0x00c7cf70 : strcpy
0x00c78178 : strncpy
0x00c77540 : strncmp
0x00c46808 : atoi
0x00cf7808 : memcpy
0x00c7c41c : strchr

50

9automatically discovered functions

51

RE framework
console based
set of command line utilities
extendable with plugins

See https://www.radare.org

radare2$ r2 /bin/ls[0x00005060]> pd 10;-- entry0:;-- rip:
0x00005060
31ed
xor ebp, ebp
0x00005062
4989d1
mov r9, rdx
0x00005065
5e
pop rsi
0x00005066
4889e2
mov rdx, rsp
0x00005069
4883e4f0
and rsp, 0xfffffffffffffff0
0x0000506d
50
push rax
0x0000506e
54
push rsp
0x0000506f
4c8d058a0c01. lea r8, [0x00015d00]
0x00005076
488d0d130c01. lea rcx, [0x00015c90]
0x0000507d
488d3d9ce5ff. lea rdi, [0x00003620][0x00005060]> px- offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00005060 31ed 4989 d15e 4889 e248 83e4 f050 544c 1.I..^H..H...PTL
0x00005070 8d05 8a0c 0100 488d 0d13 0c01 0048 8d3d ......H......H.=
0x00005080 9ce5 ffff ff15 6ead 2100 f40f 1f44 0000 ......n.!....D..
0x00005090 488d 3dd1 b121 0055 488d 05c9 b121 0048 H.=..!.UH....!.H
0x000050a0 39f8 4889 e574 1948 8b05 eaab 2100 4885 9.H..t.H....!.H.
0x000050b0 c074 0d5d ffe0 662e 0f1f 8400 0000 0000 .t.]..f.........
0x000050c0 5dc3 0f1f 4000 662e 0f1f 8400 0000 0000 ]...@.f.........
0x000050d0 488d 3d91 b121 0048 8d35 8ab1 2100 5548 H.=..!.H.5..!.UH
0x000050e0 29fe 4889 e548 c1fe 0348 89f0 48c1 e83f ).H..H...H..H..?
0x000050f0 4801 c648 d1fe 7418 488b 05a9 ae21 0048 H..H..t.H....!.H
0x00005100 85c0 740c 5dff e066 0f1f 8400 0000 0000 ..t.]..f........
0x00005110 5dc3 0f1f 4000 662e 0f1f 8400 0000 0000 ]...@.f.........
0x00005120 803d a1b1 2100 0075 2f48 833d 97ae 2100 .=..!..u/H.=..!.
0x00005130 0055 4889 e574 0c48 8b3d caae 2100 e8cd .UH..t.H.=..!...
0x00005140 e4ff ffe8 48ff ffff c605 79b1 2100 015d ....H.....y.!..]
0x00005150 c30f 1f80 0000 0000 f3c3 660f 1f44 0000 ..........f..D..
[0x00005060]>

52

use miasm2 features from radare2

See https://github.com/guedou/r2m2

r2m2 - radare2 + miasm2 = ♥assemble, disassemble, split blocks
convert miasm2 expression to radare2 ESIL

provides two radare2 plugins
ad: assembly & disassembly
Ae: Analysis & emulation

53

r2m2_Ae.so - Analysis[0x00000000]> pd 10,=< 0x00000000,==< 0x00000004||
0x00000008||
0x0000000a||
0x0000000c||
0x0000000e||
0x00000010||
0x00000012||
0x00000014||
0x00000016

08d80100
18df0800
0000
0000
0000
0000
0000
0000
0000
0000

known destinations

JMP 0x100
JMP 0x8E2
MOV R0, R0
MOV R0, R0
MOV R0, R0
MOV R0, R0
MOV R0, R0
MOV R0, R0
MOV R0, R0
MOV R0, R0.----------------------------.
| 0x100 ;[gb]|| (fcn) fcn.00000100 240|| DI|| MOV R9, 40|| STC R9, CFG|| MOV R9, 0|| STC R9, RPE|| LW R11, (0x41A000)|| AND3 R12, R11, 0x1000|| AND3 R11, R11, 0x20|
| SRL R11, 0x5|| SRL R12, 0xB|| OR R11, R12|| BEQI R11, 0x3, 0x1D2;[ga] |`----------------------------'f t| || '---------------.
.-------------'|||.---------------------------.
.--------------------.
| 0x120 ;[gd]|| 0x1d2 ;[ga]|| BEQI R11, 0x2, 0x1F6;[gc] || MOVH R11, 0x8000|`---------------------------'| MOVU R2, 0x412034 |f t| MOVU R1, 0x412010 || || MOVH R12, 0xC0|
| || MOVU R4, 0x605138 || || MOVU R3, 0x412000 || || SW R4, (R3)|
| || MOVU R3, 0x412014 || || SW R12, (R3)|
| || SW R4, (R1)|
| || SW R11, (R2)|

callgraph54

r2m2_Ae.so - emulation[0x00000000]> e asm.emu=true[0x00000000]> aei[0x00000000]> pd 2,=< 0x00000000
08d80100,==< 0x00000004
18df0800[0x00000000]> aes[0x00000100]> pd 2;-- pc:0x00000100
0070
0x00000102
2859[0x00000100]>

JMP 0x100
JMP 0x8E2; pc=0x100 -> 0x59287000; pc=0x8e2 -> 0x8df00

DI
MOV R9, 40; psw=0x0; r9=0x28

JMP emulation with ESIL
55

Reversing With Strings

56

Goalsauto-name functions
using errors format strings

high-level knowledge
using strings as hints

57

Auto-naming Functions[0x00c679b2]> pd 40x00c679b2
0x00c679b6
0x00c679ba
0x00c679be

38d150ce
2dd250ce
01c3b300
89deb0fa

MOVU R1, 0xCE5038
MOVU R2, 0xCE502D
MOV R3, 179
BSR fcn.printf; "[TEL] (error) %s:%d "; "Initialize"

typical error message pattern

strategy
1. assemble MOVU R1,<error format string address>
2. search corresponding bytes
3. disassemble and check the MOVU, MOVU, MOV, BSR pattern
4. find the closest function prologue
58

~150
functions automatically named59Telnet Related Functions$ flashre naming dump_w03.bin --offset 0xc00000
af TEL.Accept 0xc67a46
af TEL.Initialize 0xc6795c
af TEL.ClearSdBuffer 0xc67bfa
af TEL.Reply 0xc80040
af TEL.SendOptionCode 0xc67b86
af TEL.ProcessCharacter 0xc7fede
af TEL.TELNET_CreateResHistory 0xc7fa92
af TEL.WaitForTermination 0xc8019e
af TEL.Execute 0xc8013e
af TEL.SendLoginMessage 0xc67c4a

auto-named telnet functions

TEL.SendLoginMessage().--------------------------------.
| 0xc67c4a ;[gc]|| (fcn) TEL.SendLoginMessage 202 || ADD SP, -20|| LDC R0, LP|| SW R8, 0x10(SP)|| SW R7, 0xC(SP)|| SW R6, 0x8(SP)|| SW R0, 0x4(SP)|| MOV R7, R1|| BSR TEL.ClearSdBuffer;[ga]|| MOV R12, -1|| BEQ R0, R12, 0xC67CA4;[gb]|`--------------------------------'f t| || '-------------------------.
.--------------'|||.-------------------------.
|| 0xc67c60 ;[gg]||| MOVU R1, 0xCCF586||| BSR fcn.strlen;[gd]||| MOV R8, R0||| MOVU R1, 0xCE4FEC||| BSR fcn.strlen;[gd]||| ADD3 R8, R0, R8||| MOVU R1, 0xCE5002||| BSR fcn.strlen;[gd]||| ADD3 R8, R0, R8||| ADD3 R1, R8, 0x1||| BSR 0xC7512E;[ge]||60High-Level Knowledge

use strings as RE hints
discover functions manipulating specific strings

strategy
1. assemble MOVU R1,<string address>
2. find the closest function prologue61

$ flashre hints dump_w03.bin --offset 0xc00000 update
0xc20580 0xc20c82 update -f %s====
0xc96870 0xc969c6 FwUpdate error f_open(%s) ret=%d\n0xc96870 0xc96a36 \nUpdate fail. Unexpected target name.\n0xc96870 0xc96b3e \nUpdate reserved.\n====0xc9b502 0xc9b51a USAGE: sd update filename
0xc9b502 0xc9b65a \nUpdate fail. Unexpected target name.\n0xc9b502 0xc9b722 \nUpdate success.\n0xc9b502 0xc9b780 Update error.(checksum)\nupdate hints
62

Two RE targets
1. update mechanism
discover the binary format

2. configuration parser
parameters effects
understand commands

63

Update Mechanism

64

Update Header
32 bytes longstarts with “FLASHAIR”
defines five different types
MAIN2, BOOT, MAC, RF, USRPRG$ flashre update fwupdate.fbn###[ FlashAir Update Header ]###
card
= 'FLASHAIR'
type= 'MAIN2'
unk0= '\x01\x02\x03\x04'
unk1= 0x1c7e
unk2= 0x1f00250f
checksum = 0xc2
unk3
= 0x0
length= 1047568

one-byte checksum
sum of all data bytes modulo 255
65

SPI Memory Map Array at 0xceff28
Type

Content

Address

Size

BOOT

MeP code

0x000000

64 KB

MAIN2

MeP code

0x010000

1.8 MBMAC

MAC address ...

0x1d0000

24 KB

RF

starts with “2230”

0x1d800032 KB

USRPRG

full of 0xFF bytes

0x1e0000

128 KB

66

Reversing the Configuration Parser

67

parse_config() - 0xc15f4e
configure values
APPSSID, APPNETWORKEY ...

start daemons
TELNET, DHCP_Enabled ...

execute commands
COMMAND

68

Starting the Telnet Daemon[0x00000000]> s TEL.Start[0x00c6784c]> pd 12/ (fcn) TEL.Start 28||
0x00c6784c||
0x00c6784e||
0x00c67850||
0x00c67852||
0x00c67856||
0x00c6785a||
0x00c6785c||
0x00c6785e||
0x00c67860||
0x00c67862\`=< 0x00c67864
0x00c67868

LDC R0, LP
ADD SP, -4
SW R0, (SP)MOVU R1, 0xCE500D
BSR fcn.printf
MOV R2, 0
MOV R1, 34
LW R0, (SP)ADD SP, 4
STC R0, LP
JMP 0x812258
RET; "TELNET start"

jumps to 0x812258

first argument is 34

69execute_command() - 0xc29cce
two functions access an array at 0xc9ff18
is_valid() at 0xc29462
is_authorized() at 0xc29078

command_t structures array
47 elementsfunction address and nametypedef struct command {char* name;void* function;
char* default_argument;
char* long_name;char* help;
int level;} command_t;
70

15 new commands- >8 current
isdio
dns
userpgwsd
rot
lua
telnetupdatesntpc
buf- >8 tz
rfic
level
sysclkpspw
pio
netlogdcmes
factory

71

The userpg commandjumps to 0x812258
also called in parse_config()
first argument was 34.--------------------.
| 0xc26208 ;[gb]|| (fcn) cmd.userpg 8 ||cmd.userpg ();|| MOV R2, 0|| MOV R1, 33|| JMP 0x812258;[ga] |`--------------------'
072

Identifying the OS73

More Error Strings!
$ rabin2 -zzz dump_w03.bin |egrep '[a-z]{3}_[a-z]{3} error'
0x0000dc60 set_flg error(%04x) in fb_sio_isr\n0x0000e644 chg_ilv error(%04x) in fb_sio_init\n0x0000e668 wai_flg error(%d) in fb_getc\n0x000cff0c chg_ilv error(%04x) in fb_sio_init\n0x000cff30 wai_flg error(%d) in fb_getc\n0x000e9730 wup_tsk error(%d) in fb_sio_isr\n0x000e9751 set_flg error(%04x) in fb_sio_isr\nwup_tsk() looks promising!
74

http://www.tron.org/wp-content/themes/dp-magjam/pdf/t-kernel_2.0/html_en/task_dependent_synchronization_functions.html

75

wup_tsk - wake up a task in T-KernelSee https://www.tron.org

The Real-time Operating system Nucleus
Japanese RTOS
launched in 1984

specifications maintained by the TRON Forumtypical version: MITRON (Micro Industrial Tron)many implementations
T-Kernel, TOPPERS, RTEMS, UDEOS, PrKERNEL, DryOS, …
~150 supported architectures
76

Where is it Used?

Casio Exilim EX-FC100

Canon 5D Mark III

Joy-ConAsteroid Explorer Hayabusa

77See https://www.tjsys.co.jp/embedded/netnucleus/index_j.htm

Which TRON Implementation?

$ rabin2 -zzz dump_w03.bin |grep -i nucleus
0x000a4103 NetNucleus WPS version %d.%d.%d0x000eafcd NetNucleus WPS version %d.%d.%dNetNucleus - IP stack from Toshiba for UDEOS

78

See http://www.tron.org/wp-content/themes/dp-magjam/pdf/specifications/en_US/TEF024-S001-04.03.00_en.pdf

Reading μITRON 4.0 Specification[Differences from the µITRON3.0 Specification]
The task state names are now in the adjective form. They have been renamed
from RUN to RUNNING, from WAIT to WAITING, from SUSPEND to
SUSPENDED, and from WAIT-SUSPEND to WAITING-SUSPENDED. [..]

$ rabin2 -zzz dump_w03.bin |egrep 'RUN|WAIT|SUSPEND'
0x000d7574 WAITING-SUSPENDED
0x000d7586 SUSPENDED
0x000d7590 WAITING
0x000d759e RUNNING
79

Game Plan☐
X memory dump☐
X architecture
X☐Operating
System☐ execution vector

80Solving the 0x812258() Mystery!

81

TEL.Init() - 0xc6786aa single match in the dump
search result at 0xd08ee4

used in a potential tasks array
located at 0xd08c50[0x00c00000]> /x 6a78c600 # Address of TEL.Init()
Searching 4 bytes in [0xc00000-0xe00000]
hits: 10x00d08ee4 hit0_0 6a78c600

searching TEL.Init() address82

34 tasks identified
elements of 20 bytes

0x812258() is sta_tsk()
move task to READY state[0xc0000]> (tsk_addr, ?s 0xd08c50 0xd08c50+0x14*33 0x14)[0xc0000]> pv @@= `.(tsk_addr)`
0x00c27aa6 # 1-- >8 -0x00c3a152 # 21 - DHCP server-- >8 -0x00c30560 # 24 - DNS server 53/UDP
0x00c3062e # 25 - Bonjour server 5353/udp-- >8 -0x00c12f42 # 27 - calls parse_config()-- >8 -0x00c26218 # 33 - userpg()
0x00c6786a # 34 - TEL.Init()tasks addresses
83

The userpg task - 0xc26218

checks that the USRPRG section (0x1e0000) is not 0xff
jumps 0x1e0000
calls the function stored at R084

Game Plan☐
X memory dump☐
X architecture
X☐Operating
System☐execution
vectorX

85

Thanks to JPCERT/CC,
Toshiba is aware ofthese results since June.
86

Putting Everything Together

1. build a fake USRPRG update
2. write it to the card
3. call update -f usrprg.bin
4. call userpg

87

Project Outlook
identify remote vulnerabilities
DHCP, HTTP, 802.11, ...

SDK
gcc supports MeP

new firmwares
encrypt or hide pictures88Black Hat Sound Bytes
unexpected
a Japanese SoC and a Japanese OS

original
detailed FlashAir analysis and code execution

reproducible
open-source tools & addresses published89

Tools!
guedou/flashre
guedou/r2m2
radare/radare2
cea-sec/miasm
cea-sec/sibyl
sgayou/rbasefind
guedou/jupyter-radare2
guedou/r2scapy

90

> update -f thank_you.update
update -f thank_you.update
F:o--------------------------------+o> userpg
userpg+user_task######## ##
##
###
##
## ##
##
##
##
##
## ##
###
## ##
##
##
##
## ##
## #### ## ## ############# #### ## ## ## ########### ######### ## #### ## ##
##
##
## ##
## ##
### ##
##
##
##
## ##
## ##
## ##
##

##
## ####### #### ###### ## #### #### ####
####
##
## ##
## ####
##
##
## ##
## ##
##
##
## ##
##
##
##
## ##
## #################### ####

-user_task

91Few More Things

92Magic Lantern W-03
CPU architecture
memory dump

Hackaday W-01

Seesa wiki W-03+

commands

new commands
new features

2015

2016

CPU architecture

2017

2018
Operating System

Update Mechanism93

$ R2M2_ARCH=mepl r2 -a r2m2 fwupdate.fbn -m 0xc0ffe0[0x00c0ffe0]> s $$ + 32
[0x00c10000]> pd 5`==< 0x00c10000
08d80101
JMP 0x10100`=< 0x00c10004
28d80000
JMP 0x4
0x00c10008
5b7c
LDC R12, CFG
0x00c1000a
101c
OR R12, R1
0x00c1000c
597c
STC R12, CFG[0x00c10000]>

mapping fwupdate.fbn correctly94parse_config() - 0xc15f4e
0x00c1633e
0x00c16342
0x00c16344[..]

41d1d1c96002
a9d86a06

MOVU R1, 0xC9D141
MOV R2, R6
BSR fcn.strcmp; “APPSSID”; parameter

testing a parameter name[0x00c1633e]> (print_string, ps @ `pd 1~[4]`)[0x00c1633e]> .(print_string)
APPSSID

extracting the parameter name95

Listing Undocumented Parameters
1. search the MOVU, MOV, BSR pattern
2. print the string[0x00c15f4e]> e search.from=$FB[0x00c15f4e]> e search.to=$FE[0x00c15f4e]> e cmd.hit=.(print_string)[0x00c15f4e]> /x ..d1....6002c.d

call command on hit
96

~30 documented~70 extracted

AGINGTIMEAPMODEAPPAUTOTIMEAPPCHANNEL
APPDPMODE
APPEXT
APPINFOAPPMODEAPPNAMEAPPNETWORKKEYAPPSSID
APPTYPE
AP_PS_AGING
AP_UAPSD_Enabled
Alternate_DNS_Server
BRGNETWORKKEYBRGSSID
BRGTBLTIME
CID
CIPATHCOMMAND[..]
SD_SYNC
SHAREDMEMORYSTAMACSTANUM
STA_RETRY_CT
STEALTH
Subnet_Mask
TCP_DEFAULT_TIMEOUTTCP_MAX_RETRANSTELNET
TIMEZONEUDP_CHECKSUMUPDIRUPLOADUPOPTVERSION
WEBDAVWLANAPMODEWLANSTAMODE
XPMODE
97

Executing Commands
command(char* command) # 0xc29e1c
strcpy(0x81d6d8, command)parse_argc_argv(0x81d6d8) # 0xc29bfc
execute_command(0x81d6d8) # 0xc29cce
memset(0x81d6d8, 0x284).------------------------------.
| 0xc29e1c ;[gg]|| (fcn) fcn.command 120|| LDC R0, LP|| ADD SP, -4|| SW R0, (SP)|| MOV R2, R1|| MOVU R1, 0x81B6D8|| BSR fcn.strcpy;[gc]|| MOVU R2, 0x81B6D8|| MOVU R1, 0xCCF6BE|| BSR fcn.printf;[gb]|| MOVU R1, 0x81B6D8|| BSR fcn.parse_argc_argv;[gd] || MOVU R1, 0x81B6D8|| BSR fcn.execute_command;[ge] || MOVU R1, 0x81B6D8|| MOV R2, 0|| MOV R3, 284|| BSR fcn.memset;[gf]|| MOVU R2, 0xCCF6C2|| MOVU R1, 0xCCF6C5|| LW R0, (SP)|| ADD SP, 4|| STC R0, LP|| JMP fcn.printf;[gb]|98`------------------------------'

Listing All Available Commands[0x00000000]> pv @@= `?s 0xc9ff18 0xc9ff18+24*47 24` > offsets.txt

extracting command_t offsets[0x00000000]> ps @@= `cat offsets.txt`

printing commands99$ rabin2 -zzz dump_w03.bin |grep -f mitron4-service_calls.txt
0x0000dc60 set_flg error(%04x) in fb_sio_isr\n0x0000e668 wai_flg error(%d) in fb_getc\n0x0009cbdc Error:FileTask wai_flg %d\n0x0009cf40 ABORT error rel_wai (%d)\n0x000a4266 snd_mbx
0x000a4298 snd_mbx\n0x000a42d0 snd_mbx\n0x000cff30 wai_flg error(%d) in fb_getc\n0x000d4dad !!! AUTH:isnd_mbx
0x000d4e4f rcv_mbx\n0x000d660c isnd_mbx
0x000d95dc rcv_mbx
0x000dbee4 !!! ASSOC:isnd_mbx
0x000dc86a !!!!! ctrl_snd_mbx no memory\n0x000e6060 ipsnd_dtq
0x000e6a45 !!! BAS:isnd_mbx\n0x000e8452 !!! SCAN:isnd_mbx
0x000e9730 wup_tsk error(%d) in fb_sio_isr\n0x000e9751 set_flg error(%04x) in fb_sio_isr\n0x000f03b1 snd_mbx\nidentifying new mitron Service Calls

100

See https://en.wikipedia.org/wiki/TRON_project“ITRON is the most used OS in 2003”
Wikipedia

101