android-multiplexing-security-pocs
Accompanying PoCs for the paper titled "Exploiting Sensor Multiplexing for Covert Channels and Application Fingerprinting on Mobile Devices"
view repo
Mobile devices often distribute measurements from a single physical sensor to multiple applications using software-based multiplexing. On Android devices, the highest requested sampling frequency is returned to all applications even if other applications request measurements at lower frequencies. In this paper, we demonstrate that this design choice exposes practically exploitable side-channels based on frequency-key shifting. By carefully modulating sensor sampling frequencies in software, we show that unprivileged malicious applications can construct reliable spectral covert channels that bypass existing security mechanisms, e.g. Android's permissions framework. Moreover, we present a variant of this technique that allows an unprivileged malicious observer app to fingerprint other device applications and user interactions at a coarse-grained level. Both techniques do not impose any assumptions beyond application installation and accessing standard mobile services via the Android Sensors SDK. As such, they open a powerful attack vector that exploits subtle yet insecure design choices in mobile sensor stacks.
READ FULL TEXT VIEW PDFAccompanying PoCs for the paper titled "Exploiting Sensor Multiplexing for Covert Channels and Application Fingerprinting on Mobile Devices"
Mobile devices contain an array of sensors that measure the device’s location, position, and ambient environment. At present, the Android framework supports over a dozen sensors, from traditional accelerometers and gyroscopes to magnetic field, temperature, humidity and air pressure sensors [7]. This has been driven by the proliferation of low-cost micro-electromechanical systems (MEMS), which have miniaturised sensor measuring mechanisms on the micrometer scale. Today’s mobile systems host several, often multi-sensor, integrated circuits (ICs) in millimeter-sized packages. High-frequency sensors, such as accelerometers and gyroscopes, are used ubiquitously for transforming devices into game controllers, detecting geographic and screen orientation, implementing gesture recognition systems, performing human activity recognition, and supporting accessibility features [7, 19, 44, 21, 15, 16, 17].
During standard use, multiple applications may access measurements from one or more physical sensors; for example, a fitness tracker and foreground navigation app may request magnetometer measurements for direction heading simultaneously. On Android systems, applications request measurements using the desired sensor, its sampling frequency, and a maximum reporting latency using the Sensors SDK [7]. If multiple applications access a single physical sensor, then software-based multiplexing is used, where the maximum of the requested sampling frequencies is returned to all calling applications. Consequently, applications may receive measurements at a higher rate than the originally specified frequency. There is no guarantee that measurements will not arrive at a faster rate if another app requests the same sensor at a higher frequency.
In this work, we show that this exposes a design flaW that can be leveraged as a software-controlled side-channel. Firstly (§4), we demonstrate that unprivileged applications can construct spectral covert channels for unauthorised inter-process communication (IPC). This is achieved by modulating the sampling frequency of one app to generate deterministic side-effects in the sampling frequency observed by a second app that requests the same sensor simultaneously. The approach is based on frequency-shift keying (FSK), where higher frequency signals requested by a transmitter application are multiplexed into a lower frequency carrier signal established by a receiver app. Experimental results show that a large range of widely deployed mobile device sensors can be exploited aboard devices from multiple manufacturers. The proposed method can be used to transmit arbitrary bit-strings between two same-device user applications, including low resolution one-bit images, which bypasses application sandboxing and related mechanisms for securing IPC.
The second part of this paper (§5) develops a variant that enables coarse-grained application fingerprinting. This is achieved using a malicious observer app that requests measurements from an arbitrary sensor at a very low sampling frequency. If a victim app uses the same sensor at a higher frequency, this frequency is modulated into the malicious app’s signal that can be detected in near real-time. We describe how 10 widely used, sensor-enabled Android apps—e.g. Pokémon Go (100M+ downloads), Uber (500M+ downloads) and PUBG Mobile (500M+ downloads)—use particular sensors and sampling frequency combinations that serve as discriminating features for application identification. Further, the Android SDK [8] provides several default sampling frequencies to help developers set appropriate values that balance utility and battery consumption for various use cases (e.g. games, detecting orientation changes, and UI interactions). Such default frequencies, as well as bespoke sensor frequencies used by the aforementioned apps, can be detected by a malicious, unprivileged app using simple rule-based expressions.
For both attacks, implementation details, experimental results, and potential countermeasures and recommendations are presented. Additionally, we describe how recent measures introduced in Android 9, which limit the long-polling of continuous sensors, are insufficient for preventing the attacks. The presented techniques do not impose any special requirements, e.g. rooting or kernel-mode access, beyond the use of regular user applications using APIs available to any developer through the Android Sensor SDK.
We present new software-controlled side-channels that exploit the distribution of sensor measurements to multiple mobile applications requesting the same underlying sensor. These methods can be exploited for: establishing spectral covert channels for app-wise IPC, and
fingerprinting sensor-enabled victim applications. The vulnerabilities arise from design-level security flaws in Android-based mobile sensor stacks. The methods are evaluated against evaluation devices from separate major OEMs, potentially affecting millions of devices globally. Proof-of-concept code for the attacks is made open-source to facilitate future research.
111Proof-of-concept repository: https://github.com/cgshep/android-multiplexing-security-pocsThe attacks in this paper were disclosed to Google’s Android Security Team on 3rd June 2021 under a 90-day disclosure period. They were acknowledged on the same day, a severity assessment was provided on the 21st June 2021, and the issues will be addressed in a forthcoming major Android release.
Current covert channel research has focussed on timing side-channels using CPU cache contents (Prime+Probe [40], Flush+Reload [47], Flush+Flush [18], and their variants [27, 14, 49, 35, 48, 25, 36, 28]), exploiting contention in DRAM memory controllers [42] and GPU access patterns [45, 38, 23]. Additionally, mobile sensors have found wide utility for out-of-band channels using the device’s ambient environment. MEMS gyroscopes have been used as low-frequency microphones for detecting ambient speech [37] and accelerometers for inferring touch interactions [46, 41, 13, 30, 31]. CPU core temperature sensors have been used for same-core and cross-core thermal side-channels, where intensive operations of a victim process deterministically increase the core temperature observed by a malicious observer [32, 10, 29]. Novak et al. [39] described how camera flashes, vibrations, and device speaker sounds can be used to transmit data to a (same-device) receiver using device sensors, while Block et al. [11] used a similar approach using ultrasonic frequencies. In 2016, Matyunin et al. [33] showed how EM emissions of I/O operations can be detected by mobile magnetic field sensors. MagneticSpy [34] showed how a malicious app could fingerprint same-device apps and web pages using the magnetic field sensor with 90% accuracy.
For clarity, we do not use physical media, but instead exploit the software interfaces used by apps for interacting with sensing hardware. The closest work, by Ulz et al. [43], presented methods for creating covert channels on embedded systems using: , unused/reserved registers of sensing microcontroller units (MCUs); , reading/writing to MCU register configuration bits; and , timing differences between the activation of sensor MCUs. The authors posit that observable effects of different requested sampling periods could be used for frequency-based information encoding; however, experimental evidence was not provided. In this work, we extensively and empirically show that a large number of widely deployed continuous sensors on Android devices are vulnerable to covert channels using sensor measurement multiplexing. Moreover, we present a novel variant of this technique for fingerprinting active, sensor-enabled applications.
The Android framework supports 13 hardware- and software-based sensors.222We exploit continuous sensors defined in the Android Sensor SDK [7]. GPS location, sound levels, and detecting nearby Bluetooth devices and Wi-Fi access points have also been treated as ‘sensors’ [20, 22, 39, 11]. However, these use separate interfaces that are not vulnerable to the same attacks. Hardware sensors interact with a single physical component, e.g. a MEMS gyroscope, while software (a.k.a. virtual or emulated) sensors process signals from one or more physical sensors at a sensor hub or OS level. The precise separation between physical and virtual sensors is largely OEM-dependent. As a guide, accelerometers and gyroscopes are usually implemented in hardware, while rotation vector and linear acceleration sensors are common virtual sensors [7]. The Android sensor stack (Figure 1) comprises several layers for translating raw physical values, which are device- and OEM-dependent, into reliable values that can be used by developers of gaming, UI, navigation and other sensor-driven applications in a standardised way.
Developers utilise the SensorManager class for enumerating supported device sensors and registering listeners to receive sensor measurements (registerListener). Applications must implement the SensorEventListener interface when registering a new listener, which is triggered on an event-driven basis and provides sensor measurements on a first-in first-out (FIFO) basis. For portability, a limited interface is provided for registering listeners, offering the ability to choose a target sensor and a desired sampling frequency. The SDK routes requests to the HAL: a single-client layer that abstracts OEM-specific firmware/hardware, which is shared by Android OS and user apps. Upon receiving measurement requests, the HAL communicates directly with sensing hardware or, optionally, to a sensor hub for pre-processing measurements without using the main application processor. The HAL returns the resulting data to the Android framework using FIFO fast message queues (FMQs), thus avoiding kernel involvement [2]. The framework returns sensor data to the calling application as SensorEvent objects, which are processed by the application’s SensorEventListener.
In the event that multiple applications register requests to a single sensor, then a multiplexing mechanism is used, irrespective of whether physical or virtual sensors are used. The multiplexing system returns measurements to all applications at the fastest requested rate. As a result, when an application requests a sensor using a particular sampling frequency, then this is a ‘best effort’ endeavour: there is no guarantee that events will not arrive at a faster rate if another application requests the same sensor.
The Android source states that “There is no mechanism to send data down from the applications to the sensors or their drivers. This ensures one application cannot modify the behavior of the sensors, breaking other applications” [8]. The latter part of this statement is not strictly accurate. We discovered that a lack of appropriate controls at the API layer enables applications to influence, and be influenced by, the sensor sampling frequencies requested by other applications. This section develops an FSK-based method wherein a malicious receiver app effectively generates a carrier wave at an extremely low frequency, which is modulated by another app requesting the same sensor at a higher frequency. This modulates the malicious app’s received signal; oscillations in this signal can then be used for information transmission.
The covert channel involves two colluding applications—a transmitter, ; and receiver, —who wish to establish a uni-directional communication channel outside the Android IPC security mechanisms. Standard IPC is conducted through the intent mechanism [3], using the broadcast system to send messages to other applications under a publish-subscribe model. Broadcast receivers and intent filters are denoted in applications’ manifest files for specifying the security policies and permissions for authorised inter-app IPC.
The attack scenario assumes has access to security- or privacy-sensitive data; for example, permissions for accessing SMS data, GPS co-ordinates, camera data, etc. wishes to send this data to , who does not have these permissions, but does have the ability to extract data from the device (e.g. internet access for reaching a remote server). Crucially, the user may not wish to download if it requests permissions to sensitive data and a data transmission medium.
Our channel enables to illicitly leak data to without any privileges beyond the ability to setup simple services for receiving sensor measurements. These are separate services launched independently by and , which may be disguised as or integrated into legitimate applications. (One-to-one information transfer is described in detail for simplicity; however, the approach can be used without alteration as a covert broadcast channel to multiple receivers. This is possible because sensor multiplexing modulates the sampling frequency of all applications registered to a sensor.)
The covert channel exploits the multiplexing feature for returning the highest sampling frequency of a given sensor to all requesting applications. This is achieved by and targeting a shared sensor, where can alter the multiplexed frequency observed by . The main insight is that the multiplexed sampling rate can be modulated by a single application, , who repeatedly registers and unregisters a sensor listener using a very short (fast) sampling period, . If first registers a sensor listener at a long (slow) sampling period, , then ’s observed sampling period will modulate between and . This is triggered by ’s repeated registering and unregistering of sensor listeners. By carefully defining the sampling periods and pulse widths—the time between registering and unregistering a sensor listener—an FSK-based binary transmission channel can be established between and . Figure 2 provides a high-level overview.
Firstly, registers a sensor request at rate , which is routed through the HAL from which measurements are returned (steps 1a–2a in Figure 3). Next, bit-encodes the secret that it wishes to transmit. iterates through each secret value, , and registers a sensor request of sampling period if , and unregisters the request if . Likewise, these requests are routed through the OS and HAL (1b–2b). After each listener (un-)registration, waits for a short time period (pulse width), , to allow the new sampling period to be multiplexed into the signal received by . The secret values are sent from by oscillating ’s received sampling period between and accordingly (3a–3b).
Notably, this approach is not limited to two sampling periods ( and ). It is possible to register multiple sampling periods at higher frequencies than , which are modulated into ’s signal at their own rates. This enables us to construct a rudimentary message transmission protocol using four separate sampling periods: to define the start of a message transmission using a syncword period, ; to indicate transmission endings using period, ; ’s carrier period, ; and ’s modulating period, .
The full channel involves three stages:
1. Channel initialisation: (a), registers measurements using a target sensor, , with period . (b), registers a listener for the same sensor, , but at a significantly higher frequency, , to signal the start of a transmission.
2. Data transmission (Figure 2): (a), unregisters the listener with sampling period . then transfers a bit-encoded secret value, , by registering a new listener with sampling period for a pulse width of time if . Otherwise, unregisters its sensor listener and waits for time, , to transmit . This causes ’s sampling frequency to return to . (b), observes the changes in sampling periods in the background, i.e. and , and appends the observed values to a message buffer.
3. Channel termination: (a), signifies the end of a transmission by registering a listener with period . (b), observes that the sampling period has modulated to , and completes any post-transmission operations, e.g. sending the buffer to an external server for analysis.
State machines were implemented for managing our protocol using two distinct Android applications for and . These were used to access continuous sensors on the devices under test, where SensorEvents are delivered as soon as they are available by the HAL at the requested sampling period. Without constant user interaction, the two other supported sensor classes—one-shot and on-change sensors—cannot be leveraged effectively. Continuous reporting sensors comprise most of the sensors available on Android [7]. In this work, the accelerometer (AC), gyroscope (GY), gravity (GR), linear acceleration (LA), magnetic field (MF), and rotation vector (RV) sensors were successfully exploited.
Three test devices from separate OEMs were evaluated:
Xiaomi Poco F1 with a Qualcomm Snapdragon 845 SoC (octo-core @ 2.8GHz, 6GB RAM) and Android 10 (build QKQ1.190828.002). Cost: £309/$370 USD (2019).
Google Pixel 4A with a Qualcomm SDM730 Snapdragon 730G SoC (octo-core @ 2x2.2GHz and 6x1.8GHz, 6GB RAM) and Android 11 (build RQ2A.210405.005). Cost: £349/$450 USD (2020).
Motorola Moto G5 with a Qualcomm MSM8937 Snapdragon 430 (octo-core @ 1.2GHz, 2GB RAM) and Android 8.1 (build OPP28.82-19-4-2). Cost: £120/$170 USD (2017).
Because the covert channel leverages changes in sampling frequencies, the fastest supported sampling rate acts as a hard throughput limit for a particular sensor. These limits were ascertained using the List<Sensor> getSensorList (int type) of the SensorManager (see §3) for each device, using Sensor.TYPE_ALL to acquire the details of all available sensing hardware. From this, the getMinDelay() method was used to return the minimum delay allowed between two SensorEvent objects in microseconds for sensors with continuous mode reporting. The minimum supported sampling periods for each device and sensor, including their hardware models where known, are shown in Table 1.
Xiaomi Poco F1 | Motorola Moto G5 | Google Pixel 4A | ||||
Sensor | Vendor | Min. Period | Vendor | Min. Period | Vendor | Min. Period |
AC | Bosch BM160 | 2500 | Bosch* | 10000 | STM LSM6DSR | 2404 |
GR | Qualcomm* | 5000 | Motorola* | 10000 | Google* | 5000 |
GY | Bosch BM160 | 5000 | Bosch* | 5000 | STM LSM6DSR | 2404 |
LA | Qualcomm* | 5000 | Motorola | 10000 | Google* | 20000 |
MF | AKM AK0991x | 10000 | — | — | STM LIS2MDL | 10000 |
RV | Xiaomi* | 5000 | Bosch* | 5000 | Google* | 5000 |
*: Specific model not known, —: Not supported.
For the message transmission protocol, we developed encoding and decoding algorithms for and (Algorithms 1 and 2) for binary data transmissions. The encoder and decoder are assumed to have an agreed set of sampling rates for the carrier, transmission, syncword and ending periods—characterised further in §4.3.3—and a shared target sensor and pulse width time. The channel stages (§4.2) were implemented using the native Android SDK without any third-party libraries, device rooting, custom ROMs, or other dependencies beyond the standard sensor APIs.
Params.: Target sensor, ; carrier, transmission, syncword and end periods, , , , ; pulse width time, ; and a bit-encoded secret, .
Setup: Receiver calls RegisterListener(, );
RegisterListener(, );
Wait();
UnregisterListener();
foreach do
if
UnregisterListener();
else if
RegisterListener(, );
Wait();
UnregisterListener();
RegisterListener(, );
Wait();
UnregisterListener();
|
Params.: Target sensor, ; carrier, transmission, syncword and end periods, , , , ; pulse width time, ; tolerance value, ; and an empty data buffer, .
RegisterListener(, );
;
public void OnSensorChanged(event):
;
if SyncwordReceived
if
Done;
else if
;
;
else if
;
;
else if
SyncwordReceived = true;
;
|
The encoder assumes that the receiver has created the carrier wave into which the transmission signals are modulated. After this, the transmitter communicates the syncword by registering a sensor listener for a target shared sensor, , using the syncword sampling period, , and waiting for the pulse-width time, . Next, the listener is unregistered and, for each secret bit, , sensor listeners are registered and unregistered based on whether or respectively using sampling period . The transmitter then waits for time . This is repeated until all secret bits are transmitted, before sending the ending signal with period .333In our implementation, we did not use error-correcting codes. Even without this, near or wholly error-free transmission was achieved for many sensors on our evaluation devices (see §4.4).
The decoder creates the carrier signal by registering a listener for using period . receives all incoming measurements by overriding the OnSensorChanged function from implementing the SensorEventListener interface. For each incoming sensor measurement, computes the time period of sequential measurements. Next, when uses the encoder, the decoder filters the received multiplexed frequency according to: whether the inferred period is the syncword and, if so, setting the SyncwordReceived flag; closing the receiver if the ending period is then received, ; appending ‘0’ the receiver buffer, , if the period is (with a tolerance, ); and appending ‘1’ if the received period is from the multiplexing effect triggered by ’s encoder.
The encoder and decoder require suitable syncword, target, carrier, and the ending/post-amble sampling periods. It was observed that lowering these periods caused measurements to be multiplexed into ’s signal at a higher rate, thereby increasing the channel’s throughput. Based on preliminary trials while transmitting 100 random 64-bit bit-strings, several factors must be considered for setting these rates:
[start=1,label=[O0]:]
The transmitter’s syncword period, , must be sufficiently shorter (faster) than the receiver’s carrier period, , i.e. .
If , then measurements are returned using the carrier signal’s period—activated prior to the syncword—for both applications. This inhibits ’s detection of to signal the start of data transmissions.
[start=2,label=[O0]:]
The transmitter’s post-amble period, , must be shorter than the carrier period and sufficiently distinct from the syncword frequency, i.e. .
If , then, like [O1], the receiver will not detect the transmitter’s post-amble due to the propagation of the lowest requested period (highest frequency) when multiple applications request the same sensor. Secondly, interference will occur between the syncword and post-amble if and are not distinct.
[start=3,label=[O0]:]
The transmission signal period, , must be shorter than and differ from the syncword and post-amble, satisfying .
The reasons are similar to [O1] and [O2]: to prevent interference between competing frequencies, while also allowing the receiver to reliably detect transitions between and to distinguish between transmitted bit values.
[start=4,label=[O0]:]
The post-amble and syncword periods should be shorter (faster) than the period of the transmission signal, .
If (see [O1]), then the post-amble may be triggered during the transition between and . infers the current sampling frequency from sequential measurements, which is complicated by Android’s lack of real-time guarantees when delivering sensor measurements [1, 9]. During 15% of our initial trials, was triggered prematurely during and transitions; even moving averages and other smoothing measures did not robustly solve this. However, setting the post-amble and syncword rates to be faster than the target rate significantly improved channel reliability. The above observations were used to structure the sensor sampling period hierarchy as such:
(1) |
[start=5,label=[O0]:]
The frequency hierarchy must account for significant temporal jitter between sensing modalities.
Sampling jitter complicated the ability to precisely infer the current sampling period. According to Android: “Physical sensors sometimes have limitations on the rates at which they can run and the accuracy of their clocks. To account for this, the actual sampling frequency can differ from the requested frequency as long as it satisfies the [following] requirements.” [1]. If the requested frequency is below the min. frequency, then between 90%–110% of the min. frequency must be returned. If the request is between the min. and max. frequency, then 90%–220% of the requested frequency must be returned. Lastly, if the request is above the max. supported frequency, then 90%–110% of the max. frequency must be returned, but below 1100Hz [1].
The effect of sensor jitter was studied by sampling each sensor at its maximum supported rate on each device (Table 1). 10,000 measurements were collected per sensor and per device, before calculating the inferred sampling period between each measurement using the (microsecond-level) time between consecutive SensorEvent objects. Note that sensor measurements are managed internally in Android using FIFO FMQs, thus accurate period inferencing is possible using the timestamps contained in sequential SensorEvent objects [6].
Figure 4 shows the distributions of the inferred sampling periods. In general, the jitter varies significantly between sensors and devices. These differences likely arise from varying sensor manufacturing tolerances and implementation differences in proprietary, OEM-specific sensor HALs. To overcome this, an error threshold, (10%), was used for locking into an inferred sampling period as a global limit. The MF sensor exhibited the lowest jitter on our tested devices (0.5% error from the mean, Xiaomi Poco F1 and Google Pixel 4A; no MF sensor on the Moto G5). The AC, GR and LA sensors were the next best performing (1–2%, Xiaomi Poco F1; 2%, Pixel 4A; 2.5%, Moto G5). The GY and RV exhibited the largest jitter (2–4%, Xiaomi Poco F1; 2%, Pixel 4A; 2.5–5%, Moto G5). It is notable that jitter tends to increase when the minimum supported sampling period decreases (based on the distributions of the fastest sensors: AC, GY, and RV).
[start=6,label=[O0]:]
The requested sampling period can significantly differ from the period at which measurements are returned.
It was also noticed that the requested sampling period can vary significantly from the actual period observed by an application (Figure 5). On the Xiaomi Poco F1, the GR, LA and RV sensors exhibited step function-like behaviour, and regularly over-sampled the requested period. In the worst case, the GR and LA sensors sampled at a 40% faster rate (e.g. 70ms requested period). This also differed between sensor manufacturers on the same device: the least precise sensors (GR and LA) belonged to an undisclosed Qualcomm sensor, while the most precise—the AC, GY and MF sensors—were provided by Bosch BM160 and AKM AK0991x units. The RV sensor also consistently over-sampled, albeit without the step-like function of the GR and LA sensors. Generally, the Google Pixel 4A exhibited the best response rates, with all actual periods fell within 95% of the requested period, and exceeding 99% in many cases (e.g. 10ms, 70ms, and 80ms). Only two Moto G5 sensors responded well to different requested sampling periods: the AC and GY sensors (from Bosch). The remaining sensors operated under a mono-frequency model; only a single frequency was returned irrespective of the requested frequency. This prevented the use of different sampling frequencies for our covert channel, and so these modalities were removed from further consideration.
This section evaluates our inter-application covert channel using the six continuous sensors from §4.3.
For each device, the average error rate and throughput (bit rate) of the proposed covert channel was evaluated. The pulse width—the length of time between transmitting individual bit values—was the dominating factor for the channel’s throughput. Intuitively, the shorter the pulse width, then the greater the bit rate due to the lack of real-time measurement delivery guarantees. We measured 100 transmissions of 64-bit random sequences on a per-sensor and per-device basis. For each configuration, pulse widths were evaluated in the following range: the minimum width was the shortest before triggering total channel failure (no bits detected by the receiver). The width was increased until error-free transmission was achieved (across 100 bit-strings) or the error rate was unchanged. In total, 74 configurations were evaluated across the devices and sensors.
Appropriate sampling bands (Eq. 1) were derived from the minimum supported period for each device sensor as the base (highest) frequency. The other frequencies were derived from multiples of this period; for instance, for GY with a minimum period of 5000 (Xiaomi Poco F1), then , , , and . Where this method could not be used, e.g. sensors with step-like responses, the next supported, distinct sampling rate at a higher period was used. The full set of sampling bands used on each device is provided in Appendix A.
Each channel instantiation created data files on and with the transmitted and received bit-strings, channel IDs and timestamps on a per-sensor and per-pulse width basis. The timestamps corresponded to immediately before the encoder procedure (-side) and following the post-amble signal (-side). Following the experiments—completed over two day periods with assistance from three volunteers—the files were retrieved from the three devices for off-line analysis. The average (median) bit rate was calculated for each pulse width, device, and sensor, as well as the transmission error rate using the Levenshtein (edit) distance between the bit-strings. This metric, also used in [35, 12, 24, 26, 28], computes the insertions, deletions and substitutions needed to revert the received bit-string to the transmitted one. We observed that bit deletions/omissions were the primary source of transmission errors from the absence of measurement delivery guarantees.
The experimental results are presented in Figure 6. For each sensor, very low transmission error rates were attained on at least one evaluation device for each sensor; the best-case rates are shown in Table 2. The AC sensor was able to achieve near-zero error rate using a pulse width of 75ms (Pixel 4A and Poco F1), corresponding to a 10bps bit-rate; both devices produced no error over 100 channel tests using a 150ms pulse width with a bit-rate at 5.1bps. The Moto G5 AC sensor, however, produced significant error (12 edit distance), even at the longest pulse widths (e.g. 300ms). MF was the next best performing sensor, achieving error-free transmission for the Poco F1 (100ms width, 9.62bps); however, the Pixel 4A required a longer pulse width to achieve the same results (175ms, 5.08bps). The GR sensor achieved near error-free transmission (0.215 average edit distance) with a 7.28bps bit rate using a 150ms pulse width for the Pixel 4A. The Poco F1 did not achieve this until a 350ms pulse width (2.81bps). In the best case, the RV sensor achieved the lowest error rate of an average 0.636 edit distance at 15ms (6.70bps) using the Pixel 4A. The LA sensor fared significantly worse, but still achieved error free transmission at 2.89bps with the Pixel 4A.
Intriguingly, the covert channel performs the best on the most capable, highest cost device (Pixel 4A), and executes with high error and with only two sensors on our oldest, lowest cost handset (Moto G5). On this latter device, error-free channels were not observed: the best case edit distances were 12.61 and 8.86 (AC and GY), and required significantly longer pulse times, thereby producing lower bit-rates than the other devices. This leads to the conjecture that more expensive handsets—presumably manufactured at higher prices per unit with higher quality components—are inherently more vulnerable to high bit-rate, low-error transmission using our technique.
Sensor | Pulse (ms) | Error (Edit) | Bit Rate (bps) | Device |
AC | 150 | 0 | 5.10 | Poco F1 + Pixel 4A |
GR | 150 | 0 | 7.37 | Pixel 4A |
GY | 150 | 0.215 | 7.28 | Poco F1 |
LA | 350 | 0 | 2.89 | Poco F1 |
MF | 100 | 0 | 9.62 | Poco F1 |
RV | 150 | 0.636 | 6.70 | Pixel 4A |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Beyond random bit-strings, we also investigated the efficacy of transferring images and other data types. This better represents a realistic scenario where a disguised legitimate app, e.g. file manager or image editor, leaks sensitive data to a receiver which transfers it from the device. Accordingly, experiments were conducted in transferring high resolution photographs using three-stage process: encoding the desired image using a one-bit colour palette; transmitting the encoded bit-string; and exporting the bit-string in a suitable image format, e.g. PNG. and were performed using a Python script using NumPy, SciPy, and the Python Image Library (PIL). Example image transfers are shown in Figure 7. We were also successful in transmitting bit-encoded GPS coordinates by encoding and segmenting decimal values as 4-bit strings. Communicating natural language is more difficult, e.g. leaking SMS records or instant messages. This requires an appropriate character encoding scheme that preserves the contents with low error and reasonable throughput; given the low communication bit rate (10bps for near-error free transfers), individual character transmissions thus take 1000ms using ASCII or another 8-bit encoding scheme.
It was previously shown that the activity of sensor-enabled applications can be deduced by malicious observer applications. A second attack vector was discovered that enables one to fingerprint, and to even individually identify, the nature and identity of victim, sensor-enabled apps based on their sensor usage patterns. This was achieved in two ways: detecting the use of default Android sampling periods used by mobile application developers; and the detection of bespoke sampling frequencies set by application developers.
For the first, Android’s Sensors SDK provides app developers with four preset sampling frequency constants [9]: gaming controllers (SENSOR_DELAY_GAME, 20ms); UI interactions, e.g. gesture recognition (SENSOR_DELAY_UI, 60ms); and detecting screen orientation changes (SENSOR_DELAY_NORMAL, 200ms). The fourth, SENSOR_DELAY_FASTEST, polls at the maximum supported frequency. The first three rates aim to provide an optimal trade-off that maximises utility while minimising battery consumption from long-polling sensors [7]. Using these constant values is not mandatory, however; developers may set their own custom sampling frequencies. In this section, we describe how a malicious observer application can essentially create unnaturally long carrier signals waves into which these specific sampling frequencies are modulated.
The threat model assumes a malicious app, (e.g. disguised as a legitimate app) that wants to detect changes in the device’s orientation, the use of sensor-driven games, UI interactions, or to otherwise identify a sensor-enabled victim app, . may aim to perform this continuously and transparently in real-time for user/device profiling. The goal is for to perform this without requiring additional permissions that may reveal its intentions upon installation. As stated, the attack exploits different sampling frequencies requested by , which are modulated into a long carrier frequency established by . This is achieved using three steps:
Malicious Set-up: registers listener(s) for one or more sensors using their lowest supported sampling frequency (highest period).
Victim Execution: Unwittingly, registers another listener at another frequency for the same sensor, whether that is a pre-defined period, e.g. SENSOR_DELAY_GAME for games, or a custom frequency. Due to multiplexing, the signal observed by is modulated to this higher frequency registered by . consumes the received measurements for its intended purpose before eventually de-registering the listener.
Malicious Execution: Concurrently, infers ’s sampling period and compares to a pre-defined period to detect the type of interaction used by , or even its identity if it uses a known sensor/sampling frequency combination.
This process is illustrated in Figure 8, with an optional fourth state for recording the interaction. (Note: and are interchangeable. If is performed first, then the faster frequency used by will already be returned to when it requests values at an extremely slow frequency.)
The and apps from §4 were modified for inferring the victim sampling frequencies from a malicious observation app. Unlike §4, however, one cannot assume that a particular sensor will be used a priori. That is, how can detect multiplexed sampling period changes of an arbitrary sensor used by ? To address this, we developed to receive measurements from all six continuous sensors concurrently (Listing 1). Registering listeners for multiple sensors simultaneously is permitted behaviour under the Android framework. However, the inferred periods of each target sensor must be maintained independently. Correspondingly, six decoders are needed in practice for each of the six continuous sensors. Unlike the covert channel decoder (Algorithm 2), instead of testing for , , etc., we compared the inferred periods to each of the four aforementioned Android sampling period constants.
We implemented to register a sensor at random when requested by the user at a sampling period corresponding to one of the pre-defined Android SDK constants. The time at which activated the sensor, as well as the sampling period, were written to file for off-line analysis. was developed to store the timestamp and the inferred sampling period when one of the aforementioned constant values was detected. Alongside the timestamp, detected sensor and sampling period, we added channel IDs similar to our covert channel test-bed in order to straightforwardly pair interactions between and .
This section evaluates the accuracy and latency of our proposed fingerprinting method.
Initial trials were conducted where was set to run persistently in the background. This created signals for all six target sensors in parallel using their maximum supported frequencies. Next, was opened for an initial 25 trials per sensor, device, and sampling period. Similar to our covert channel, we observed that many of the actual inferred frequencies do not strictly reflect those specified in the Android SDK [7]. For two devices, the observed periods still broadly reflected the Android SDK, albeit within a 10% error band (Tables 3–5). Similarly, a 10% error tolerance was used. We also observed that a small minority of sensors returned measurements at the maximum supported period when the SENSOR_DELAY_NORMAL period was requested. Notwithstanding, the observed rates were still individually distinguishable from a long-period carrier signal in most cases.
It also became apparent that, in some cases, could not discriminate between the signals transmitted by on certain devices. That is, could not distinguish certain SensorManager sampling period constants used by when multiplexed into ’s carrier signal. For instance, the SENSOR_DELAY_NORMAL sampling period on the Xiaomi F1’s AC and GY sensors is the maximum supported period. Consequently, these periods used by cannot be distinguished from ’s carrier frequency. Moreover, the Motorola Moto G5’s mono-frequency reporting caused issues once more. The GR, LA, and RV sensors could not be distinguished from the maximum period for the same reason. These problematic sensors were disregarded from further consideration.
In total, 20/24 (83.3%) cases could be successfully detected on the Xiaomi Poco F1 and Google Pixel 4A, while 6/20 (30%) of cases were detectable with the Motorola Moto G5. A breakdown of the distinguishable cases is shown in Tables 3–5. After identifying the cases where individual sampling periods could be reliably discriminated, we conducted further trials whereby was activated and was used to trigger a desired sensor using one of the aforementioned constant sampling periods. This was performed 100 times per sensor, per sampling period, and per device, amounting to 4,600 logged interactions in total between and .
Sensor | Fastest | Game | UI | Normal | Max. |
AC | 2.484 | 19.83 | 66.67 | 198.6 | 198.6 |
GR | 4.961 | 19.89 | 79.41 | 198.7 | 198.6 |
GY | 4.968 | 19.87 | 66.67 | 198.6 | 198.6 |
LA | 4.961 | 19.89 | 79.48 | 198.6 | 198.6 |
MF | 10.0 | 20.00 | 66.67 | 200.0 | 1000 |
RV | 4.166 | 16.64 | 55.59 | 166.6 | 833.3 |
Legend — Green: distinguishable using the max. period as the reference period; Red: indistinguishable.
Sensor | Fastest | Game | UI | Normal | Max. |
AC | 2.346 | 18.77 | 65.70 | 197.1 | 976.2 |
GR | 4.693 | 18.77 | 65.70 | 197.1 | 197.1 |
GY | 2.346 | 18.77 | 65.70 | 197.1 | 976.2 |
LA | 14.08 | 18.77 | 65.70 | 197.1 | 197.1 |
MF | 9.956 | 19.58 | 66.67 | 195.9 | 979.5 |
RV | 4.693 | 18.77 | 65.70 | 197.1 | 197.1 |
: Erroneously returned the SENSOR_DELAY_GAME period when SENSOR_DELAY_FASTEST was used.
Sensor | Fastest | Game | UI | Normal | Max. |
AC | 9.934 | 19.98 | 59.68 | 198.6 | 198.6 |
GR | 5.026 | 9.893 | 9.941 | 9.890 | 9.915 |
GY | 4.944 | 19.87 | 59.59 | 198.6 | 198.6 |
LA | 4.958 | 9.893 | 9.863 | 9.879 | 9.901 |
RV | 4.950 | 9.906 | 10.03 | 9.926 | 9.918 |
: Failed to return SENSOR_DELAY_FASTEST when multiplexed into the maximum period.
: GY was modulated when RV was activated. (Note: RV is a virtual sensor that uses GY as input.)
The malicious application correctly detected the sensor and sampling period used by the victim in every distinguishable case without error during our experiments. With respect to detection latency, the average latencies for each sensor, device, and constant are presented in Figure 9. On average, a given sensor and sampling constant could be detected by the malicious observer in under 500ms. Unsurprisingly, the faster/shorter the sampling period used by the victim application, the quicker the malicious application could detect it. This is caused by the way in which our procedure infers a sensor’s sampling period using sequential sensor events. The faster rate that a victim application requests, the faster the malicious application can process the multiplexed events and detect the sampling period requested by the victim.
In the best cases, the detection latency was reduced to 80ms when the victim used the sensor’s fastest sampling rate, reaching under half this (40ms) in a minority of cases (e.g. the Pixel 4A’s AC and RV sensors). At the opposite end, the victim’s sampling period could be inferred in 400ms where SENSOR_DELAY_NORMAL was used. The SENSOR_DELAY_UI constant could be detected in 250ms for all devices and sensors, and 150ms for the Pixel 4A and Moto G5. SENSOR_DELAY_GAME, meanwhile, could be detected in 100ms, and 60ms for the Pixel 4A and Moto G5. The detection latency is largely consistent for the Pixel 4A. Interestingly, in contrast to the covert channel, the Moto G5 performed relatively well where multiple sensor periods could be distinguished relatively consistently. The Poco F1 was less consistent, where the GR and GY sensors required somewhat longer to detect the chosen period than the other sensors. In general, the detection latency is both device- and sensor-dependent, but, in all cases, this could be achieved in under half a second on all test devices.
As a final step, we investigated whether sensor-enabled mobile applications could be fingerprinted using identifiable sampling behaviour. To this end, the sensor usage and sampling periods of 10 popular mobile apps were investigated as a proof-of-concept. These applications were chosen from their suspected use of continuous-mode sensors: Doodle Jump, an arcade game with 50M+ user downloads (DLs); Google Fit, (50M+ DLs); Google Maps (5B+ DLs); Modern Combat 5 (100M+ DLs); Pokémon Go (100M+ DLs); PlayerUnknown’s Battlegrounds (PUBG) Mobile (500M+ DLs); Real Racing 3 (100M+ DLs); Star Tracker (5M+ DLs); Uber (500M+ DLs); and Waze (100M+ DLs).
Firstly, the malicious observer app was launched that registered listeners for all supported device sensors. Next, each target app was opened 25 times and, where required, main menus, login dialogs and other intermediate interfaces were bypassed to reach the main activity where sensors were utilised. This caused a sampling frequency modulation of ’s registered sensor listeners, which were subsequently logged to file and then analysed. Table 6 shows the detected sensor(s) and sampling period(s) for each test application.
The results demonstrate that precise sensor usages, sampling rates and their combinations vary widely across widely used mobile apps. Consequently, it is possible to use this information as discriminating features for in-use application identification. Across the evaluated apps, only Uber and Google Fit shared the same sensors and sampling periods (AC: 10ms, MF: 20ms). A unique combination of these parameters was used in the remaining cases. The target sensors and sampling rates were hard-coded into our malicious observer app as a set of expert rules for identifying individual applications. On a per-app basis, we were able to deduce applications based on these parameters without error and in real-time. In an attack scenario, malicious actors may implement a dictionary/database of known frequency-application mappings to infer active sensor-enabled apps in a covert, unprivileged fashion.
Application | Detected Sensors |
Doodle Jump | AC (10ms) |
Google Fit | AC (10ms), MF (20ms) |
Google Maps | AC (10ms), GR, LA, MF (20ms) |
Modern Combat 5 | GY (15ms) |
Pokémon Go | AC (10ms), GR, GY, MF, LA (20ms), RV (16ms) |
PUBG Mobile | AC, GY, MF (20ms) |
Real Racing 3 | AC (20ms) |
Star Tracker | AC (20ms), RV (13ms) |
Uber | AC (10ms), MF (20ms) |
Waze | AC, GR, LA (20ms), MF (67ms) |
Legend — Green: Unique sensor parameter combinations; Yellow: Conflicting parameters with another app.
Wider security issues from mobile sensors are not new (see §2). To counter this, Android 9 introduced security updates for visibly indicating to users when high-frequency, long-polling sensors are used. In this section, these changes are examined how they are ultimately unsatisfactory for addressing our attacks. We discuss UI-, API-, and system-level countermeasures that thwart the attacks, and suggest recommendations.
From Android 9 (API level 28), applications cannot use background services to access sensors in continuous reporting mode; if this is attempted, sensor events are not returned to the calling application. Instead, apps must use foreground services that are visible to the user using a taskbar notification in order to raise the users’ awareness of on-going background processing. This notification is removed only when the service is stopped. To access sensor services, Android application manifest files must contain the FOREGROUND_SERVICE permission. Unfortunately, this leads to the first issue: FOREGROUND_SERVICE is a normal permission that, according to the Android project, the associated “data and actions present very little risk to the user’s privacy” [5]. As such, Android OS automatically grants it to the requesting application. Unlike so-called ‘dangerous’ or run-time permissions—e.g. accessing SMS messages, call logs, and location data [4]—normal permissions do not require approval via a dialog prompt. A malicious application can thus access sensor services to mount our attacks without requiring explicit user approval.
Secondly, foreground service notifications are heavily customisable (Figure 10). The notification heading, text body, and icon can all be manipulated with minimal restrictions by a malicious developer, which could be used to masquerade as a legitimate application. A UI countermeasure is to require applications to display the full set of active registered sensor listeners in the foreground service notification. This would indicate any unusual or unwanted sensor usage that strays beyond the application’s expected remit. Yet, using the technical names of sensors is likely to prompt user confusion; referring to the class of sensors in use, e.g. ‘motion’ or ‘position’, may be more appropriate. A usability investigation for indicating potentially dangerous sensors to users is warranted.
From the design of the Sensors SDK, a robust countermeasure, which prevents both attacks, is to remove control from application developers by eliminating the sampling period parameter from registerListener in the Sensors SDK. Instead, the appropriate sampling rate could be inferred and returned to the application at an operating system level.
Recommendation 1: Consider removing the ability to directly set sensor sampling periods. By adopting this measure, malicious apps are unable to establish carrier signals at a desired frequency, thereby preventing both presented attacks.
The root cause of both attacks is the design of returning measurements at the fastest sampling rate when multiple apps request the same sensor. The ultimate solution is to enforce that the requested sampling period is the one which is received by an application. This is the case used by Apple iOS devices, which we were not able to successfully exploit in the same way. Unfortunately, this countermeasure imposes core changes to how the Android framework multiplexes sensor events to applications and services.
Recommendation 2: Enforce requested sampling periods on a per-app basis. This prevents both attacks by stopping malicious apps from exploiting software multiplexing using higher frequency signals registered by other apps.
The presented attacks work optimally where malicious apps leverage unused shared sensors. We stress that our attacks cannot be mounted where a third application is already using a sensor at the highest frequency such that frequency bands cannot be established. In these cases, it makes sense for attackers to target under-used modalities, such as gravity and linear acceleration sensors, where available. It is also possible for malicious apps to detect cases where a sensor(s) are already being used at its fastest rate. This can be achieved by registering multiple sensors, i.e. Listing 1, and comparing the inferred rate with the highest supported frequency using getSensorList() from the SensorManager API.
In this paper, we presented two approaches for exploiting design choices in mobile sensor stacks for covert channels and application fingerprinting. Specifically, we show how software-based multiplexing can result in reliable methods using frequency-key shifting. Neither technique imposes special requirements or privileges—for example, a rooted handset or kernel-mode access—beyond the standard Sensor SDK functions available to Android developers.
In §4, a new spectral covert channel was presented for transmitting arbitrary bit-strings between two unprivileged, same-device applications that bypassed existing IPC protection mechanisms. This was achieved using a carrier frequency established by a receiver app, which was modulated by a transmitted app that requested a higher sensor sampling frequency. It was empirically shown how many physical and virtual continuous sensors could be used for this purpose, including accelerometers, gyroscopes, and magnetic field sensors, with very low error rates. Indeed, the transmission of low-resolution yet legible single-bit images was possible.
In §5, a variant was developed for fingerprinting sensor-enabled mobile applications in a coarse-grained way. This involves a malicious app that generated multiple sensor signals at their maximum supported periods simultaneously. Victim apps that used the same sensor(s) at a higher frequency thus triggered modulations in the malicious app’s signal, which could be used for detecting particular interactions (e.g. UI interactions, screen orientation changes, and gaming activity). On average, this could be achieved 30–400ms depending on the requested sampling period, sensor, and device. Moreover, we also showed how some widely used apps use particular sensor and sampling frequency combinations, which can be leveraged for application identification.
Ultimately, both methods arise from inherently insecure design choices; all of our evaluation devices from disparate OEMs were vulnerable, potentially affecting millions of devices worldwide. Interestingly, higher-end test handsets, e.g. Google Pixel 4A, were the most susceptible to the covert channel method, exhibiting the lowest error and latency, while all devices were susceptible to our fingerprinting technique. In §6, we suggested two recommendations for remediating the vulnerabilities: removing the ability for developers to set precise sensor sampling periods; and enforcing the requested sampling periods by removing the multiplexing functionality. Unfortunately, these necessitate design-level changes to the Android sensor stack.
This work has received funding from the EU’s Horizon 2020 research and innovation programme under grant agreement No. 88315 (EXFILES).
International Joint Conference on Neural Networks
, pp. 381–388. Cited by: §1.Distributed Computing and Artificial Intelligence
, pp. 173–184. Cited by: §1.This appendix provides the precise parameters used for each device and sensor for establishing FSK-based covert channels. These are shown in Tables 7–9.
Sensor | ||||
AC | 10000 | 7500 | 5000 | 2500 |
GR | 40000 | 20000 | 10000 | 5000 |
GY | 20000 | 15000 | 10000 | 5000 |
LA | 40000 | 20000 | 10000 | 5000 |
MF | 25000 | 20000 | 15000 | 10000 |
RV | 20000 | 15000 | 10000 | 5000 |
Sensor | ||||
AC | 10000 | 7500 | 5000 | 2500 |
GR | 20000 | 15000 | 10000 | 5000 |
GY | 10000 | 7500 | 5000 | 2500 |
LA | 50000 | 40000 | 30000 | 20000 |
MF | 25000 | 20000 | 15000 | 10000 |
RV | 20000 | 15000 | 10000 | 5000 |
Sensor | ||||
AC | 40000 | 30000 | 20000 | 10000 |
GY | 30000 | 20000 | 10000 | 5000 |