After recently having stated in a Tweet that Sonos speakers expose a web interface, I just wanted to add some information here. I first found this interface about 4..5 years ago, when a good friend bought himself a Sonos system and I decided to just run a quick scan. Back then there wasn’t a lot of information on this interface online, which has changed over the past few years. Today, if you search for “sonos web interface” or “sonos hidden interface” you’ll finde various information, just as published here.

The Interface

The interface can be found on port 1400/TCP. The service listening on this port introduces itself as Linux UPnP/1.0 Sonos/45.1-56150 (ZPS12) Direct access to http://sonos-speaker:1400 will return a 403 . The first base access you’ll find is /status (be sure to not have a slash on the end, you want the file, not the folder).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <head><title> Diagnostics </title></head> <body> <h2 align= "center" > Options </h2> <a href= /status/zp > zp </a><br> <a href= /status/enetports > enetports </a><br> <a href= /status/VERSION > VERSION </a><br> <a href= /status/proc/ath_rincon/status > proc/ath_rincon/status </a><br> <a href= /status/ifconfig > ifconfig </a><br> <a href= /status/showstp > showstp </a><br> </body></html>

/status/zp

The zp page contains an XML with some system information.

I decided to remove the HouseholdControlID

It uses a style sheet located at /xml/review.xsl .

<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/xml/review.xsl"?> <ZPSupportInfo><ZPInfo><ZoneName> X </ZoneName><ZoneIcon> x-rincon-roomicon:living </ZoneIcon><Configuration> 1 </Configuration>

A copy of the XSL can be found here.

/status/enetports

/status/version

<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/xml/review.xsl"?> <ZPSupportInfo><File name= '/VERSION' > 45.1-56150 </File></ZPSupportInfo>

/status/proc/ath_rincon/status

contents of /proc/ath_rincon/status Debug info for INFRA mode at 3290 Mode: INFRA (station) Operating on channel 2422 Home channel is 2437 RF Chains: RX:2 TX:2 RF Chainmask: RX:0x03 TX:0x03 Max Spatial Streams: RX:2 TX:2 Noise Floor: -100 dBm (chain 0 ctl) Noise Floor: -101 dBm (chain 1 ctl) Noise Floor: -100 dBm (chain 2 ctl) PHY errors since last reading/reset: 16774 OFDM ANI level: 1 Ch11 Spur Immunity Level: 0 HAL Reset Failures: cnt: 0 last: 0 Region: 2

/status/ifconfig

running /sbin/ifconfig ath0 Link encap:Ethernet HWaddr 94:9F:3E:F6:28:22 inet6 addr: fe80::969f:3eff:fef6:2822/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:199 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Interrupt:155 Memory:90d40000-90d60000 br0 Link encap:Ethernet HWaddr 94:9F:3E:F6:28:22 inet addr:192.168.101.206 Bcast:192.168.101.255 Mask:255.255.255.0 inet6 addr: fe80::969f:3eff:fef6:2822/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:236714 errors:0 dropped:2009 overruns:0 frame:0 TX packets:216569 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:43255047 (41.2 MiB) TX bytes:19601452 (18.6 MiB) eth0 Link encap:Ethernet HWaddr 94:9F:3E:F6:28:22 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:102 errors:0 dropped:0 overruns:0 frame:0 TX packets:102 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:34072 (33.2 KiB) TX bytes:34072 (33.2 KiB)

<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/xml/review.xsl"?> <ZPSupportInfo><Command cmdline= '/sbin/ifconfig' > [..] </Command></ZPSupportInfo>

/status/showstp

<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/xml/review.xsl"?> <ZPSupportInfo><Command cmdline= '/usr/sbin/brctl showstp br0' > br0 STP is disabled for this interface </Command></ZPSupportInfo>

Yes this is Spanning Tree Protocol :-)

/support/review

This page gives us a similar view as the /support page, but with some JS magic.

/reboot

<HTML><BODY><h2> Reboot </h2><form action= "/reboot" method= "POST" ><input type= "hidden" name= "csrfToken" value= "lLCNesDvN9OI0lCDxEddQNNLoohVOipn" /><br /><button type= "submit" > Submit </button></form></BODY></HTML>

The reboot function actually uses a csrfToken!

/wifictrl

Which also uses the csrfToken

<HTML><BODY><h3> Tools for debugging network issues </h3><br /><form name= "Ping" method= "POST" action= "/ping" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><input type= "text" name= "host" size= "64" /><div><input type= "submit" value= "Ping" /></div></form><br /><form name= "Ping6" method= "POST" action= "/ping6" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><input type= "text" name= "host" size= "64" /><div><input type= "submit" value= "Ping6" /></div></form><br /><form name= "Traceroute" method= "POST" action= "/traceroute" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><input type= "text" name= "host" size= "64" /><div><input type= "submit" value= "Traceroute" /></div></form><br /><form name= "Traceroute6" method= "POST" action= "/traceroute6" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><input type= "text" name= "host" size= "64" /><div><input type= "submit" value= "Traceroute6" /></div></form><br /><form name= "Nslookup" method= "POST" action= "/nslookup" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><input type= "text" name= "host" size= "64" /><div><input type= "submit" value= "Nslookup" /></div></form><br /><form name= "mDNS Announce" method= "POST" action= "/mdnsannounce" ><input type= "hidden" name= "csrfToken" value= "DOp5wUhpeY57pUGxtD+xRX7PreYXG9Zs" /><div><input type= "submit" value= "mDNS Announce" /></div></form></BODY></HTML>

ping

Back in The Day

Right now you’re probably thinking the same as I did back when I first saw the interface “Oh, yeah! Command Injection! Just give me five minutes” and then a bit later “Let’s just hit it with Shellshock”. Sadly, things aren’t as insecure as they look and feel at first sight.

Neither manual injection nor the typical scanners were able to get anything executed on the speakers :-(

How Bad is it?

Well, this is a complicated topic. When run on a home network, behind a closed home router everything should be fine. You should not let strangers into your home network! If run on a public network or in general on a network shared with guests (just as its done in many restaurants) somebody might badly mess with the system. Badly meaning: Everything from a DoS, a Rick Roll to playing crazy sound tracks.

The biggest fail would of course be if somebody decided to expose his speaker to the internet.

Source: Shodan Screenshot

In that case some attacker will be able to just play music from whereever. Which has obviously already been done.