Recently I was lucky to come across one of Transcends WiFi enabled SD memory cards. I already wrote something on how to access it easily; this time I write about some interesting findings within the shipped SDs Linux.

What is it about

Transcend produces SD memory cards with a special feature: Wireless network connections. Within the size of an average SD card, there is not only 32 GB of flash memory but also an embeded system (which is running some linux) and a wireless network module. Really, everything within a normal-sized SD card. Early adventures were documented in transcend-wifi-ftpd.html. I started sniffing through the system using the telnet interface. Insecure? Kind of, as the WiFi is secured. Thus, whoever guesses the WiFi-key will be able to eavesdrop my telnet session. Ok, let's digg into the system!

Note: I will referr to the storage available to the camera/pc via SD interface as SD storage. It is mounted as /mnt/sd from within the system.

The Hardware

I admit -- I was not able to resist the urge to crack-open the SDs plastic shield. Inside I found these major ICs:

The System

One of the first things to notice is the remarkable design decision to double-mount the physical SD-card memory dedicated to camera usage. It is attached both to the internal Linux system as well as to the external camera connectors. VFAT was one of the file systems capable of such usage, wasn't it?
Oh, let's have a look at the system details (I use an external busybox image which has been dumped onto the payload storage and thus is involved as /mnt/sd/busybox-armv7l:

# /mnt/sd/busybox-armv7l uname -a
Linux (none) 2.6.32.28 #130 PREEMPT Mon Feb 18 13:54:18 CST 2013 armv5tejl GNU/Linux
# cat /proc/cpuinfo
Processor       : ARM926EJ-S rev 5 (v5l)
BogoMIPS        : 421.06
Features        : swp half fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant     : 0x0
CPU part        : 0x926
CPU revision    : 5

Hardware        : KeyASIC Ka2000 EVM
Revision        : 0000
Serial          : 0000000000000000
# cat /proc/meminfo
MemTotal:          29824 kB
MemFree:           16552 kB
Buffers:              24 kB
Cached:             9004 kB
SwapCached:            0 kB
Active:             2924 kB
Inactive:           6776 kB
Active(anon):        672 kB
Inactive(anon):        0 kB
Active(file):       2252 kB
Inactive(file):     6776 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           696 kB
Mapped:              400 kB
Shmem:                 0 kB
Slab:               2028 kB
SReclaimable:       1172 kB
SUnreclaim:          856 kB
KernelStack:         280 kB
PageTables:          120 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       29824 kB
Committed_AS:       7260 kB
VmallocTotal:     825344 kB
VmallocUsed:         324 kB
VmallocChunk:     824240 kB
# cat /proc/version
Linux version 2.6.32.28 (root@ubuntu-desktop) (gcc version 4.5.2 (Sourcery G++ Lite 2011.03-42) ) #130 PREEMPT Mon Feb 18 13:54:18 CST 2013
# dmesg
(192-96-1)
console [ttyS0] enabled
Mount-cache hash table entries: 512
NET: Registered protocol family 16
bio: create slab  at 0
cfg80211: Calling CRDA to update world regulatory domain
NET: Registered protocol family 2
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
ttyS0 at MMIO 0xa0004000 (irq = 1) is a KA2000
msgmni has been set to 58
loop: module loaded
TCP cubic registered
NET: Registered protocol family 17
lib80211: common routines for IEEE802.11 drivers
lib80211_crypt: registered algorithm 'NULL'
ka2000_sdhc: module license 'Proprietary' taints kernel.
Disabling lock debugging due to kernel taint
(0>0)switch_modules
max_blk_size=512, max_blk_count=8, max_req_size=32768
init bomb irq
req irq 40 (1000000)
req irq 43 (40)
req irq 41 (43)
ka_sdhc_drv_init
bw = 22
mmc0: new SDHC card at address b368
mmcblk0: mmc0:b368 CAR 30.2 GiB
 mmcblk0:bootsec @ 2000
 p1
