by Griffin Byatt
I recently purchased my second Das Keyboard, the Das Keyboard 5Q. I bought it for the quieter keys, and the pretty RGB backlighting. It also comes with some “smart” features, billing itself as the “World’s First Smart Keyboard”.
As a security professional, I’m default-skeptical of internet connected devices like this - devices that are more important than a smart lightbulb, but with less security investment than an operating system - so I wasn’t expecting to use any of these features. Regardless, when the keyboard arrived, I took a look at the docs to see if there was anything of interest.
Pretty quickly, I got to the description of the Local API, which was all but describing a classic vulnerability - CSRF or DNS rebinding to a local server. I downloaded the app, launched Proxyman, and confirmed my suspicions. I reached out to the Das team for a security contact on July 25th, and by August 2nd they announced a fix on the forum1.
At this point, this is a pretty boring vulnerability class, but I wanted to write a post for a couple of reasons. First, and most importantly, I haven’t written anything in a while, and I’d like to keep a somewhat regular pace. And second, because discovering code execution by reading documentation is a first for me.
The original disclosure with an up-to-date timeline can be found below. Note that the referenced proof-of-concept is not included here.
Users who run the Das Q application are vulnerable to no-click code execution while browsing the web. The initial vulnerability was uncovered simply by reading the developer documentation, and exploitation requires minimal technical ability.
The Das Q software runs two servers on localhost. One listens on port 27301 (the public API server) and one listens on 27302 (the Das Q server). The Das Q server is used by the Q application to install and configure packages, and the API server is used to send the keyboard “signals” as defined in the API documentation. Neither server is authenticated, and both have an extremely lax CORS policy (they accept requests from any origin).
As a result of these flaws, any website may execute arbitrary code on any Q user’s computer. This is demonstrated
in the proof-of-concept below. This is done by sending a cross-origin request to http://localhost:27302/install,
specifying an attacker-controlled
releaseUrl. The Q application then downloads the arbitrary zip file from
the target URL and installs it. As part of this process, the attacker code is executed.
Additionally, and somewhat less seriously, these issues would allow any website to view Q users’ plugin data, host information, and API keys, which are available in response to a variety of API requests.
var exec = require('child_process').exec; exec("open /Applications/Calculator.app");
To run the PoC, run the following from a Mac:
$ unzip das_poc.zip $ cd das_poc $ python -m SimpleHTTPServer 8080
Ensure the Das Q Application is running, then go to http://localhost:8080/hack.html. Note that Calculator.app is opened.
This is a fundamental design flaw in the application, and is technically public information. This flaw is described (without appreciating the consequences of the design) in the documentation itself.
Local API A script can communicate directly to the Q desktop API on port 27301. The Q desktop will then communicate with the Q enabled device. Signal propagation: < 1s Commands can only be sent locally to http://localhost:27301 No credential requirement Not reliant on Q Cloud, useful if Q Cloud is down or performing maintenance Can be used offline Privacy – Signals are not stored on the Q cloud database Messages will not appear in Q Signal Centre - https://qapp.daskeyboard.com/signals Mobile apps will not see these signals
Due to the fundamental nature of the issue, specific remediation steps are not possible. However, generally, the following features should be implemented:
Users can protect themselves immediately by quitting the Q application and preventing it from auto-starting until an update is made available. Due to the critical nature of this issue, and the low technical barrier for discovery, it would be beneficial to announce the issue as soon as possible.
I will adhere to the Google Project Zero disclosure policy with a 90-day disclosure deadline. I will only disclose ahead of the deadline if there is evidence that this is being exploited in the wild, the vulnerability is fixed, the issue is deemed a “no fix”, or it is disclosed by some other means (e.g. you disclose it early).