Abusing API’s in IoT Devices

Totally_Not_A_Haxxer
System Weakness
Published in
44 min readJan 10, 2023

--

Introduction

This article will talk heavily on abusing API systems such as the ones used in RokuTV’s, AppleTV’s, FireSticks, GoogleCasts, GoogleHomes, Routers and much more. This article will also go into deep detail about developing a path of logic to get around security systems that may prevent making a request to these API endpoints. This article will also talk about crafting, parsing and creating logic systems to catch and scan for certain devices using ARP scanners and SSDP sniffers. Without further to say let us get into it.

BEWARE: THIS ARTICLE IS EXTREMELY LONG AND IN DEPTH, THERE IS NOT A SECOND PART TO THIS ARTICLE, ENSURE YOU HAVE THE TIME TO READ IT OR ARE IN FRONT OF NOTHING IMPORTANT! (SIZE: 11,319 WORDS LONG)

Introduction (2) SKIPABLE SECTION

This article will explain something interesting and a little different, as a security researcher who has the power of development behind their belt I have always wanted to use programming to take advantage of design flaws in systems. In today’s article we will be going through a design flaw found in google cast SmartTV’s. This is not an exploit but rather abusing and taking control over IoT devices that use API’s and other forms of communications remotely with the device itself. These are design flaws because of the way they communicate with the factor that almost anyone who has a laptop and has a valid operating system even if it is a CLI only OS can make requests to these API endpoints without any form of authentication and abuse it. While you may be thinking “ how can you abuse an endpoint “ that is exactly the question anyone would think. Some of these endpoints have broken authentication behind them which allow you to bypass authentication systems set in place to use system functions such as reset, power off, turn on, factory reset, discover modes, change settings and much more. This article will first introduce you to the basic ideas of how design flaws can be dangerous and move on to talk about a program I developed to abuse multiple forms of IoT API endpoints using ARP modules, setters and various ideas and forms of logic to seriously cause some damage. I will also then walk through the process of how and why I came across this program then go into the deep depths of recon used to find these endpoints and use cases. I will also be explaining how my framework Caster works to enumerate and control these devices by abusing their API’s. This is a long road of brain confusion and general understanding of how protocols like HTTP and SSDP work with each other as well as other devices may connect to each other. Without further to do lets get into it.

What are we going to be talking about & the rabbit hole that brought me here?

This article is going to be among the bigger ones I have written so let me share exactly why and what we will be talking about. Have you ever wondered what happens inside of IoT devices? or maybe even opened up a wireshark session and found that a large amount of SSDP packets were being transferred over the network? Well recently I have been working with a framework I call CastHunter. What is CastHunter you ask? Cast hunter is a CLI / WUI based IoT enumeration framework which originally was only developed to enumerate and troll a google cast device on the network. For clear information a GoogleCast is a SmartTV device developed by google similar to roku and other devices. So the process of this program was easy, find endpoints on google that related to the google cast, make a request to the casts network with that file path on a specific port and execute the function, Whether that was grabbing information or even doing something such as changing the name it was an easy concept. However I ended up getting a google cast and realizing these endpoints did not exist and despite some doing what they were menant to I hit a major block- the framework was just lame, it could not do much. I had wireshark open to ensure that the requests I was making (HTTP) were actually reaching the hosts and returning or not returning data. When I ended up sitting back and wondering where it went wrong getting ready to trash the project I ended up seeing a packet that was HTTP, it was making a request to a device’s IP address on port 8060 from a device in caster that shown as a RokuBox. I did some more research filtering through HTTP packets from that host on that port and then realized roku boxes had the same thing but in more depth. You can literally go to the address in a browser followed by the port number and access information from the device, grab app information, send remote controlls, send and mock buttons and settings and even browse for information and install media. This led me down what I like to call the Rabbit hole of security research. This rabbit hole ended up in many messy port scans, wireless sniffers and trying to discover more and more information. After about a few weeks of trying to enumerate roku I also ended up seeing that AppleTV and FireStick all had similar API’s same with some home routers. Due to this research hole Caster can now support up to 10 different devices which include the following

Some devices have been limited due to the amount of found API’s however other devices are also more supported while others also require more heavier work around. What I will be talking about is how abusing API’s comes in handy, where and why you would want to do it and how these systems can be bettered to prevent abuse. Sadly not all of these API’s can be protected given well despite it not being an OPN network you can still see flowing HTTP traffic and SSDP or even MDNS queries over the network.

Why do devices like smart TV’s use API’s?

Most IoT devices may store information on a local server because it may be easier to store and parse especially if certain devices like roku devices or some applications like digital TV controllers may need to access. Some of this data is important such as device UUID’s, serial numbers, account data, SSID information, network information and so on from there. For example if you download an application for RokuTV’s that allow you to send controlls and commands to the device in the case you lost your remote, however the device you installed on the application may require UUID to access certain enpoints or use libraries to make special requests to the devices using protocols such as SSDP to figure out more device information to make the controller much more secure and or accurate at completing its job. This is also why some applications such as social media and even local web servers may store and collect data from your device, an instance such as games may grab your general region and system information to grab the geo-location, this locations helps game servers assign the most likely closest and accurate server for you to connect to for a better UserExperience (UX). Some devices like Roku provide portals for developers to find this information where more higher and closed sourced companies like apple may make it extremely difficult to access these URL’s without specific implementations. Devices such as the AmazonFireStick may use DIAL ( Discovery And Launch Protocol ) which allows for the developers to work with a fireTV device to enable the device app to be discover-able and launch-able from another device via a second-screen app. These type of protocols however are super hard to abuse and 9 chances out of 10 you are going to need to manually setup a developer side of the firestick which requires more knowledge of services like WhisperPlay. When it comes to abusing API’s at this point you can not abuse it which is where it gets secure, however who wants to abuse an API to just stream data? This is where the enumeration of the endpoints used on these devices actually come in handy.

What exactly defines a design flaw

A design flaw is exactly what it sounds like, a flaw in the design of a system that was implemented and may have caused issues with the resulting product. Design flaws can be something as small as a simple formatting change which may only create front end issues or something as big as the one today which leads to major security vulnerability issues. What we will be exploring today in this article is not an exploit but rather taking advantage of an API endpoint within chromecasts. This API endpoint is not secure, can be found and sniffed even on a private network by listening for SSDP or HTTP requests and can even be controlled and visited by random hosts. This is a major security issue especially if the URL’s like the ones in this post require next to no authentication and can be reached via curl. These API’s in more deeper cases can be detrimental to a network or can inflict some interesting ideas on people that are not so good to start off with. Design flaws like this which have no general idea of cyber security can be a major issue, upon building my program i also figured out that routers, apple TV’s, Amazon TV’s and even something as simple as an alexa has their own API’s and individual URL’s. These can lead to major security issues especially if you have IoT devices like IP-Cameras which are already vulnerable by themselves. Design flaws can be again dangerous in many ways, they can be the reason a bug becomes a full fledged vulnerability and the reason that applications may be shut down for days. It is important that during the design process you work with the team to create an amazing but secure option for your application, then when application and implementation development time role around collaborate with your team and ensure they check for vulnerabilities. Next it is important to understand why the protocols use protocols such as SSDP to communicate.