FAT sec 724 sz 3c6e #2 rtdir 8000 csz 20
FAT sec 724 sz 3c6e #2 rtdir 8000 csz 20
sdio wakeup
mmc1: queuing CIS tuple 0x01 length 3
mmc1: queuing CIS tuple 0x1a length 5
mmc1: queuing CIS tuple 0x1b length 8
mmc1: queuing CIS tuple 0x14 length 0
mmc1: queuing CIS tuple 0x80 length 1
mmc1: queuing CIS tuple 0x81 length 1
mmc1: queuing CIS tuple 0x82 length 1
mmc1: new SDIO card at address 0001
AR6000: configuration opcode 7 is only used for RTOS systems, not Linux systems
ath6k/AR6003/hw2.1.1/athwlan.bin firmware will be loaded
AR6K: ** HIF layer does not support scatter requests (17)
wmi_control_rx() : Unknown id 0x101e
channel hint set to 0
Add Filter 0 = 01:00:5e:00:00:01
Keep Filter 0 = 01:00:5e:00:00:01
Keep Filter 0 = 01:00:5e:00:00:01
(0>1)dcim c 3 @a020, f:2724 (off 4e4808)
Folder: 199_WIFIWSD00003 (5f393931 49464957)
Img1: WSD00003 (30445357 33303030 sz 79cdh)
user_dir:(5f333231 20505446)(00000000 00000000)
ctrlimg c 1d36c2 @3a77800, f:6191 (off c32304)

3 c 1d36c6-1d36c8 @3a77880 f:6191(o:70)
fat cnt 2, x0, pBuf1 c17f2400, pBuf2 0(0)
misc c 1d36c3 @3a77820
bomb reg2 3a77820 - 3a77825
bomb reg 2724 - 6392
st 1d3681, 1:70, 2:0, 3:0, 4:0, 5:0
bomb reg 2724 - 6392
(1>0)(0>1)dcim c 3 @a020, f:2724 (off 4e4808)
Folder: 199_WIFIWSD00003 (5f393931 49464957)
Img1: WSD00003 (30445357 33303030 sz 79cdh)
user_dir:(5f333231 20505446)(00000000 00000000)
ctrlimg c 1d36c2 @3a77800, f:6191 (off c32304)

3 c 1d36c6-1d36c8 @3a77880 f:6191(o:70)
fat cnt 2, x0, pBuf1 c17f2400, pBuf2 0(0)
misc c 1d36c3 @3a77820
bomb reg2 3a77820 - 3a77825
bomb reg 2724 - 6392
st 1d3681, 1:70, 2:0, 3:0, 4:0, 5:0
bomb reg 2724 - 6392
(1>0)(0>1)dcim c 3 @a020, f:2724 (off 4e4808)
Folder: 199_WIFIWSD00003 (5f393931 49464957)
Img1: WSD00003 (30445357 33303030 sz 79cdh)
user_dir:(5f333231 20505446)(00000000 00000000)
ctrlimg c 1d36c2 @3a77800, f:6191 (off c32304)

3 c 1d36c6-1d36c8 @3a77880 f:6191(o:70)
fat cnt 2, x0, pBuf1 c17f2400, pBuf2 0(0)
misc c 1d36c3 @3a77820
bomb reg2 3a77820 - 3a77825
bomb reg 2724 - 6392
st 1d3681, 1:70, 2:0, 3:0, 4:0, 5:0
bomb reg 2724 - 6392
(1>0)
# mount
proc on /proc type proc (0)
/dev/mtdblock0 on /mnt/mtd type jffs2 (0)
none on /dev/pts type devpts (mode=0622)
/dev/mmcblk0p1 on /mnt/sd type vfat (shortname=winnt,iocharset=utf8,rw)
Remarkable: The CPU features Java and -- one of the first lines emitted by dmesg referrs to a serial console. Make that a ToDo as it would be nothing else than the possibility to make my ol' Siemens TC20 monochrome VT220 terminal a wireless device featuring telnet to the world! So much to do, so little time :(
Going on, there is a quite usual embedded system scenario: Plenty of binarys which are only links to a busybox. Semmingly, the folks at transcend have designed their very own busybox for this device as it features some non-standard applets:
# /bin/busybox
BusyBox v1.18.5 (2013-02-25 15:18:08 CST) multi-call binary.
Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.

Usage: busybox [function] [arguments]...
   or: busybox --list[-full]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        ash, bash, boa, boa_indexer, bootchartd, bunzip2, buzzer, bzcat, cat, chmod, 
	cmd_server, cp, date, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,
	dumpleases, echo, egrep, env, fgrep, find, fs_info, ftpd, ftpget, ftpput, 
	gen_filelist, get_authfile, grep, hostname, ifconfig, inetd, init, insmod,
	instant_setupd, instant_upload, instant_upload_clean, iu_progressd, iwconfig,
	iwevent, iwlist, iwpriv, kcard_app, kcard_cmd, kcard_startup, kill, linuxrc, ln,
	logger, logread, ls, lsmod, macaddr, mkdir, mount, mv, nslookup, perl, ping,
	pkill, ps, pwd, readahead, rm, rmdir, rmmod, route, sh, sleep, sync, syslogd,
	tcpsvd, telnetd, thumbNail, thumbnail_video, touch, tscmd, tslist, udhcpc,
	udhcpd, udpsvd, umount, unzip, wget, wifi_connect_router, wifi_download,
	wifi_filelist, wifi_ftp_server, wifi_ftp_upload, wifi_get_apconfig,
	wifi_get_config, wifi_get_config_real, wifi_quick_send, wifi_set_config,
        wifi_upload, xargs
