2025-04-12 04:27 UTC
I think I understand why the USB exploit analyzed by Amnesty International uses both a virtual Extigy sound card and a FastTrackPro sound card.
https://securitylab.amnesty.org/latest/2025/02/cellebrite-zero-day-exploit-used-to-target-phone-of-serbian-student-activist/
It took me 6 weeks to notice: in the logs, the Extigy and the FastTrackPro sound cards are not two virtual devices.
They're one device with two interfaces.
Which explains why the device "morphs":
- it first returns Extigy as the USB VID/PID in its device descriptor
- the Extigy quirk causes Linux to re-fetch the device descriptor
- the Amnesty analysis points out that you can return a bigger bNumConfigurations in the new device descriptor to cause an out-of-bound read+free on disconnect
- but you can also return a different VID/PID - say, the FastTrackPro VID/PID
- and Linux will use that VID/PID to probe the next audio interface:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/card.c;l=773;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
Now you have a device with both a corrupted bNumConfigurations - and with VID/PID set to FastTrackPro, which now triggers FastTrackPro quirks.
The original writeup identifies that, like the Extigy, the FastTrackPro has quirks that are only run for that VID/PID.
Amnesty speculates that the attacker uses the FastTrackPro "to confirm that the memory corruption primitive CVE-2024-53197 is functional".
The writeup looks at the skip_setting quirk:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/quirks.c;l=1598;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
but there's also this boot quirk, which switches the device's configuration:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/sound/usb/quirks.c;l=1652;drc=bc9dca02d645353bd4ff789c5a3a20064923889b
This calls to usb_set_configuration(dev, 2), which reads bNumConfigurations and looks for configuration #2.
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/drivers/usb/core/message.c;l=2007;drc=9f2a3933beeaeead53829d3a7be53770e41e7869
So if you wanted to confirm that your heap manipulation worked, in your fake `struct usb_host_config`, set 2 as your bConfigurationValue.
usb_set_configuration will read the corrupted bNumConfigurations and start reading `struct usb_host_config`s out of bounds.
If it finds configuration #2, it means your fake is located in the right place, right after the Extigy/FastTrackPro's own `struct usb_host_config`s.
And since the search doesn't dereference anything, you can't crash.
Replies (1)
-
@zhuowei@notnow.dev 2025-04-12 20:16
Actually, I'm wrong: once you overwrite the VID/PID from Extigy to FastTrackPro, you can't trigger the Extigy overwrite again, Even if you used the FastTrackPro to detect when your heap spray failed, you can't do anything to clean up, and you'll crash anyways on device disconnect. So maybe they used the FastTrackPro because the out of bound access in `usb_set_configuration` is easier to exploit than the out of bound access->arbitrary free in `usb_destroy_configuration`?