Understanding SSDP and why it is used in IoT devices

SSDP or Simple Service Discovery Protocol is exactly what it sounds like! A protocol dedicated to discover network services and devices such as UPnP devices ( Universal Plug and Play ). This protocol helps determine what network services are running on other device within the same network. In the instance of an AmazonFireTV you may see this come across on the network ( on wireshark ).

This is a simple example of what SSDP packets look like, as you can see here there are two forms mainly being used by the FireStick. One is NOTIFY and the other is M-SEARCH, what are these you may be wondering? First off it is important to note that while SSDP helps discover services on a given device it may also be trying to access those API’s we were talking about earlier to check if the device is compatible for screen share, Bluetooth etc.

  • NOTIFY: Notify in an SSDP packet are messages that are used by certain devices like the FireStick in our case to NOTIFY the devices presence and capabilities, think of it like a broadcast in a network saying “HEY device at 10.0.0.180, I am alive and I can do this with the service at this location! “. NOTIFY packets are important because it helps other devices on the network see supported protocols, capabilities, protocol types, locations etc etc. These are important in cases like the AmazonFireTV to tell the TV or device to work with other devices that are looking to ensure that the fireTV is compatible with certain services such as ScreenShare / Pull. You typically will see alot of SSDP packets with the NOTIFY data sent when a device is powered on or when the service status changes within the device. A typical NOTIFY packet will contain the following information.

As you can see here the SSDP NOTIFY packet stores multiple fields such as the server, the location, host-name, NT, Cache-Control and the USN. This information is important for other devices to know as a response when they try to search for the service.

  • M-SEARCH: It is the opposite of NOTIFY, instead of working to broadcast the devices information M-SEARCH grabs and requests information from a certain client to view if the services are compatible. These packet types are important because they allow the devices to communicate back and fourth for service or device communication. A typical M-SEARCH packet will contain the following information.

This frame and packet shares information on the host, its MAN also known as MANDATORY field is there to set a header field which specifies the target for the search. in our case here a client will be sending the M-SEARCH message with the MANDATORY field with “ssdp:discover” and the ST ( SEARCH TARGET ) to urn:dial-multi-screen-org:service:dial:1 which indicates it is looking for a multi-screen media service which is typically matched with DIAL, this means other devices on the network are looking for a DIAL.

  • Summary: SSDP will commonly use M-SEARCH and NOTIFY because they are important for service discovery, service probing and configuration as well as enabling device discovery or service discovery and communication of Universal Plug And Play devices (UPnP).

Now that you know how the services work and so on from there, what about different protocols that are used and opened by devices such as RokuTV’s?

Understanding ECP

ECP also known as External Control Protocol is a common protocol used along some devices which may give you access to system functions of that device outside of its own network. For example say you have a SmartTv or SmartHome device running on your network with address 10.0.0.120 but you are on host 10.0.0.75 in a real world you would think that you can not access the system functions of that device due to your network difference and the fact that you are two different hosts. Truthfully speaking that is true but also false at the same time. Obviously you will not be able to load system commands like ls, dir, pwd, whoami etc etc without spawning a shell or logging onto the device but rather run a few if not many system functions which may allow you to take advantage of the device from a remote location on that network. When IoT devices use ECP it can lead to a million different functions and in the end it all depends on the device and manufacturer. Sometimes ECP is used by the device itself to fetch or store information, because devices store information locally and start essentially what can be known as a file server, the device will handle files such as XML or JSON files over this “ file server “. Because of this any host on the network can visit the host-name given a certain port and access files and output device information. ECP itself is not always the issue but can you see how this in the future and on some devices can become an issue? Imagine being able to view system data just within your browser.

Now what?

Well we now understand how and why the services exist and work, but whats next? Now that we can understand what I am talking about when I mention SSDP and ECP etc, we can finally move onto how exactly you can abuse API endpoints, the process of discovering them WITHOUT GOOGLE and understanding what each function does.It is important to note that we will be looking at real life current (2023) API endpoints for these devices, I will also be talking about Roku, AppleTV and Amazon’s FireStickTV.

Developing a sense of logic

Like most of my modern day projects, research papers etc I always end up developing a path of logic in my head, like a set of conditionals before I end up actually starting the process. But instead of nested conditionals rather a map or otherwise known as a mind map. We already know that as far as we can understand that these API endpoints are hosted on near all of the devices that are IoT related and that they all have their own unique sectors and areas of reaching. But what about actually reaching and finding these? Well as a beginner guide we are going to start off with Roku, as it is the easiest among-st all of these. Here are some questions we can ask and answer along our path to developing logic.

  • Does the device have any weird or wacky ports? (This will show that our device may have a process of port randomization, for example ports like 54901 or 30820 are weird ports and are not service related. This must mean that the device may be using port randomization each time it reboots or just has a wacky port number [a good step in the right direction])
  • Does the device have any UPnP ports open, servers open such as SSH, Fileserver, FTP etc? (This will help us pinpoint interesting services that we can pull data from)
  • Is the device using static ports such as 8008, 8009? ( This will help us determine what address on what port we will need to access, a solution for this is to scan ports on the device. )
  • Is the device broadcasting any SSDP M-SEARCH/NOTIFY packets? ( This will help us understand whether or not there is a service that the device uses to connect to, within this case we can test for other endpoints within the device )
  • What brand is the device that is broadcasting information? (This helps us determine any current or older vulnerabilities or maybe even extra API information that is not as public but was found on some forums when googling for this device and its api type)

These questions will really help us understand whether or not we can enumerate a device and abuse its endpoints. For example if we know the device is sending SSDP NOTIFY packets to a host of 239.255.255.255 then we can assume there might be a special endpoint within that notify packet which will tell us that the device can be enumerated or forced to spit out information ( even if it was meant to do so, this information still is not supposed to be seen by any other people other than developers themselves ). If we verify static ports like 8008, 8009 or 60000 we can assume the device has a server on it with either UPnP or other services for its API. This path of logic will help us say or determine and predict certain information. For example we can say that if a device is running port 60000 there may or may not be another filepath that can be found on that server. Now as of right now in this current process there is no way to tell whether or not all the filepaths exist without formerly testing this ourselves. Lets create a scenario. We have a device which is at address 10.0.0.59 and it spit out a SSDP notify packet which we sniffed in wireshark. it was an HTTP request to this path http://10.0.0.59:8060/ well automatically we already know that the device has a port 8060, but what about other ports? it seems as if this device is loaded on such a weird endpoint with a larger port number than most typical devices? Well if we run a nmap scan on the host we may get something like this.