Probably for reasons of sizing, some of the traditional applets have been removed -- the absence of less is the most painful of them to me as I tend to digg into almost everything using this tool.

Booting up

During Bootup, /etc/init.d/rcS is involved. I try to reconstruct, what it does.

The configuration files

The traditional config file directory /etc features some interesting pieces of information. There is the /etc/instant_upload.conf containing an unencrypted Google+-Account; anyhow, main configuration entries are stored in /etc/wsd.conf. It looks like this:

# cat wsd.conf
Config-State : 0
Login-enable :
Login-name : admin
Login-password : admin
[LANGUAGE]
English
[AP]
AP_ACCOUNT : 3
SSID :
Key :
SSID :
Key :
SSID :
Key :
[FTP]
FTP Path :
User Name :
Password :
[Wi-Fi Setting]
Auto WIFI : Yes
Auto OFF : 0
Auto Mode : DS
WIFISSID : WIFISD
Host WPA2 Key : 12345678
Host WPA2 Switch : on
Host WPA2 Key Backup : 12345678
Channel : auto
Domain Name : .
My IP Addr : 192.168.11.254
Target IP Addr : 192.168.1.1
Receiver IP Addr : 192.168.1.51
[Instant Setup]
GPlus-Enable : NO
GPlus-SSID : G+_WIFISD
GPlus-Key : 12345678
GPlus-User :
GPlus-Password :
[MISC]
Buzzer Mode : Disable
Within this file, we find not only the complete WIFI-setup but also all login credentials used with this piece of storage. Looking around, I found something remarkable:
# cat /etc/json/basic_dev_info.json
{
        "protocol_version":    1,
        "manufacturer":        "Transcend",
        "device":              "WIFISD",
        "serial":              "0000-00000",
        "firmware":            "V133",
        "user_email":          "transcendrd@gmail.com"
}
What is this? Where is it used? I currently have no clue. According to strings and grep this file is referenced from Transcend's customized Busybox. Up until now, I did not feel the urge to reverse-engineer this special binary. If someone feels encouraged to do so -- feel free to get in touch with me.

The Scripts

The system comes with a bunch of shell scripts:

# cd / ; find * | egrep '\.sh$'
usr/bin/wifi_countdown.sh
usr/bin/bodyguard.sh
usr/bin/gen_wpa4json.sh
usr/bin/gp_find_album.sh
usr/bin/dhcpd_notify.sh
usr/bin/ap_iu.sh
usr/bin/ap_fu.sh
usr/bin/ap_client.sh
usr/bin/is_post.sh
usr/bin/gen_is_config.sh
usr/bin/kcard_app.sh
usr/bin/ap_is.sh
usr/bin/boa_auth.sh
usr/bin/gp_config.sh
usr/bin/gp_upload_iu.sh
usr/bin/factory_reset.sh
usr/bin/wifi_shutdown.sh
usr/bin/auto_off.sh
usr/bin/fb_login.sh
usr/bin/test_wireless1.sh
usr/bin/gp_login.sh
usr/bin/is_wpa_config.sh
usr/bin/gp_upload.sh
usr/bin/ap_server.sh
usr/bin/iu_progressd.sh
usr/bin/reset_upload_record.sh
usr/bin/gen_hostapd_config_fu.sh
usr/bin/system_clean.sh
usr/bin/gp_get_album_list.sh
usr/bin/gp_validate_token.sh
usr/bin/gp_create.sh
usr/bin/test_wireless2.sh
usr/bin/gen_boa_passwd.sh
usr/bin/unzip.sh
usr/bin/gen_hostapd_config.sh
usr/bin/notify_progressd.sh
usr/bin/copy_control_images_to_nor.sh
usr/bin/wifi_watch.sh
usr/bin/control_create.sh
usr/bin/keepalive.sh
usr/bin/gp_gen_hostapd_config.sh
usr/bin/get_config_json.sh
usr/bin/notify_iu.sh
Following my interest, I started with a look into fb_login.sh, assuming some magic Facebook related stuff. Not quite -- more the opposite:
# cat /usr/bin/fb_login.sh
#!/bin/sh

