This is part two in my Touchlogging series, you can find part one here.
In part one, I wrote a little bit about the background and how to intercept touch events on jailbroken iOS. This part will focus on Android. I do recommend that you start with part one even if you are not interested in iOS.
Let's start with rooted Android devices. How can X and Y coordinates of touch events be captured? As it turns out, we can open a shell and type getevent: that's it, mission accomplished. What getevent is doing is reading from /dev/input, so we can just as well read the information from there directly. With root access, we can use getevent or read from /dev/input directly on the device.
What if the device is not rooted? We can actually still use getevent, but it has to be triggered via an ADB shell, which in turn requires USB debugging to be enabled on the device. This is possible because the rights are elevated when accessing the device through ADB.
Now we know how to capture events on rooted android devices and non-rooted android through ADB, but can we capture events directly on non-rooted android devices? This also turns out to be possible with some caveats. There are two ways that I found. The first one is live wallpapers. Basically, all touch events that occur when the live wallpaper is visible are sent to the live wallpaper. This in itself is useful for capturing information entered into widgets. However, additionally, if you know the layout of the screen of the victim, it may be possible to combine this with other attacks, such as by overlaying the screen to get user input.
This brings me right into the next way I found for capturing touch events on non-rooted Android devices; overlay the screen. Using TYPE_SYSTEM_ALERT, it is possible to create screen overlays. The rule for the overlays appear to be as follows (I say "appear to be" as this is based on tests I have done myself). If the width of the overlay is 30 pixels or less, the background application gets the events unless the overlay itself is touched. If it is touched, the overlay gets the touch events and not the background application. If an attacker wants to use screen overlays to capture input, the reasonable options are either to use a full screen overlay and get all events, or put small overlays, 30px or less, in specific positions, and do something when they are touched.
Alternatively, if you are running one of the devices that leave /dev/input world readable, then the attacker simply has to read some files to get all touch events. In fact, the attacker would get all events, not just touch events.
If you are trying to defend against touchlogging attacks, here are some things that can be done.
- Check if USB debugging is enabled (mainly applicable in a BYOD setting).
- Do not allow this to be enabled unless the user is a developer, as it serves no purpose for standard users.
- Check all installed apps for the permission TYPE_SYSTEM_ALERT, if found, take appropriate action. Do keep in mind that some apps use this permission for legitimate purposes, so just having the permission does not mean its a malicious app.
- Detect rooted devices. However, I do not think that the best course of action is to block execution on rooted devices, this is a decision that should be taken based on a number of factors. Detecting rooted devices and submitting that information to the backend server is generally a good idea though.
- If possible, advise users to avoid using live wallpapers.
- If you are running one of the vulnerable devices, contact the handset manufacturor and ask for a patch. There may already be one available.