Your drivers may have an open Web server exposing you to attacks
During pentests performed by SecuRing we sometimes deal with applications that interact with hardware. Quite often they need custom drivers which may result in serious consequences. The biggest threats include the fact that drivers are usually run in a kernel space. That means not less than gaining root and full control of the victim’s machine when you take over the driver! For some people that may be obvious, since exploiting drivers is as old as the invention of SQL Injection.
Before the “Web server drivers” era, exploiting drivers on a machine was usually used for local privilege escalation. You needed to execute code on a machine, import some header “.h” files and abuse the driver’s logic.
But things have changed… In 2018 we observed that interacting with modern drivers currently means communication with fully featured web server using REST API, Websockets or other typical web technologies.
Let’s summarise our knowledge about classic drivers. Take a look at a simplified diagram shown below.
An application usually runs in a user space that communicates with a driver using a defined IPC mechanism. The driver placed in a kernel space does its job and passes messages directly to a device through hardware I/O. To simplify the example, the above diagram doesn’t include shared libraries, /dev/mem, etc.
Web server drivers
The diagram for this kind of drivers looks a bit different. There’s one additional block:
Now, the application is using web technologies to communicate with the driver’s server, then the message is passed to the driver and then to a device. The server may be also embedded into the driver.
Why do developers choose such an architecture?
There are many reasons. Firstly, this architecture is easier to maintain when you have to write a cross-platform driver. You develop one web-based API and the communication problem disappears.
Secondly, this architecture is also simple to extend. If you plan to create something extendable , that users will be writing plugins to — you may choose this solution. I’m pretty sure that nowadays there are far more people that understand straight REST API calls better than interacting with complicated C++ functions.
Thirdly, again, times are changing. We are used to having apps in our web browsers. Rich clients are not sexy anymore. With this solution, you can control your hardware directly from your browser! Convenient, but… what about #security?
Things go wrong
“Controlling your hardware directly from your browser”. The point is that maybe it’s not you who’s in control. 😉
Consider a driver server accepting all loopback connections from any website. Simple Cross-Site Scripting attack or visiting a malicious website can send messages to your driver just the same as as you can.
SecuRing your software
If you are implementing/testing a driver with such an architecture, you have to remember about at least 3 key rules:
- bind the web server only to 127.0.0.1,
- implement CORS mechanism and check where the request came from,
- authenticate the user.
This is of course not everything. You always have to remember to do parameter validation and other basic issues.
We were pentesting a device used for sensitive cryptographic operations. User had to install a driver, plug in a device to USB and open a web browser. We proved that any website was able to control the device remotely and execute arbitrary actions.
During pentests we were analyzing a 2FA dongle. It was basically a network device creating an additional interface used for WebSocket communication. The device was authenticating user but we managed to bypass it. We noticed that the device was exposing excessive debug methods that allowed us to create a full PoC bypassing the 2FA from a malicious website.
A $200 keyboard with a special interactive crown. Driver installation allows you to extend the crown functionality using default/custom plugins. The plugin I used communicated with the driver using websockets. I was able to take control of that communication. If you are interested in more details, check it out here.
These are only examples of bugs existing in an HTTP-based architecture. If you want to learn more, feel free to contact us. Every driver may increase the attack surface on your machine. Check if your drivers expose excessive ports by passing the following command to the terminal:
If you are involved in creating such drivers, remember to at least verify the 3 checks (localhost binding, CORS&Origin validation, user authentication). It’s also a good practice to pentest your software, so you won’t expose your clients to risk.