tmpstr=`cat /etc/instant_upload.conf  |grep "GPlus Name"`
username=${tmpstr:13:${#tmpstr}}
tmpstr=`cat /etc/instant_upload.conf  |grep "GPlus Password"`
password=${tmpstr:17:${#tmpstr}}

echo "user = $username, password = $password"
if [ -z "$username" -o -z "$password" ]; then
        echo "Username $username or passwd $password empty"
        echo "Error=Bad username password" > auth.inc
        exit 1
fi

curl https://www.google.com/accounts/ClientLogin \
-k \
-s \
--data-urlencode Email="$username@gmail.com" --data-urlencode Passwd=$password \
-d accountType=GOOGLE \
-d "GData-Version:  2"  \
-d source=Google-cURL-Example \
-d service=lh2 > auth.inc

echo "user=$username" >> auth.inc
It is the upload script to throw some content to Google. Seemingly, in /etc/instant_upload.conf there is unencrypted account information. Which is no problem as long as the SD card is not given to the wrong hands. Or as long as you do not care about who knows your login credentials.
Interestingly, gp_login.sh and fb_login.sh do the same. Maybe there was a planned cooperation with FB which got cancelled in the last moment.
Following this lead, let's look into gp_upload.sh:
# cat /usr/bin/gp_upload.sh
#!/bin/sh

. /etc/auth.inc

if test $# -lt 2 ; then
        echo "Need 2 argumets!\n Syntax: upload.sh [ALBUM] [FILE]\n"
        exit 0
fi
echo "Upload $2 to Album $1"
album="$1"
photo="$2"

curl \
    --request POST \
    --data-binary "@$2" \
    --header "Slug: $album" \
    --header "Content-Type: image/jpeg" \
    --header "Authorization: GoogleLogin auth=$Auth" \
    "https://picasaweb.google.com/data/feed/api/user/$user/album/$album" \
    -o log.txt -k -s

if [ $? -ne 0 ] ; then
        exit 2
fi

Ok, nothing really surprising, there. Going on, there is a gp_validate_token.sh:
# cat usr/bin/gp_validate_token.sh
#!/bin/sh

JSHON_EXE="/bin/jshon"

if [ ! -f /etc/auth.inc ]; then
        echo "Can't find auth file.!"
        exit 1;
fi

. /etc/auth.inc


if [ ${Auth:0:4} != "ya29" ];then
# Not support to validate CleintLogin auth
        exit 0;
fi
curl "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$Auth" \
-L -k \
-s \
-o log.txt

if [ $? -ne 0 ] ; then
        echo "http error\n"
        exit 2
fi

output=`${JSHON_EXE} -e error < log.txt`
if [ $? -eq 0 ]; then
        echo ${output//\"/}
        exit 1
fi
No big surprise, either.

The quick-and-dirty way to exploring the system

Use the almighty /mnt/sd/autorun.sh to do almost everything on boot. Instead of the painful networking, you can just cp everything interesting onto the SD storage visible to the PC/camera on SD bootup. Backdraw: It does not feel half as cool as browsing a live system on a SD card ;)
You should not try to cp /mnt/sd to /mnt/sd.

Mid-Conclusion: Sweet poison

It should be fairly easy to make this little device the perfect poisoned gift in just three easy steps. Prerequisite: You need to know your enemies WiFi passphrase. Which should be fairly easy if your enemy is your ex-boyfriend or your ex-girlfriend. Who changes WPA passphrase after dumping the (now) insignificant other? If that is out of reach, you can still walk by every now and then, providing your own WiFi and hoping that the SD will be powered. Ah, so many possibilities. And I haven't even started to mention directed antennas.

Enjoy.

Lighting the black box?

Up to this point, the WiFi SD card was treated as a black box. Fortunately, Transcend offers the WiFi SD source code on their site at http://de.transcend-info.com/Support/DLCenter/DL_Click.asp?getFile=/Files/Driver/WIFISD_GPL_release_20131219.zip -- 164 MB of fun.
In order to keep this article somewhat focused, I will restrain myself to finding out, what the E-Mail-Adress transcendrd@gmail.com is used for.

Of course, just from reviewing the code and without examination of the binaries, there is no way to see if the code published by Transced is related to the binaries on the card...

Talking of which, there is some discrepancy:

# /mnt/sd/busybox-armv7l strings /bin/busybox | grep basic_dev_info.json
/etc/json/basic_dev_info.json
is what I see on the SD. The source code however does not reflect this:
[ad001@glas ~/tmp/wifisd/GPL_release_20131219/bbox]$ cat `find busybox-1.20.2_KA/`  | grep /etc/json/basic_dev_info.json
[ad001@glas ~/tmp/wifisd/GPL_release_20131219/bbox]$ echo $?
1
Okaaay... I probably need the source code for the firmware acutally running on my disk... so ATM it stays a black box.

This article as PDF down/tr-wifi-2.pdf.

Stichworte:


Impressum