It is no pleasant experience at all for anyone to get the valuable property bought with the money you have earned with your blood, sweat, and tears stolen by some unknown cybercriminal. The Internet of Things (IoT) is developing with the rapid pace, and the devices that can be controlled remotely have become an indispensable part of our everyday life. A distinct disadvantage of these novelties is that they enable adversaries to use the devices you own for free, to conceal their crimes, and stay anonymous.
However, it is not the end to the story, for when we enter the era of connected cars, car sharing, self-driving cars, and pervasive wireless technologies, attackers will be able to sit in their cozy chairs while making your devices to fly right in their sticky fingers. Drones are the subject of major concern here. We have managed to get the DJI Spark drone and to find a vulnerability that makes the bleak picture above as real as it gets.
DJI drones have been on the radar of the hacker community for quite a long time. The interest of its members revolves mostly around unblocking some features of drones, setting control channels of drones to a higher frequency, and removing such restrictions as flight altitude limits or strictly set no-fly zones. Moreover, there are piles of publicly available info about jailbreaking drones. The most useful know-hows produced by the community are gathered in several Github cross-referenced repositories. Those striving for knowledge may also check the community wiki dji.retroroms.info. For quite a while the website has been accessible as a web archive only, but now the wiki is available again.
DJI Spark is a device out of the non-pro DJI drone line. It was released in 2017 and marketed as a drone for amateur aerial photography. In a way, it is inferior to other models: for example, its fully charged battery lasts for up to 16 minutes of flight. Still, compared to its big brothers (Phantom 4 and Mavic), Spark is considerably cheaper – 499$.
The heart of Spark is the Leadcore LC1860C ARMv7-A CPU with Android 4.4. Updates are several files with the
.sig extension. The update files are signed with RSA-SHA256, some of them have segments encrypted with the AES algorithm. Fellow cybersecurity enthusiasts have already revealed the format and got the AES keys, so everyone can use the tool, to extract data from the files and decrypt encrypted segments. In the drone firmware (the file with the biggest size) there is an abundance of native applications ensuring this complex device operates the way it is supposed to.
DJI Spark is equipped with a set of external interfaces:
To operate the drone from a desktop, DJI designed the DJI Assistant 2 application. The application enables operating the device connected to a desktop computer via USB, updating its firmware, changing its wi-fi network settings, etc.
While browsing the community materials, we came by websocket_tool.py, a script to change maximum altitude the drone can reach. A new value was written in with the help of a request to some web-socket server. It turned out the web-socket server is launched by the very DJI Assistant 2 application. In other words, the application has 2 interfaces:
Remember hackers coming out of the woodwork when cellphones became connectible to desktop computers? The reason is obvious: it was an easier and more reliable way to infect a system from a trusted computer than using traditional means. It resulted in various malware that allows an attacker to infect a phone connected to a PC emerging from obscurity.
Similarly to that, application interfaces may be used by attackers to bring their ill intentions into existence. So, we decided to check this scenario and give a closer look to the web-socket server interface.
We launched the latest DJI Assistant 2 1.1.6 version and connected a powered-on DJI Spark with the V01.00.0600 firmware version to a computer. Let’s try to access the web-socket server. To operate with web sockets, we used the wsdump.py tool from the websocket-client package.
The server response signified that there were no services at the URL ws://victim:19870/. Having had a sneaky peek at the web_socket_tool.py script, we found a valid URL – /general.
It was evident that the server required no authorization to be worked with. However, its responses were encrypted, which implied that by its design the interface was intended to be used only by the DJI software rather than a user. It begs the question: what does it transfer? Let us see how the messages between the client and server are encrypted. It is also worth to be mentioned that during the analysis of the older DJI Assistant 2 versions, we found out that they communicated with the server in plain text. After that we learned that the encryption mechanism was implemented in the 1.1.6 version, that is why the script from the community materials had no encryption.
First, we checked some of the encrypted text properties. The encrypted text remained similar every time the application was rerun. Drone rebooting did not affect it in any way either. Running the application on Mac brought the same result. These indicates that encryption keys did not depend on a session or used OS. Therefore, the keys we assumed that the keys were hardcoded. So, we tried to find them.
The code of web-socket server is stored in the DJIWebSocketServer.dll library. With the help of a tool capable of searching the signatures of cryptographic algorithms (e.g., Krypto ANALyzer for PEiD) we identified the algorithm – AES, and localized encryption procedures.
The used encryption mode can be determined even with zero knowledge about the specifics of AES. The only thing needed is to compare decompiled code with open sources from Github. The comparison shows that the CBC mode is used. By analyzing cross-references, we can find the initialization of encryption keys (Krypto ANALyzer showed them as well).
The encryption keys are indeed hard-coded. They are represented by strings of 32 bytes. There are two of them: the first one is used for requests to the server, the other for responses. Now, we have all the necessary source data to communicate with the web-socket server.
All we need to do here is to put encryption/decryption of the transferred data in the wsdump.py script, and we will get decrypted data sent to us by the application. A modified wsdump.py script at our github.
Besides the information regarding the application version, type of a device, etc., there is also a list of URLs of drone management services.
/adsb/log/1d9776fab950ec3f441909deafe56b1226ca5889 - data export from the ADS-B modules /controller/appreciation/1d9776fab950ec3f441909deafe56b1226ca5889 - license information /controller/config/user/1d9776fab950ec3f441909deafe56b1226ca5889 - a wide range of settings, including maximum flight altitude /controller/flight_record/1d9776fab950ec3f441909deafe56b1226ca5889 - flight information /controller/module_activate/1d9776fab950ec3f441909deafe56b1226ca5889 - operations with hardware modules, e.g., Intelligent Flight Battery /controller/nfz_upgrade/1d9776fab950ec3f441909deafe56b1226ca5889 - no-fly zone updating /controller/p4_ext/1d9776fab950ec3f441909deafe56b1226ca5889 - the Phantom 4 drones service /controller/simulator/1d9776fab950ec3f441909deafe56b1226ca5889 - managing the simulator built in DJI Assistant 2 /controller/upgrade/1d9776fab950ec3f441909deafe56b1226ca5889 - firmware updating /controller/user_feedback/1d9776fab950ec3f441909deafe56b1226ca5889 - user's feedback to the DJI company /controller/vision_calibration/1d9776fab950ec3f441909deafe56b1226ca5889 - camera calibration /controller/vison_simulator/1d9776fab950ec3f441909deafe56b1226ca5889 - managing the simulator (uses the commands similar to those of the simulator service) /controller/wifi/1d9776fab950ec3f441909deafe56b1226ca5889 - managing Wi-Fi hotspot /controller/zenmuse_debug_data/1d9776fab950ec3f441909deafe56b1226ca5889 - handling debugging information from Zenmuse cameras
/adsb/log/1d9776fab950ec3f441909deafe56b1226ca5889 - data export from the ADS-B modules
/controller/appreciation/1d9776fab950ec3f441909deafe56b1226ca5889 - license information
/controller/config/user/1d9776fab950ec3f441909deafe56b1226ca5889 - a wide range of settings, including maximum flight altitude
/controller/flight_record/1d9776fab950ec3f441909deafe56b1226ca5889 - flight information
/controller/module_activate/1d9776fab950ec3f441909deafe56b1226ca5889 - operations with hardware modules, e.g., Intelligent Flight Battery
/controller/nfz_upgrade/1d9776fab950ec3f441909deafe56b1226ca5889 - no-fly zone updating
/controller/p4_ext/1d9776fab950ec3f441909deafe56b1226ca5889 - the Phantom 4 drones service
/controller/simulator/1d9776fab950ec3f441909deafe56b1226ca5889 - managing the simulator built in DJI Assistant 2
/controller/upgrade/1d9776fab950ec3f441909deafe56b1226ca5889 - firmware updating
/controller/user_feedback/1d9776fab950ec3f441909deafe56b1226ca5889 - user's feedback to the DJI company
/controller/vision_calibration/1d9776fab950ec3f441909deafe56b1226ca5889 - camera calibration
/controller/vison_simulator/1d9776fab950ec3f441909deafe56b1226ca5889 - managing the simulator (uses the commands similar to those of the simulator service)
/controller/wifi/1d9776fab950ec3f441909deafe56b1226ca5889 - managing Wi-Fi hotspot
/controller/zenmuse_debug_data/1d9776fab950ec3f441909deafe56b1226ca5889 - handling debugging information from Zenmuse cameras
These services can be handled remotely via a web-socket interface. Hmm…what a great scope for our sinister deeds!
DJI drones can be controlled via a smartphone even without a special controller. As long as DJI Spark is considered, a controller is sold either as part of the Spark Combo package or separately. Without the controller, the smartphone application is the only option to control DJI Spark. The drone creates a Wi-Fi hotspot which is connected to by the application. The hotspot is secured with the WPA2-Personal protocol and forbids more than 1 simultaneously connected users.
We conducted a set of experiments to deauthenticate the pilot from the Wi-Fi hotspot. If the drone looses the signal from its pilot while flying at a low altitude, it will eventually fall down to the ground. However, if a pilot is deauthenticated after the drone has gained altitude, the device acts more strangely: it increases its RPM speed and reaches higher altitude. So, one needs a strong line of sorts or the drone will just fly away like some white dove of peace without waving us goodbye. The line we used was not long enough to check the maximum altitude the drone can reach, but we did not want to part with Spark. Alas, Spark, we thought you were a good friend to us, but it turned out you are just a prisoner of Wi-Fi.
The web-socket interface grants full access to the wi-fi network settings. By establishing a network connection to a computer that has a launched web-socket server, an adversary can see wi-fi settings and connect to another person’s drone. But what if the settings are changed. A drone will lose the connection with a user, and an attacker will become its sole owner.
All in all, a typical attack scenario may look like this (we copied json-commands format from the GitHub script).
To perform a successful attack, a cybercriminal should infect a victim’s system or to remotely trace the moment a drone is connected to a victims computer via USB and DJI Assistan 2 is started. The exact time can be identified by the 19870 port opening, connect to the web-socket server
ws://victim:19870 and change the password to a drone wi-fi hotspot by performing the following actions:
ws://victim:19870/generalurl, get the file value from a server response.
This scenario was tested on the DJI Spark drone but it is supposedly working with all the Wi-Fi manageable drones that are compatible with the DJI Assistant 2 application. The list of such drones is provided in Release Notes.
This type of attack works with all the supported OSs and default firewall settings. It can be conducted both in wired and public wireless networks. For you not to burden yourselves with performing all the described procedures manually, here is our PoC.
To the present day almost any smart device is USB-connectible to its big brothers (like a PC or laptop) to upload some files, update a device firmware or just charge it (most gadgets are only USB-chargeable), etc. Few people suspect that this moment that may look like a kind of routine everyday action, poses the highest degree of threat since an infected device may be easily used to infect the other. Malicious software is absolutely inconspicuous because it does not disrupt the security of a system. For example anti-virus software will identify it as some configuring application for USB devices that sends something to a device. That is it.
This way an attacker is as invisible as air and can infect smart devices (from wearable gadgets to drones). Cybercriminals have an opportunity to change settings to their liking and, ultimately, upload malicious firmware to a device. The infection will spread when the device is connected to other PCs/laptops.
In the age of IoT, the problem will loom large. That is why smart-device developers should focus on the scenarios when their devices are connected to other gadgets and computers and contrive the authentication and authorization mechanisms and trusted boot of signed firmware. Otherwise, the situations when a smart car in service get infected via diagnostic interfaces, and its owner will have to pay ransom to start the car will become commonplace.
We reported the detected vulnerability to the DJI company in the framework of the Bug Bounty programme they had started. The report was accepted and bug bounty paid.
09/25/2017 – first notification about the bug sent;
09/28/2017 – technical details sent;
10/12/2017 – the vulnerability accepted and the amount of bug bounty set;
12/20/2017 – bug bounty paid.
DJI company is considered to be the leader in consumer and commercial drone market. According to Wikipedia, it has a tremendous market share of the consumer drone market – 50%; and it will produce about 4 million drone units by 2021. That is why attacks on their drones are so dangerous – they affect a great number of users and organizations, as well as their confidential information. And such cases have already taken place in real life, like the case with the SSL keys and XSS vulnerability. It is also worth to mention the cases with a drone crashing into the White House’s south lawn and banning DJI drones in the US Army.
The described attack method is possible due to the following security weaknesses of the DJI software.
A Wi-Fi attack allows hijacking drones, but possible scenarios are not limited by this. The web-socket interface has a lot of features that may enable an attacker to change all the settings of the drone and access confidential data.
The detected weaknesses of the DJI software is provide a good ground of speculations, to be precise, about the purpose of the web-socket server interface. If it is used only by the DJI software, then why does it leaves network access open? And if there is an encryption mechanism, then it is obvious that messages are transferred via the network and used not only in localhost communications. Perhaps, the developers left this backdoor on purpose.