nmap -p1-65535 -v -A -Pn 10.0.0.59
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-09 16:13 EST
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 16:13
Completed NSE at 16:13, 0.00s elapsed
Initiating NSE at 16:13
Completed NSE at 16:13, 0.00s elapsed
Initiating NSE at 16:13
Completed NSE at 16:13, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 16:13
Completed Parallel DNS resolution of 1 host. at 16:13, 2.55s elapsed
Initiating Connect Scan at 16:13
Scanning 10.0.0.59 [65535 ports]
Discovered open port 43173/tcp on 10.0.0.59
Connect Scan Timing: About 32.71% done; ETC: 16:15 (0:01:04 remaining)
Discovered open port 8060/tcp on 10.0.0.59
Connect Scan Timing: About 66.42% done; ETC: 16:15 (0:00:31 remaining)
Discovered open port 9080/tcp on 10.0.0.59
Discovered open port 7000/tcp on 10.0.0.59
PORT STATE SERVICE VERSION
7000/tcp open rtsp AirTunes rtspd 377.40.00
|_rtsp-methods: ERROR: Script execution failed (use -d to debug)
|_irc-info: Unable to open connection
8060/tcp open upnp
9080/tcp open glrpc?
43173/tcp open unknown
| fingerprint-strings:
| FourOhFourRequest, GetRequest, HTTPOptions

This is a good example of how we can keep trying to access information and find new gateways for this host. we see that 8060 is our upnp or universal plug and play port and it is open, we also see some other ports open such as 9080 and a weird weird long port that is not a specific service. We are already starting to open up more and more questions. So what happens if we make the same HTTP request to the same host? We get this block of information in our browser.

<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:roku-com:device:player:1-0</deviceType>
<friendlyName>Nighty Night</friendlyName>
<manufacturer>Roku</manufacturer>
<manufacturerURL>http://www.roku.com/</manufacturerURL>
<modelDescription>Roku Streaming Player Network Media</modelDescription>
<modelName>0000X</modelName>
<modelNumber>0000X</modelNumber>
<modelURL>http://www.roku.com/</modelURL>
<serialNumber>YG00DW393885</serialNumber>
<UDN>uuid:295c0014-9c06-1002-809d-acae1945d3ae</UDN>
<serviceList>
<service>
<serviceType>urn:roku-com:service:ecp:1</serviceType>
<serviceId>urn:roku-com:serviceId:ecp1-0</serviceId>
<controlURL/>
<eventSubURL/>
<SCPDURL>ecp_SCPD.xml</SCPDURL>
</service>
<service>
<serviceType>urn:dial-multiscreen-org:service:dial:1</serviceType>
<serviceId>urn:dial-multiscreen-org:serviceId:dial1-0</serviceId>
<controlURL/>
<eventSubURL/>
<SCPDURL>dial_SCPD.xml</SCPDURL>
</service>
</serviceList>
</device>
</root>

Well- that was alot of information that it just spit out. It seems as if it was not obvious enough this is a roku device and we can see we just accessed a url which was able to spit out decent information, well what about the rest? For now we are going to ignore service type, id, UDN and the model and device information. We are specifically interested in these two files here.

<SCPDURL>dial_SCPD.xml</SCPDURL>
<SCPDURL>ecp_SCPD.xml</SCPDURL>

Why are these interesting? First off we notice that there is dial and ECP to a SCPD URL. Typically SCPD is highly related to SOAP and UPnP. I will not go deep into explaining how to exploit all of these services but something to note is that UPnP is one of the most vulnerable services out there to many types of attacks and most devices that have a UPnP service on them are vulnerable to something in relation to the UPnP service itself. These URL’s are interesting because they basically give us filepaths within the base URL that we can access. So if we go to the first url DIAL_SCPD.XML we will see the following.

<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<serviceStateTable>
<stateVariable sendEvents="no">
<name>A_ARG_TYPE_DeviceID</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>

This in some if not most or all cases is bad because it is giving us the direct state variables with the service state url. Again we will be probably discussing this on a deeper level later on as it is something that requires heavy explanation and security research. Now that we know the different url’s exist and that there are other file information what if we just make a path up. We can assume there are two main file-paths here within the server which are

dial and ecp

these two urls may be important for device enumeration or exploration as you can say. What happens if we go to dial on the web server?

we get a browser error saying

No webpage was found for the web address: http://10.0.0.59:8060/dial/

This does not mean the filepath does not exist or that the host was not connecting. It actually gives us a good understanding that this may be a correct file path and that there may be something after it. Most IoT devices are known to use .json or .XML file formats for responses and holding data since it just makes it easier overall. Let us create some brute forcing logic that may give us some ending files with .xml or .json that may give us some more device information.

dialdev
devdial
devicedial
dialdevice
devinfo
infodev
deviceinfo
dd

If we try all of these filepaths at the end of our url we will get a error saying there was no webpage found for the requested address which means the file does not exist. However this changes when we type dd.xml. We end up getting the same page response we got from the root path of the server but this is a perfect example of how we can format logic. Through discovering the device name and type we can develop a sense of logic that helps us to continue finding more and more paths. This may have been a really bad way of explaining things at least for this section but it gives you an idea of creating a flow of logic as every hacker and programmer must need their own path of logic to fix or resolve questions. Just through this tiny little bit and being able to access device information we can actually answer alot of questions or in fact all of them.

  • Does the device have any weird or wacky ports? Yes there is one port 43173 this is a very weird port to have service on, this should not be explored but should be a resort for exploring new security issues or even server data.
  • Does the device have any UPnP ports open, servers open such as SSH, Fileserver, FTP etc? Multiple servers including UPnP which can help us in the term that we need to ever exploit the device or need the device to spit out more information about itself.
  • Is the device using static ports such as 8008, 8009? Yes ports 9080, 8060 and 70000 all very well known service taken ports were discovered on the host.
  • Is the device broadcasting any SSDP M-SEARCH/NOTIFY packets? Yes it seems to not only broadcast service discovery packets but will occasionally make requests to itself.
  • What brand is the device that is broadcasting information? Roku

Now that we have the logic finished what else is there to do? Well the more we discover and the more we develop logic the more research we can put into these devices. Routers, FireSticks, Chromecasts etc all have something and it shows when you do a NMAP scan on it or run any form of scan for open ports or data. I mean just going to the browser and typing the address followed by a port might bring you something. From here on there is possibly more devices you can discover which have the same thing. Now all you have to do is apply that logic to discovery.

Understanding the logic ( secondary section SKIPABLE )

