[00:01.410 --> 00:05.070] Hello everyone. Thank you for attending this talk. [00:05.510 --> 00:09.090] I'm Slava. I'm a security researcher at CheckPoint. [00:09.430 --> 00:12.710] Security research is my daily work. [00:12.930 --> 00:16.190] Today I'm going to show how an Android application [00:16.190 --> 00:20.050] can attack the digital signal processor of a mobile device [00:20.430 --> 00:24.890] and thereby gain privileges and denial-of-service capabilities. [00:29.600 --> 00:31.880] Let's begin with a question. [00:31.880 --> 00:36.360] Do you know how many processors are on your mobile phone? [00:36.400 --> 00:38.640] The answer is many. [00:38.660 --> 00:42.720] As a single Snapdragon system on a chip embedded in Pixel, [00:42.720 --> 00:46.640] Samsung, Xiaomi, LG, OnePlus, Sony and other devices [00:46.640 --> 00:50.180] may include multiple CPU cores, [00:50.180 --> 00:52.920] an Adreno graphic processor unit, [00:53.000 --> 00:55.040] a Snapdragon wireless module, [00:55.160 --> 00:57.340] a Hexagon digital signal processor, [00:57.340 --> 01:00.240] and Spectro image signal processor. [01:00.240 --> 01:03.580] Snapdragon product tiers are differentiated [01:03.920 --> 01:09.680] by scalable computing resources for the CPU, GPU and DSP. [01:09.680 --> 01:14.900] The lowest tiers might contain only a single Hexagon DSP, [01:14.900 --> 01:17.240] whereas the premium tier contains [01:17.980 --> 01:20.580] up to four Hexagon DSP processors [01:20.860 --> 01:23.580] dedicated for specific use cases. [01:24.300 --> 01:30.000] These are modem DSP, known as baseband audio DSP, [01:30.000 --> 01:33.020] compute DSP, and sensor DSP. [01:33.040 --> 01:40.620] In this research, I turned my attention to ADSP and CDSP subsystems. [01:41.420 --> 01:45.580] ADSP and CDSP processors are intended for such cool tasks [01:45.580 --> 01:49.460] as processing of audio and voice data, [01:49.460 --> 01:52.580] computer vision, machine learning calculations, [01:52.580 --> 01:57.280] camera streaming, artificial intelligence, etc. [01:57.280 --> 02:02.480] On some devices, such as the Sony Xperia XZ, [02:02.480 --> 02:07.860] only the ADSP processor is responsible for all these tasks. [02:07.860 --> 02:12.240] But on other devices, such as the Pixel 4, [02:12.240 --> 02:17.680] these tasks are shared between ADSP and CDSP. [02:18.680 --> 02:21.460] Let's take a look at the communication scheme [02:21.460 --> 02:26.100] between an Android application and a DSP running library. [02:27.620 --> 02:31.650] FasterPC is a Qualcomm proprietary RPC mechanism [02:31.940 --> 02:35.620] used to enable remote code function calls [02:35.620 --> 02:41.220] between application processor, where Android is run, and DSP. [02:41.220 --> 02:47.140] On Android side, user mode process initiates the remote invocation. [02:47.140 --> 02:49.980] In our case, an Android application calls [02:49.980 --> 02:53.630] one of the stub functions in its native code. [02:53.630 --> 03:01.990] Stub is auto-generated code that converts the function call to an RPC message. [03:01.990 --> 03:08.450] Generally, the stub code is compiled as a separate native library. [03:08.690 --> 03:15.910] The stub code loads libADSP-RPCSO and libCDSP-RPCSO built-in libraries [03:15.910 --> 03:18.870] to invoke Android drivers. [03:18.870 --> 03:24.850] DSP-RPC drivers send the queued message to the DSP side [03:24.850 --> 03:30.150] through the shared memory channel, and then wait for the response. [03:31.510 --> 03:37.270] On DSP side, a framework presented by the FasterPC shell binary [03:37.870 --> 03:43.950] dequeues the messages and dispatches them for processing by a skeleton. [03:43.950 --> 03:50.170] And again, skeleton is auto-generated library that unmashes parameters [03:50.170 --> 03:54.370] and calls the target method in the object library. [03:54.370 --> 03:59.230] The object library is some logic provided by Qualcomm or OEMs [03:59.230 --> 04:02.810] and designed to run on a DSP. [04:05.070 --> 04:08.250] Who can run their own code on DSP? [04:08.650 --> 04:13.350] Any third-party developer can implement its own DSP library. [04:13.950 --> 04:19.170] Because the Hexagon SDK, which is responsible for compiling C++ code [04:19.170 --> 04:23.130] into Hexagon bytecode, is publicly available. [04:23.510 --> 04:28.850] But it's impossible to run a third-party library on DSP. [04:28.930 --> 04:34.170] For security reasons, DSP is licensed for programming by OEMs [04:34.590 --> 04:39.030] and code running on the DSP is signed by Qualcomm. [04:41.060 --> 04:43.760] Who manages the DSP? [04:43.760 --> 04:49.960] It's Qt, a Qualcomm proprietary multi-threaded real-time operating system. [04:49.960 --> 04:53.980] Integrity of the Qt is trusted by the trust zone. [04:53.980 --> 04:59.540] Qt executable binary, different for ADSP and CDSP, [04:59.540 --> 05:05.200] is assigned and split into several files in the same way [05:05.200 --> 05:09.800] as any other trusted application on Qualcomm devices. [05:10.740 --> 05:15.280] For each Android process initiating the remote invocation, [05:15.280 --> 05:20.280] Qt creates a separate faster PC shell process on the DSP. [05:20.640 --> 05:26.320] The DSP architecture provides different protection domains, PD. [05:26.540 --> 05:31.020] Kernel PD has access to all memory of all domains. [05:31.020 --> 05:34.740] Guest OS PD has access to the memory of its own PD [05:34.740 --> 05:39.780] and memory of the user PD and some system registers. [05:40.580 --> 05:45.000] User PD has access only to its own memory. [05:45.820 --> 05:50.640] Skeleton and object libraries, as well as the fast RPC shell, [05:50.640 --> 05:53.200] are running in the user PD. [05:55.650 --> 06:02.310] The stub code provided by Qualcomm or OEMs can be skipped from the fast RPC chain. [06:03.010 --> 06:08.130] As was mentioned, libADSP-RPC and libCDSP-RPC libraries [06:08.130 --> 06:13.430] are responsible for communication with DSP-RPC drivers. [06:13.810 --> 06:18.570] Each library exports two major functions. [06:18.570 --> 06:23.470] Remote handle open function opens a remote session between the client [06:23.470 --> 06:29.490] on application processor and new fast RPC shell process on the DSP. [06:29.970 --> 06:34.150] The skeleton library name is provided as the first argument. [06:34.150 --> 06:41.770] Remote handle invoke function is able to invoke methods exported by the skeleton library. [06:41.930 --> 06:49.070] Using these two functions, an Android application can request to execute any skeleton method [06:49.070 --> 06:52.330] without using a stub code. [06:53.730 --> 06:58.730] Now we have enough information to state the downgrade vulnerability. [06:59.010 --> 07:03.610] DSP libraries are signed and cannot be patched. [07:03.610 --> 07:09.430] However, any Android application can bring a signed by Qualcomm skeleton library [07:09.430 --> 07:13.810] in its assets and then open a remote session. [07:13.910 --> 07:19.730] The library will be successfully loaded on the DSP because its signature is correct. [07:21.070 --> 07:25.850] The fact that there is no version check of loading skeleton libraries [07:25.850 --> 07:29.790] opens the possibility to run a very old skeleton lib [07:30.660 --> 07:34.050] with known one-day vulnerabilities on the DSP. [07:34.050 --> 07:39.470] Even if the patched skeleton library already exists on the device, [07:39.470 --> 07:43.730] it is possible to load the old version of this library. [07:44.070 --> 07:50.070] Any DSP code fix can be simply bypassed by an attacker. [07:51.070 --> 07:55.750] Due to the lack of leads of the skeleton libraries permitted for the device, [07:55.750 --> 07:59.670] it is possible to run a library intended for one device, [07:59.670 --> 08:04.990] for example, Chinese Xiaomi, on any other device, for example, Samsung. [08:05.010 --> 08:11.270] This means that a vulnerability discovered in one of OEM libraries [08:12.070 --> 08:15.390] compromises all Snapdragon-based Android devices. [08:17.710 --> 08:23.730] The major goal of the research was to find a way to execute custom code on a DSP [08:23.730 --> 08:26.830] bypassing Qualcomm's signature. [08:27.030 --> 08:34.650] To do so, we had to discover and exploit a vulnerability in a DSP-running library. [08:36.270 --> 08:40.270] DSP libraries are proprietary hexagon ELFs. [08:40.390 --> 08:43.130] The easiest way to instrument a hexagon executable [08:43.130 --> 08:47.610] is to use the open-source QUIC emulator, QEMU. [08:48.190 --> 08:55.790] Hexagon instruction set support was added in QEMU only in the end of 2019. [08:56.030 --> 09:03.050] We fixed a lot of bugs to be able to run real DSP libraries in the user mode of the emulator. [09:03.970 --> 09:11.490] To fast leaps on Ubuntu PC, we used American Fuzzy Loop, AFL, in combination with QEMU. [09:11.490 --> 09:17.310] A skeleton library is primarily a library, and we had to prepare a simple program, [09:17.590 --> 09:21.270] a scale loader, that loads and invokes the one. [09:21.630 --> 09:28.430] Moreover, most skeleton libraries widely use DSP framework and system calls. [09:28.430 --> 09:31.750] Our simple program cannot handle such requests. [09:32.010 --> 09:39.870] Therefore, we had to load the cured OS on the emulator before execution of the REST call. [09:39.870 --> 09:44.530] The easiest way to do so is not to use a real cured OS, [09:44.530 --> 09:52.970] but its light version, Run-ELF-PBM, adopted by Qualcomm for execution on a hexagon simulator, [09:52.970 --> 09:55.950] and included in the hexagon SDK. [09:56.570 --> 10:02.710] That's it. The IFR permutates the content of a data file [10:02.710 --> 10:07.830] and triggers execution of Run-ELF-PBM on the emulator. [10:07.830 --> 10:14.270] QEMU returns the code coverage matrix to the AFL after execution of the test case. [10:15.590 --> 10:22.210] On this slide, you can see the data format that we used to fuzz skeleton libraries. [10:22.430 --> 10:28.750] The first word is the second argument of the remote handle invoke function. [10:28.830 --> 10:36.750] The index on the invoked method, number of input and number of output arguments are encoded there. [10:36.750 --> 10:41.410] Next several words we take as the size of arguments, [10:41.410 --> 10:46.150] then we expect to see a value of input arguments. [10:47.270 --> 10:51.050] We were surprised by the fuzzing result. [10:51.050 --> 10:56.090] Crashes were found in all DSP libraries that we choose to fuzz. [10:56.090 --> 11:02.210] Besides, most issues were discovered exactly in skeleton libraries. [11:02.210 --> 11:07.290] This means that hexagon SDK reduces vulnerable code. [11:08.970 --> 11:18.530] Hexagon SDK automatically generates stub and scale code for marshalling and unmarshalling of function arguments. [11:18.650 --> 11:22.710] Let's take a look at an example of such code. [11:25.150 --> 11:35.510] Stub and scale code based on interface definition language modus, IDL modus, prepared by the developer. [11:35.510 --> 11:44.670] Here you can see an example of the IDL declaration of two functions in the neural network library, HexagonNN. [11:44.670 --> 11:48.650] A vulnerable code will be generated for both of them. [11:50.350 --> 11:58.870] HexagonNN SMP print function passes an input-output buffer argument to the DSP. [11:58.870 --> 12:06.510] In the stub code this buffer will be split into two separate buffers, the input and the output. [12:06.510 --> 12:14.370] The value of the buffer length will also be duplicated and therefore serialized twice. [12:15.870 --> 12:24.690] The scale function copies the input of the output buffer before calling an objects function. [12:24.690 --> 12:31.290] The size of data to be copied is one of the transmitted buffer lengths. [12:31.310 --> 12:33.690] An attacker controls this value. [12:33.690 --> 12:41.010] All verification checks can simply be bypassed by using a negative input buffer length. [12:41.010 --> 12:51.090] Typecasting to the signed int type on checking buffer boundaries is a bug leading to heap overflow. [12:52.070 --> 13:08.070] To summarize, the automatically generated code injects vulnerabilities into the libraries of Qualcomm, OEMs and all other third-party developers who use the Hexagon SDK. [13:08.070 --> 13:18.570] Dozens of DSP skeleton libraries pre-installed on Android smartphones are vulnerable due to serious bugs in the SDK. [13:20.050 --> 13:26.230] So, we discovered many vulnerabilities. Let's exploit one of them. [13:27.410 --> 13:33.910] LibFastCV, a DSP-scale SO library, can be found on most Android devices. [13:33.910 --> 13:41.110] In this example, I used the lib extracted from the Sony Xperia XZ Premium device. [13:41.390 --> 13:50.150] A malicious Android application can cause this lib to crash by providing crafted arguments to the remote handling function. [13:51.550 --> 14:00.230] The 3F method allows us to read and write everything that we want within the other space of the DSP process. [14:00.230 --> 14:09.110] It's enough to implement an exploit and execute an unsigned payload in the user protection domain. [14:10.230 --> 14:14.710] Ok, we got code execution. What can we do with it? [14:14.710 --> 14:23.470] We can crash the DSP, we can hide malicious code, we can try to access camera sensors and more. [14:23.590 --> 14:28.370] Besides, now we can communicate with secured drivers. [14:29.490 --> 14:38.430] The next step of the research is to attack the Qt-privileged domains from the user protection domain. [14:38.430 --> 14:43.330] And Qt drivers are the entry points for this. [14:45.230 --> 14:53.430] QtOS implements its own device driver model, named Qt Driver Invocation, QD. [14:53.430 --> 15:00.730] Like POSIX, Qt device drivers operate with higher privileges than user code. [15:00.730 --> 15:06.650] Dozens of Qt drivers can be found in the Qt binary. [15:07.670 --> 15:15.310] libQtA library, which is part of Hexagon SDK, contains the Qt infrastructure. [15:15.310 --> 15:19.710] FasterPC shell is linked statically with the library. [15:22.370 --> 15:32.430] QD provides a simple driver invocation API with the ability to access a device driver based only on the driver name. [15:32.610 --> 15:41.250] Actually, only Qt QD handle invoke macro is the necessary user visible API. [15:41.290 --> 15:45.570] It's responsible for all generic driver operations. [15:45.910 --> 15:50.090] The Qt QD open is just a special case of this macro. [15:53.890 --> 16:05.100] To fuzz Qt drivers on Ubuntu PC, we use the same combination of Hexagon QMU and AFM, as for fuzzing of user-mode DSP libraries. [16:06.390 --> 16:13.850] Qt drivers were not included by Qualcomm in the run.elf.pdn version of Qt. [16:13.850 --> 16:18.110] Therefore, we had to patch the run.elf file. [16:18.110 --> 16:20.330] What did we do? [16:20.330 --> 16:36.550] We appended program segments of Qt.elf from a real device and redirected malloc and memcpy kernel functions used by Qt drivers to their user-mode implementation. [16:37.610 --> 16:46.730] Our simple QD exec program is responsible for calling the driver invocation function by its address. [16:48.830 --> 16:55.730] First of all, any failure in Qt drivers can be used to reboot the mobile device. [16:55.850 --> 17:06.970] For example, each of the lines of this code will cause a DSP panic and can be used for a denial-service attack on the device. [17:06.970 --> 17:14.810] For research purposes, we exploited one of the discovered vulnerabilities in glink-qt-driver. [17:14.870 --> 17:25.170] Along with the user-pd exploit, it allows us to run a custom code in the context of the guest OS protection memory. [17:27.190 --> 17:32.150] Now I'll show a simple demo to prove the full attack chain. [17:32.150 --> 17:40.370] The payload will return a DSP internal data inaccessible from application processor. [17:40.370 --> 17:43.510] The device is a Pixel 4. [17:56.510 --> 18:09.790] Here you can see that using a DB shell, I'm executing some tool which can be used by any Android application. [18:09.790 --> 18:20.590] This tool will trigger chain of vulnerabilities and return some inaccessible from application processor data. [18:20.590 --> 18:24.150] For example, Qt OS data signal. [18:24.330 --> 18:29.970] After that, I'm going to control the phone and, for example, I just reboot. [18:39.640 --> 18:51.580] Instead of a conclusion, I just want to note that hexagon ADSP and CDSP subsystem are very promising areas for security research. [18:51.580 --> 19:01.900] The DSP is accessible from Android application, has access to interesting data for an attacker, and has many security issues. [19:03.500 --> 19:05.560] Thank you for your attention.