Logic is a prime point in enumeration, especially when it comes to IoT devices. Because we are not going to be exploiting the device itself rather than abusing API’s we need to start some sort of logical flow to our thinking. Say we discover a device such as a google cast but even after hours of googling can not find valid endpoints and can not figure out if it has an API or what not. Our best bet here would be to develop a path of logic and develop a few physical logical paths for us to take. The next few paragraphs will show and explain exactly how I developed my own logic, step by step, line by line.

  • Step 1: This was before the project was even an idea but to get some ideas I popped open wireshark and started listening on different interfaces to see if anything gave me an idea. I realized at the corner of my eye that an MDNS packet was found or rather sniffed, it had the following query.
_googlecast._tcp.local: type PTR, class IN, "QM" question

This was interesting and started to spark some more ideas, i also noticed right after that packet the same host name which for the articles case was 10.0.0.54 had a query where it tried to pull data from itself, it was a simple HTTP request but, to itself? Considering my experience with devices and even building applications it was quite weird that a device was making a request to itself, however this is where the logic started to develop. At this point we should pick apart the packet, which leads us into the second part and step.

  • Step 2(Packet analytics): I figured by now I could find 90% of the data from simply sniffing the packets, however from here I formulated a logical point that worked like this
if the device the google chromecast sent a packet to itself which 
was an HTTP request then this means it must have some form of endpoint
continue to inspect

As I continued to inspect I found that it made that request to its same host-name but on port 8008 which seemed to be a reserve port. I went to the URL http://10.0.0.54:8008/` to see if I would get anything but all I got was a message from the browser saying No webpage was found for the address this is where having a logical map down comes in handy. You see the browser did not tell us that the host refused to connect, so obviously there is something here that can be connected to but what about different paths? Lets separate our messages. We know that if a browser says “Host refused to connect” that the host is down on that port or maybe even the host itself is down, but if we get the message no page was found for the address that the host connected. From here what we can do is either manually start brute forcing file-paths or we can continue sniffing and see what we find. The more logical idea given we were finding HTTP requests within wire shark is to just continue to just sniff packets. After roughly an hour of letting wire-shark sit on HTTP requests only i noticed the same source 10.0.0.191 was sending HTTP GET requests to the path http://10.0.0.54:8008/setup/eureka_info which would give a response of all current device information. This gave me a secondary idea of logic, maybe if I search google for the results of the setup path I can find a few different URL’s and endpoints as to what may happen. It took roughly almost my entire rest of my day to figure this out but on the 30th page of google I found a forum talking about google chrome-casts and their API. Well this guy who was experimenting with it just spit out a bunch of the URL’s. It is a bit weird considering some of them all revolved around setup but in addition to that by making a request to one of the URL’s i found out google chrome-cast has a SSDP path because it uses SSDP. By this point I started to spin up scans to scan what port it would connect on and sure enough I found a 8008, 8443 and port 53917 which seemed to be an extra part. Logic became more and more of an insane role the more the investigation went on and the more I found out. By the end of this tiny little logical processing I was able to find URl’s that could let you factory reset the device, power the device off and even change the name. However the URL’s were not the hard part, getting them to work was.

  • Step 3(Enumerate): This was a more annoying process because I had to do a deeper deeper dive into how these URL’s worked such as if they required parameters or if they were using special authorizations used by the device etc. After about another 2 hours of inspecting wireshark requests I came across many different endpoints which I could only get to with certain parameters. I could not get all required parameters to get information to spit out in the browser however I was able to put some more logic behind the investigation with current knowledge of API’s and got to work. Eventually after constantly trying different URI’s and URL’s with parameters I finally found a URL within the google chromecast which was named zc? and had a remark of action= this header lead me to some weird findings as with certain params you can get system information. Further down the road I was able to make a request which had the action parameter of getInfo and because of that the browser finally spit out some information which contained the following.
{"status":101,"statusString":"OK","spotifyError":0,"version":"2.9.0","deviceID":"fffffffffffffffffffffffffffffffffffffffffffffffff","remoteName":"helooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo","publicKey":"xxo4fffffffffffffffffffffffffffffffffffffffff/bmDI1hlA","deviceType":"TV","libraryVersion":"3.200.454-g79c1e3f4","brandDisplayName":"Google","modelDisplayName":"ChromecastHD","resolverVersion": "0","groupStatus": "NONE","tokenType": "default","clientID": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","productID":1,"scope": "umbrella-tv,streaming,client-authorization-universal","availability": "","supported_capabilities":3,"supported_drm_media_formats": [
{"drm": 1, "formats": 70},
{"drm": 2, "formats": 70}
],"aliases": [
]}

finally things were looking up, after this I started to apply them same logic and was able to enumerate half of the endpoints logged and sniffed from wireshark to spit out information of the device, or output system functions. I will not talk about all of them within this article because it would take over 50 lines just to show the URl’s and for the scope it is too much.

Abusing the API (Creating an idea)

After additional research, hours and hours on forums, looking for weird endpoints in wireshark and finding alot of SSDP packets being used along side of MDNS i found out that there were way more devices that used the same idea for storing or sending data. Plus some devices like roku have external protocols which allow you to send a simple request to the server and make a command execute a function on the server. Originally as said in the beggining, Caster was only meant to support GoogleCast devices as the information for their smart home API was already out there and after a bit of a dabble in trying to get it to work to find out only certain devices of the cast support it I ended up going on a really long road of exploring new ways of doing things. By now I have created an idea, why dont I just create a simple program which creates an ARP handler to discover devices on the network and if it is a device that is a roku or google cast send a remote request to the URL with formatted parameters and go from there. This framework in a sense would also validate the manufacturer of the host and if it was anything like a roku or google device it was put into a separate list which the user can view at any moment using the program and also set the values. At this point in time the framework is extremely basic, but this really is not fun when you can just send a simple request manually, sure it would automate the hunt for devices but what about adding support for more and more devices? As I kept developing and adding new features to it I ended up realizing I should run a capture on my network using wire-shark for roughly 2 days and see what I capture given that is how I discovered that roku was also having its own API. Later on I ended up finding that within that same capture that I was running for two days non stop that there were many different requests to an HTTP url that was different each time. This all ended up containing URL’s for information like system information, key information and the ones in the SSDP requests and responses were all service based which gave me and amazing idea. I wrote a program to take every single packet within the list and extract any URL that had service, http://, https:// and other payloads alike within their requests/responses. If they did save the packet to an output and remove duplicates. After about 3–4 hours of looking through an insane amount of SSDP, HTTP, TCP, UDP, MDNS etc packets I gathered a list of every single url that my program found which oddly enough were UPnP connected or had an http server on it making requests with UUID’s. This is where the idea to truly abuse these API’s came in handy. First I threw all the object responses into a structure which looked something like this

// GDDEVDESC
type Root struct {
XMLName xml.Name `xml:"root"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
SpecVersion struct {
Text string `xml:",chardata"`
Major string `xml:"major"`
Minor string `xml:"minor"`
} `xml:"specVersion"`
Device struct {
Text string `xml:",chardata"`
DeviceType string `xml:"deviceType"`
FriendlyName string `xml:"friendlyName"`
Manufacturer string `xml:"manufacturer"`
ManufacturerURL string `xml:"manufacturerURL"`
ModelDescription string `xml:"modelDescription"`
ModelName string `xml:"modelName"`
ModelNumber string `xml:"modelNumber"`
ModelURL string `xml:"modelURL"`
SerialNumber string `xml:"serialNumber"`
UDN string `xml:"UDN"`
UPC string `xml:"UPC"`
ServiceList struct {
Text string `xml:",chardata"`
Service struct {
Text string `xml:",chardata"`
ServiceType string `xml:"serviceType"`
ServiceId string `xml:"serviceId"`
SCPDURL string `xml:"SCPDURL"`
ControlURL string `xml:"controlURL"`
EventSubURL string `xml:"eventSubURL"`
} `xml:"service"`
} `xml:"serviceList"`
DeviceList struct {
Text string `xml:",chardata"`
Device struct {
Text string `xml:",chardata"`
DeviceType string `xml:"deviceType"`
FriendlyName string `xml:"friendlyName"`
Manufacturer string `xml:"manufacturer"`
ManufacturerURL string `xml:"manufacturerURL"`
ModelDescription string `xml:"modelDescription"`
ModelName string `xml:"modelName"`
ModelNumber string `xml:"modelNumber"`
ModelURL string `xml:"modelURL"`
SerialNumber string `xml:"serialNumber"`
UDN string `xml:"UDN"`
UPC string `xml:"UPC"`
ServiceList struct {
Text string `xml:",chardata"`
Service struct {
Text string `xml:",chardata"`
ServiceType string `xml:"serviceType"`
ServiceId string `xml:"serviceId"`
SCPDURL string `xml:"SCPDURL"`
ControlURL string `xml:"controlURL"`
EventSubURL string `xml:"eventSubURL"`
} `xml:"service"`
} `xml:"serviceList"`
DeviceList struct {
Text string `xml:",chardata"`
Device struct {
Text string `xml:",chardata"`
DeviceType string `xml:"deviceType"`
FriendlyName string `xml:"friendlyName"`
Manufacturer string `xml:"manufacturer"`
ManufacturerURL string `xml:"manufacturerURL"`
ModelDescription string `xml:"modelDescription"`
ModelName string `xml:"modelName"`
ModelNumber string `xml:"modelNumber"`
ModelURL string `xml:"modelURL"`
SerialNumber string `xml:"serialNumber"`
UDN string `xml:"UDN"`
UPC string `xml:"UPC"`
ServiceList struct {
Text string `xml:",chardata"`
Service struct {
Text string `xml:",chardata"`
ServiceType string `xml:"serviceType"`
ServiceId string `xml:"serviceId"`
SCPDURL string `xml:"SCPDURL"`
ControlURL string `xml:"controlURL"`
EventSubURL string `xml:"eventSubURL"`
} `xml:"service"`
} `xml:"serviceList"`
} `xml:"device"`
} `xml:"deviceList"`
} `xml:"device"`
} `xml:"deviceList"`
PresentationURL string `xml:"presentationURL"`
} `xml:"device"`
}

As you can see extremely long responses as well as started forming the packet responses and telling the program what exactly to look for to identify and find new device's on the network. The more I come across the more ideas that come into my head. I found a program that did this to google casts where you can kill apps, force it to scan for WiFi devices, force it to power off, reset, reboot, factory reset, forget WPA ID’s etc. The only difference? Every time you wanted to enumerate the tool you had to manually input the IP, there was no warning that you would need to know certain ID’s that the script could not collect and not to mention the entirety of the script is broken. After doing more security research i ended up finding out how all of these worked and getting more links for more devices I found on old forums or even more recent forums that took me to the 50th page of google pretty much XD. Anyway I ended up doing the same for amazonTV’s, I was able to figure out that amazon IoT devices would send SSDP packets as well such as their fire-sticks to their UPNP filepath. The port it was hosted on was port 60000, however something was very unique about this URL, it had a unique UUID specific to every individual device which would again change per device. Originally during the first bit of recon on the device I had found a URL which would act as any other normal address based URL but instead had a random port and would have the parameters of the following.

http://%s:53917/zc?action=getInfo&version=2.7.1

This URL was definitely weirder, however this URL given I knew the port and the address would throw out the UUID of the amazonFireTV i was enumerating. However I later found out that this data is randomly added and removed from this file and that it may have belonged to something to do with spotify given the response has a JSON RESPONSE field of spotifyerror like the following.

{"status":101,"statusString":"OK","spotifyError":0,"version":"2.9.0",
"deviceID":"8b2f1ca080eb0ffffffffffffffffffffffffffad6db6c735229703e",
"remoteName":"soandso's Fire TV",
"publicKey":"gOJc+fRPPUC39XPzJyG5LOn7hGSlqeYsBIgbMmDLepuKKodPuvhvqQHkKSI/Agjn6qqcudMLaGbTkA5N0UbuSRUsvUowQIX/BOxw0Wc/06kAbLxDVjm9fKT/9j1rzKPJ",
"deviceType":"TV",
"libraryVersion":"3.200.454-g79c1e3f4",
"brandDisplayName":"Amazon",
"modelDisplayName":"AFTMM",
"resolverVersion": "0",
"groupStatus": "NONE",
"tokenType":
"default","clientID": "756a52aaaaaaaaaaaaaaaaaaaaaaaaae654456a",
"productID":1,
"scope": "umbrella-tv,streaming,client-authorization-universal",
"availability": "",
"supported_capabilities":3,
"supported_drm_media_formats": [
{"drm": 1, "formats": 70},
{"drm": 2, "formats": 70}
],"aliases": [
]}

The JSON response field used to have a UUID inside of it which meant I can easily just tell the framework to make a request to this URL, output all of the data but use the DUUID ( the original field name ) and work with the other UPNP device information field. However this was not the only issue, okay so what was it? The biggest issue I had with this URL is that every so often the device would randomize the port number of the URL to access that information which means 53917 will be something like 47809 in say every 3 hours. So how exactly do we get around this? Well we know that most devices like the FireTV’s, RokuTV’s etc all send out SSDP NOTIFY packets which contain the host, NT ( typically the UUID ) and the URL’s or locations. So here is how I got around it. We already know that the ports may be randomized, however for services like UPNP they will not be randomized unless they really went through the work to do so ( spoiler: they didn’t ). So we can do this multiple ways.

  • We can forge our own SSDP M-SEARCH packets and listen for SSDP NOTIFY packets with a valid UUID in the URL.
  • We can brute force ports until we get the URL right or brute force UUID’s
  • We can make a SSDP NOTIFY listener which listens FOR ONLY SSDP NOTIFY packets and will look for a LOCATION field within the packet. This field will have its URL checked, picked apart and validated. If the URL contains a UUID from the URL parser set by a self crafted function then it will run itself and then store the UUID along with a hostname. How will we associate the hostname with the UUID? We can create a data web which in our case is just a string that has a symbol exasperating one value from the next. For example UUID@HOST or
10.0.8.10@7ffffff56-ffff-ffff-ffff-d49e86d88dcc

and then we can use a strings splitter to split the string at the @ symbol and index the string predicting that both the host and the UUID will be at the arrays index of 0and 1 .

So let us go through our options! We do not want to do choice 1 because that requires

  • 1: Too much information we or the program will not be able to aquire in such a short amount of time without the user manually inputting it. Keep in mind the idea of this framework is to automate the abuse of several hosts at the same time, imagine a user having to place information every time for every host which changes every network.
  • 2: This will definitely take up wayyyyy too much system resources and be one of the worst ways to ever solve this issue
  • 3: Just perfect, this is because like the ARP module but different instead of sending out SSDP packets it can look for SSDP packets that are NOTIFY with a HTTP protocol of HTTP/1.1 and once found with data it will continue to parse and save that information with a valid host tied with its UUID. This makes it easier on the program because this is a well bigger and more complex function but using algorithms and proper threading it can run in the background without stunting system performance.

Now how exactly are we going to do this? Well its simple, start a simple thread which calls a packet listener, this packet listener finds one interface on the machine that is not a local host or Ethernet based interface and opens to call a handler on it. For every source packet that is found or sniffed on that interface that the ARP module did not send out it will be parsed and checked for layers. The general layer structure of an SSDP packet is of the following.

  • EthernetII (typically)
  • IPv4 (we want to check for this because our framework only works with HTTP urls that are IPv4 on the same network)
  • UDP (This defines the port and ensures our port whether source or not is 60000)
  • SSDP ( This will define the data we need to pick apart from the packet and layer itself, this is the main layer we need to decode and verify has the following headers. USN, CACHE-CONTROL, NT, HOST, LOCATION, SERVER and NTS )

Once we verify the layers exist we can output the packet and dissect it bit by bit, if it is a request frame we can parse it as a request frame, if it is a response frame we can parse it as a response frame and so on. Which means the SSDP response and location would be easy to parse because once we have the URL we can just write a simple function to extract the UUID from the URL easily. This is an example of how we can get around security systems at least this can be maimed as a security feature for the device itself unlike most RokuTv’s or google casts where you need a port, empty header and so on from there. Now we got around to developing a sense of logic and also got to explain how we are going to get around security systems now what?

Finalizing the program

Our programs concept is to take as less of a user input as possible, which means the user would not need to enter a host, port etc even keys or packet fields for manual packet crafting. So now we lay out the program since our idea is pretty basic and simple.

  • Arp Module [Background thread]: The ARP module will help the user discover devices for the unlimited time the program is running, this will also allow them to set a specific target host to enumerate without leaving the program and be able to sniff data from certain devices.
  • SSDP Module [Background thread]: The SSDP module will be the module that implements the security maneuver for amazon fire sticks, this will listen in the background for any SSDP packet that contains a UUID within its HTTP request.
  • Signal Handlers [Background thread]: The background threads for this are just to catch fatal errors in the program that we expect such as indexes or arrays that are not exactly the same and may cause the program to glitch but these handlers will ignore errors that are not fatal and continue on with the program
  • Console [Main thread]: We want the user to be able to send the controls per supported device so we will develop a nice console which has individual commands and modules such as enumerate which use keys such as roku, casts, firetv etc to specify the device type followed by the command which are executed and parsed to maps of functions or maps that upon returning true executing a function.

This is quite simple but there is one last element we are missing….CHAOS. We want this program to be as efficient as possible and be able to proove how exactly we can abuse API endpoints which is where the question comes in to Abusing API endpoints . In this program we will create a sub map of functions which is defined in the console as enumerate* . The goal of this function or module you are asking? To grab every single host within a given address and attempt to start a new thread for every host per command and attack them all at once or abuse their API’s. An example of this is say you are on a hotel’s network which typically hotels will all have alot of smart TV’s but in this case say the lobby and bar have a total of 40 TV’s not too much but enough to be annoying and you end up figuring out all of them are roku. What our framework will do is start the ARP module and find the IP address, MAC address etc of every single roku device and seperate it into its own list which can be viewed by the user. But instead of setting one manually they can target every single host on that network that is roku and do the same thing in seconds with enumerate*. This function will itterate over that same table, all 40 IP addresses that are Roku’s and verified to be TV’s and execute a function such as roku-reboot and will reboot all of the devices on seperate threads which means 40 threads will be started. At this point this is where total chaos can be reigned and at this point you are not doing anything but abusing a design flaw however this is a perfect example of how bad this framework can be sometimes.

working with APPLE TV and understanding the difficulty

As we have already discussed developing a system of logic this really is where the logic starts to play in. One thing I wanted my framework caster to support was the ability to work with AppleTV. Unlike Roku, Google Casts, Standard home routers, Google Homes, Amazon Alexas, Cameras etc this was a much much harder and more annoying roadpath. Apple is known to be by far one of the most closed sourced ( hence ONE OF ) brand names out there, everything from their OS development, hardware firmware and other forms of software are extremely locked down tight. Despite Apple having vulnerabilities they still have a very complex code base, complex file types and even their language swift which is pretty advanced and complex. This would later affect the operation of attempting to enumerate an AppleTV which is something again as said above I wanted caster to support. So I took the logic we developed and ran a scan on a old but still working AppleTV. I ran the following NMAP command

sudo nmap -p1-65535 -v -A -Pn -O --open 10.0.0.96

This gave me the following output of scanned ports and services

PORT      STATE SERVICE    VERSION
3689/tcp open daap Apple iTunes DAAP 11.1b37
5000/tcp open rtsp AirTunes rtspd 220.68
|_rtsp-methods: ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER, POST, GET, PUT
7000/tcp open rtsp AirTunes rtspd 220.68
|_rtsp-methods: ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER, POST, GET, PUT
|_irc-info: Unable to open connection
7100/tcp open http Apple AirPlay httpd
|_http-title: Site doesn't have a title.
62078/tcp open tcpwrapped
OS details: Apple Mac OS X 10.7.0 (Lion) - 10.12 (Sierra) or iOS 4.1 - 9.3.3 (Darwin 10.0.0 - 16.4.0)

As you can see by the most important output of this scan most of the services running on the apple device you guessed it is well apple based. This is where it can get sometimes confusing, in the factor that we want to abuse these API’s and these API’s are hidden or run on port randomization or even randomize the location of the API each time it restarts. Our logic still will not fail on this, to an extent it will but it will not completely fail. So lets apply that same logic, we know an HTTP server is running or HTTPD server is running on 7100 and we also know the service name as well. After doing a massive amount of googling which is typically how the flow goes I could not find anything, however I figured why not do what I did with roku, amazon fire TV etc and see if I can not drop or at least get file information. So I went to the root directory or path of the server ( defualt path ) and typed /info I got prompted to download a file titled (info). This file was not a standard XML, JSON etc file it was rather recongnized as a octet stream, I ended up running cat and got this.

bplist00�

+,-.0ZmacAddress[statusFlagsRpiXdevice
ID_keepAliveSendStatsAsBodyRvv^audioLatencies\audioFormatsRp
kUmodelXfeaturesTname_keepAliveLowPower]sourceVersion_ffffffffff96D
_$d59907bd-a73a-4998-ad8d-c87a44c97922_F4:F9:51:DF:6F:97 ���type_inpu
tLatencyMicrosYaudioType_outputLatencyMicrosdWdefault��e�!'�"#$%&_au
dioOutputFormats_audioInputFormats���d����"#()*���e���
O �2N�!��z��&��K�%P?�z3�r�ӴtZAppleTV3,2Z��_Living Room Apple TV V220.6%0
<?Hcfu����������
?UWYajlov������������

This was very very interetsing to me and I never have actually gotten deep into apple devices so I could not make out what the device actually was outputting or giving me other than the most basic file information. I also figured there was an error outputting the file which must have meant it was binary due to some weird unicode symbols and a common one I see alot when outputting binary files “�”. However upon googling and sitting through a bunch of forums and even apple documentation I came across the file format PLIST which was exactly the header of the dump. BPLIST00 is a standard header name for PLIST files otherwise known as Property List files which are files that were developed by apple designed for Mac OSX to store serialized data. If you are not aware serialized data is essentially data that is transformed into a known format that is usually stored to be reconstructed or transmitted later on. In this case Apple PLIST files store data that is serialized to be reconstructed later on for other purposes whether or not that is for services or server requirements etc. These file formats are typically used to store information that other device applications and services may require such as in our cast for audio, MAC addresses, device name, ID’s and source versions. From my understanding and research there are two types of PLIST files identified by the header of the file.

  • BPLIST00: This is the ASCII form of the file format for PLIST files, typically this is an older format for PLIST files and is less efficient to use.
  • BPLIST01: This is the BINARY form of the file format for PLIST files, this data is stored in a much more raw and efficient binary representation of the data.

We can tell our device may be older or on an older software version due to the use of BPLIST00 given that is not a commonly used standard for most modern IOS based applications. If we hexdump this information we end up getting the following.

00000000  62 70 6c 69 73 74 30 30  de 01 02 03 04 05 06 07  |bplist00........|
00000010 08 09 0b 0c 0d 0e 0f 10 11 12 13 14 15 20 2b 2c |............. +,|
00000020 2d 2e 13 30 5a 6d 61 63 41 64 64 72 65 73 73 5b |-..0ZmacAddress[|
00000030 73 74 61 74 75 73 46 6c 61 67 73 52 70 69 58 64 |statusFlagsRpiXd|
00000040 65 76 69 63 65 49 44 5f 10 18 6b 65 65 70 41 6c |eviceID_..keepAl|
00000050 69 76 65 53 65 6e 64 53 74 61 74 73 41 73 42 6f |iveSendStatsAsBo|
00000060 64 79 52 76 76 5e 61 75 64 69 6f 4c 61 74 65 6e |dyRvv^audioLaten|
00000070 63 69 65 73 5c 61 75 64 69 6f 46 6f 72 6d 61 74 |cies\audioFormat|
00000080 73 52 70 6b 55 6d 6f 64 65 6c 58 66 65 61 74 75 |sRpkUmodelXfeatu|
00000090 72 65 73 54 6e 61 6d 65 5f 10 11 6b 65 65 70 41 |resTname_..keepA|
000000a0 6c 69 76 65 4c 6f 77 50 6f 77 65 72 5d 73 6f 75 |liveLowPower]sou|
000000b0 72 63 65 56 65 72 73 69 6f 6e 5f 10 11 46 34 3a |rceVersion_..F4:|
000000c0 46 39 3a 35 31 3a 44 46 3a 36 46 3a 39 36 10 44 |Ff:ff:ff:ff:ff.f|
000000d0 5f 10 24 64 35 39 39 30 37 62 64 2d 61 37 33 61 |f.$d59907bd-a73a|
000000e0 2d 34 39 39 38 2d 61 64 38 64 2d 63 38 37 61 34 |-4998-ad8d-c87a4|
000000f0 34 63 39 37 39 32 32 5f 10 11 46 34 3a 46 39 3a |4c97922_..F4:F9:|
00000000 35 31 3a 44 46 3a 36 46 3a 39 37 09 10 02 a2 16 |ff:ff:ff:ff.....|
00000010 1e d4 17 18 19 1a 1b 1c 1d 1c 54 74 79 70 65 5f |..........Ttype_|
00000020 10 12 69 6e 70 75 74 4c 61 74 65 6e 63 79 4d 69 |..inputLatencyMi|
00000030 63 72 6f 73 59 61 75 64 69 6f 54 79 70 65 5f 10 |crosYaudioType_.|
00000040 13 6f 75 74 70 75 74 4c 61 74 65 6e 63 79 4d 69 |.outputLatencyMi|
00000050 63 72 6f 73 10 64 10 00 57 64 65 66 61 75 6c 74 |cros.d..Wdefault|
00000060 d4 17 18 19 1a 1f 1c 1d 1c 10 65 a2 21 27 d3 22 |..........e.!'."|
00000070 17 23 24 25 26 5f 10 12 61 75 64 69 6f 4f 75 74 |.#$%&_..audioOut|
00000080 70 75 74 46 6f 72 6d 61 74 73 5f 10 11 61 75 64 |putFormats_..aud|
00000090 69 6f 49 6e 70 75 74 46 6f 72 6d 61 74 73 12 03 |ioInputFormats..|
000000a0 ff ff fc 10 64 12 03 ff ff fc d3 22 17 23 28 29 |....d......".#()|
000000b0 2a 12 03 ff ff fc 10 65 12 03 ff ff fc 4f 10 20 |*......e.....O. |
000000c0 88 1b cc 32 4e 80 21 e7 80 ce 7a b9 14 b0 26 e3 |...2N.!...z...&.|
000000d0 c0 4b 1d c7 25 50 3f f9 7a 33 e7 72 f6 d3 b4 74 |.K..%P?.z3.r...t|
000000e0 5a 41 70 70 6c 65 54 56 33 2c 32 13 00 00 00 1e |ZAppleTV3,2.....|
000000f0 5a 7f ff f7 5f 10 14 4c 69 76 69 6e 67 20 52 6f |Z..._..Living Ro|
00000000 6f 6d 20 41 70 70 6c 65 20 54 56 09 56 32 32 30 |om Apple TV.V220|
00000010 2e 36 38 00 08 00 25 00 30 00 3c 00 3f 00 48 00 |.68...%.0.<.?.H.|
00000020 63 00 66 00 75 00 82 00 85 00 8b 00 94 00 99 00 |c.f.u...........|
00000030 ad 00 bb 00 cf 00 d1 00 f8 01 0c 01 0d 01 0f 01 |................|
00000040 12 01 1b 01 20 01 35 01 3f 01 55 01 57 01 59 01 |.... .5.?.U.W.Y.|
00000050 61 01 6a 01 6c 01 6f 01 76 01 8b 01 9f 01 a4 01 |a.j.l.o.v.......|
00000060 a6 01 ab 01 b2 01 b7 01 b9 01 be 01 e1 01 ec 01 |................|
00000070 f5 02 0c 02 0d 00 00 00 00 00 00 02 01 00 00 00 |................|
00000080 00 00 00 00 31 00 00 00 00 00 00 00 00 00 00 00 |....1...........|
00000090 00 00 00 02 14 75 74 46 6f 72 6d 61 74 73 12 03 |.....utFormats..|
000000a0 ff ff fc 10 64 12 03 ff ff fc d3 22 17 23 28 29 |....d......".#()|
000000b0 2a 12 03 ff ff fc 10 65 12 03 ff ff fc 4f 10 20 |*......e.....O. |
000000c0 88 1b cc 32 4e 80 21 e7 80 ce 7a b9 14 b0 26 e3 |...2N.!...z...&.|
000000d0 c0 4b 1d c7 25 50 3f f9 7a 33 e7 72 f6 d3 b4 74 |.K..%P?.z3.r...t|
000000e0 5a 41 70 70 6c 65 54 56 33 2c 32 13 00 00 00 1e |ZAppleTV3,2.....|
000000f0 5a 7f ff f7 5f 10 14 4c 69 76 69 6e 67 20 52 6f |Z..._..Living Ro|

When trying to grab file or device information especially if it is in a binary format you want to ensure you are opening the file you want to. It is important to note this because most binary parsers will only support a specific file format, and if loaded incorrectly where the file may be another format it can cause crashes or fatal errors when trying to read the bytes and sections into the array. Now I will not go into the deep depths of how to pick this form apart and write a whole 500 lined program to due so however we can talk about the important things to note inside of this hex dump to identify the file.

Secondary note: The file that was given to me downloaded from the URL WAS NOT IN ANY WAY RECOGNIZABLE BY THE OPERATING SYSTEM DUE TO DECODING ERRORS, We will need to write a program to recognize the file ourselves.

In order for us to make sure the file is a valid plist file we want to look at a few major things

  • The magic number: Every file has this, in our case the magic number is 8 bytes long and consists of 62 70 6c 69 73 74 30 30 which translates to bplist00
  • The trailer: This is the structure of the file that is usually placed at the end of the file holding information otherwise known as metadata to the file about the number of objects stored within the file as well as the size of the offset table.
  • The offset table: This is our main table of offsets which if you do not know tells us the location of each object or part of data stored within the file
  • The objects: These are often shown as keywords or text or sections of text which may look like this statusFlagsRpiXd or MACADDRESS in our case as well. These can be many different data types as well rather than just string or character based data.

Now what about writing a library to parse this data? Given the time I had left to develop a whole library to separate and parse BPLIST files and their objects it just was not practical. So the best case scenario here was for us to verify the file by grabbing and verifying the magic bytes of this file, which again are the first 8 bytes of the file. All we need to do is open the file, turn the string bplist00 into a string of bytes and see if the array of the first 8 bytes of the files byte array match, if it does then deem it as a Property List file and hex dump it, then try to find key values within that file that may be able to help the user read more efficient data. Like in the screenshot below

As you can see the strings which had important or common keys were highlighted red which highlighted a portion of audio output. As you can see the main challenge here is figuring out how to parse these files and writing a library for it, even if you were to write one the process is still extremely brutal and not always perfect, so for now a hex dump will do. Upon further research of the AppleTV devices there are other endpoints but I have not nearly explored them enough and the services enough to talk about that, as that is for another day and another article. Working with apple is extremely hard and frustrating sometimes as due to them being closed source ( which is not always the worst thing in the world ) it is hard to find and locate these endpoints, however as you saw from the logic we developed and applied we were able to get somewhere and locate files then continue to parse them and find more information on the services and file types Apple devices use for their operating systems or to store certain data. Typically PLIST files are known to have a file extension of .plist however this was not the case because it is obvious the only devices that should have had that file are people such as developers for debugging reasons or just so the device can store information to send it to a host in a more hidden way or smaller way as some data is stored like this to compress its contents and make it easier to transfer to other services or API’s.

Summary

We have reached the end and finish to this article and is the finish of this program design .We discussed different protocols, procedures, design flaws etc used in standard everyday home devices such as smartTV’s then built a logic to develop a similar program for other devices which can abuse API’s.

Conclusion

API’s are bad if not secured enough and can result in major issues or other forms of exploits. For example if an API is exposed and is found on a network that stores user data and someone writes a program like caster that can find all hosts and extract the data from the API you are going to end up loosing alot of customers and people are going to be wondering if these devices are worth their money just for someone to steal information from it. There are many solutions for these problems such as unique ID information instead of broadcasting it as well there are other ways to encode the data or encrypt it with non shared key pairs. There are a million ways that these can be secured way past text encoding and encryption and I am sure there are hundreds of ways to transfer it to the service or for the service to grab that information than storing it locally on the network of the device. However I do think that a reason as to why companies like Apple do not think about this could be due to the factor that they do not think people are going to find these endpoints or even bother knowing apple’s closed source habbits despite having a small open sourced community. It is very very important that as a developer you ensure that your API endpoints are secured enough and include some form of authorization done correctly, if the device needs to store information on a server like a network and the device needs to ensure that a external device can reach it maybe develop some form of code sharing that can prevent it. Anyway I hope you enjoyed this article, it was very long and is only the beggining of my project and security research however it definitely is a rabbit hole of tension and long long months of research and work to get this to work. Even despite the minimal help I have had using google to obtain some form of knowledge I still feel like this is a major learning experience and goes to show that nothing is a waste of time and when it does feel like a waste of time keep trying and keep exploring, there is always something out there for you to explore.

~ Totally Not A Haxxer OUT!

End

Welp we have reached the end of this article! I know this was quite a short one but it was also one that did not need much depth I was rather just sharing my experiences. I hope this article helped give you some insite as to what it can be like to work on development teams both privately and publically. If you want to keep up with my content do not forget to help support me!

Github

Caster Project

Other links

https://beacons.ai/totally_not_a_haxxer

--

--

Cyber Security Educator, Developer, Social media manager, Author, youth education, content creation, engineering, ui/ux, RE