In combination with the shady traffic found in this thread, I also came across another unfortunate thread:
Very not impressed with this āPremiumā service. Of course I give no microphone permissions on a degoogled GrapheneOS, but its still insulting to pay to be spied on.
I wonder if they try to scan files on android like they do desktop? Luckily file Discretionary Access Control (DAC) sandboxing has become a thing to mitigate this. Application Sandbox Ā |Ā Android Open Source Project
In adb there are the failed attempts to load GMS ads identifier:
And a failed attempt to read my serial identifier via TelephonyPermissions:
So despite having paid for premium to remove ads, but they still add ads to some podcasts. Thatās double dipping.
Unfortunately the ads come through the same severs as the music so they arenāt filtered out by the pihole, very irritating:
https://open.spotify.com/ad/%s
Why am I paying to listen to ads? This is not acceptable.
So I did a little digging with the attempt to try and get rid of those ads by perhaps patching out the call. Ban me spotfiy I dont care, I refuse to pay to listen to ads.
In the process I found a concerning string: s_voice_ad_inaudible_tone_enabled
My noteās are a little old but here we go. The sample used was the snap package version.
The process path said
/snap/spotify/56/usr/share/spotify/spotify
I couldnāt find that path. Turns out snaps are mounted with their own virtual filesystem, and the actual .snap stored in
/var/lib/snapd/
Source: Managing Ubuntu Snaps: the stuff no one tells you | HackerNoon
I found spotify binary in
/var/lib/snapd/snaps/spotify_56.snap
Unzipping didnt work. To get into the snap, I had to mount with squashfs and dump the contents to a directory
sudo mount -t squashfs -o ro /var/lib/snapd/snaps/spotify_56.snap /path/to/extract/spotify
Source: How do I view the contents of a .snap file? - Ask Ubuntu
Now, digging through the extracted files (and following the path our original process was running) we find the actual binary in
<extractedPath>/usr/share/spotify/spotify
Open the binary in Ghidra. Once analyzed: Search > For Stringsā¦
Filter for āadā, sorted alphabetically by āString Viewā.
And right away we find some interesting enteries:
002a262d ?? 2Fh / "/v1/ads/:slot" string 14 false
002c3b54 ?? 2Fh / "/v1/events/:event/:ad_id" string 25 true
002abb2f DAT_002abb2f ?? 2Fh / "/v1/playlist/:playlist-uri/metadata" string 36 true
002956ea ?? 2Fh / "/v1/podcast/metadata" string 21 true
002d7356 ?? 2Fh / "/v1/podcast/nextAdSegment" string 26 true
002d72ed ?? 2Fh / "/v1/preview/:ad_id" string 19 true
002c1371 ?? 2Fh / "/v1/settings/:slot/ad_server_endpoint" string 38 true
0028c28b ?? 2Fh / "/v1/settings/request_header/:header" string 36 true
002ba844 ?? 2Fh / "/v1/testing/click_ad" string 21 true
00299a1f DAT_00299a1f ?? 2Fh / "/v2/metadata" string 13 true
002d3e17 ?? 2Fh / "/v2/settings/ad_server_endpoint" string 32 true
002bd001 ?? 2Fh / "/v2/settings/state/ad_state_endpoint" string 37 true
002c586b ?? 2Fh / "/v2/testing/insert_ads" string 23 true
Some more:
0028e53e s_active_ads_0028e53e ds "active_ads" "active_ads" string 11 true
002c151b s_ad_fetch_error_(_002c151b ds "ad fetch error (" "ad fetch error (" string 17 true
00290fce s_Ad_format_(_00290fce ds "Ad format (" "Ad format (" string 12 true
002957e6 s_ad_missing_id_002957e6 ds "ad missing id" "ad missing id" string 14 true
002d9391 s_Ad_not_found_for_provided_ad_id_002d9391 ds "Ad not found for provided ad_id" "Ad not found for provided ad_id" string 32 true
002a27d5 s_ad_parse_error_-_002a27d5 ds "ad parse error - " "ad parse error - " string 18 true
002a6f22 s_ad_response_error_(_002a6f22 ds "ad response error (" "ad response error (" string 20 true
0029796f s_ad-logic/flashpoint_0029796f ds "ad-logic/flashpoint" "ad-logic/flashpoint" string 20 true
002c80ee s_ad-logic/state/config_002c80ee ds "ad-logic/state/config" "ad-logic/state/config" string 22 true
002cc6d9 s_ad-session-persistence_002cc6d9 ds "ad-session-persistence" "ad-session-persistence" string 23 true
00299ca3 s_ad-state-storage.bnk_00299ca3 ds "ad-state-storage.bnk" "ad-state-storage.bnk" string 21 true
002b88e5 s_ad-use-adlogic_002b88e5 ds "ad-use-adlogic" "ad-use-adlogic" string 15 true
002a6f10 s_ad.is_saved_track_002a6f10 ds "ad.is_saved_track" "ad.is_saved_track" string 18 true
00295818 s_ad.non_explicit_00295818 ds "ad.non_explicit" "ad.non_explicit" string 16 true
002d3ff2 s_ad.original_provider_002d3ff2 ds "ad.original_provider" "ad.original_provider" string 21 true
002bf4fc s_ad.token_002bf4fc ds "ad.token" "ad.token" string 9 true
0029344c s_ad.video_orientation_0029344c ds "ad.video_orientation" "ad.video_orientation" string 21 true
002c147b s_ad_break_in_progress_002c147b ds "ad_break_in_progress" "ad_break_in_progress" string 21 true
002dc2e4 s_ad_break_state_002dc2e4 ds "ad_break_state" "ad_break_state" string 15 true
002c80ce s_ad_break_time_002c80ce ds "ad_break_time" "ad_break_time" string 14 true
0034abb0 s_ad_core_sponsored_session_0034abb0 ds "ad_core_sponsored_session" "ad_core_sponsored_session" string 26 true
002b091b s_ad_disallow_002b091b ds "ad_disallow" "ad_disallow" string 12 true
002c58b2 s_ad_enabled_002c58b2 ds "ad_enabled" "ad_enabled" string 11 true
002a6d5b s_ad_id_002a6d5b ds "ad_id" "ad_id" string 6 false
0029df74 s_ad_injection_seek_0029df74 ds "ad_injection_seek" "ad_injection_seek" string 18 true
002abe4e s_ad_manager_002abe4e ds "ad_manager" "ad_manager" string 11 true
002957c9 s_ad_not_sponsored_by_rewarder_002957c9 ds "ad_not_sponsored_by_rewarder" "ad_not_sponsored_by_rewarder" string 29 true
0028e3ff s_ad_playback_0028e3ff ds "ad_playback" "ad_playback" string 12 true
002bd05a s_ad_playback_id_002bd05a ds "ad_playback_id" "ad_playback_id" string 15 true
002c1490 s_ad_rule_disallows_002c1490 ds "ad_rule_disallows" "ad_rule_disallows" string 18 true
002a4555 s_ad_server_endpoint_002a4555 ds "ad_server_endpoint" "ad_server_endpoint" string 19 true
002d93c8 s_ad_slot_id_002d93c8 ds "ad_slot_id" "ad_slot_id" string 11 true
002b892f s_ad_state_pusher_error:_%s_002b892f ds "ad_state_pusher error: %s" "ad_state_pusher error: %s" string 26 true
002bd052 s_ad_type_002bd052 ds "ad_type" "ad_type" string 8 true
And some more:
0034ab80 s_core-ads_0034ab80 ds "core-ads" "core-ads" string 9 true
0034aba3 s_core-ads_0034aba3 ds "core-ads" "core-ads" string 9 true
0034abcb s_core-ads_0034abcb ds "core-ads" "core-ads" string 9 true
0034ac30 s_core-ads_0034ac30 ds "core-ads" "core-ads" string 9 true
00290fe9 s_core-podcast-ad-requester_00290fe9 ds "core-podcast-ad-requester" "core-podcast-ad-requester" string 26 true
00337130 s_core-podcast-ads_00337130 ds "core-podcast-ads" "core-podcast-ads" string 17 true
00337180 s_core-podcast-ads_00337180 ds "core-podcast-ads" "core-podcast-ads" string 17 true
003350d0 s_core-podcast-ads-feature_003350d0 ds "core-podcast-ads-feature" "core-podcast-ads-feature" string 25 true
00335120 s_core-podcast-ads-feature_00335120 ds "core-podcast-ads-feature" "core-podcast-ads-feature" string 25 true
002ceabd s_core-proxy-ad-requester_002ceabd ds "core-proxy-ad-requester" "core-proxy-ad-requester" string 24 true
00334178 s_core-voice-ad_00334178 ds "core-voice-ad" "core-voice-ad" string 14 true
Ooh! An advertisement URL -> https://open.spotify.com/ad/%s
002a1d1a s_https://open.spotify.com/ad/%s_002a1d1a ds "https://open.spotify.com/ad/%s" "https://open.spotify.com/ad/%s" string 31 true
And of course more:
002dd036 s_injected-ad_002dd036 ds "injected-ad" "injected-ad" string 12 true
0029dfdc s_invalid_ad_error__0029dfdc ds "invalid_ad_error_" "invalid_ad_error_" string 18 true
002c4ce8 s_invalid_download_error__002c4ce8 ds "invalid_download_error_" "invalid_download_error_" string 24 true
0029f1e8 s_is_advertisement_0029f1e8 ds "is_advertisement" "is_advertisement" string 17 true
002b642c s_is_cpcl_ad_002b642c ds "is_cpcl_ad" "is_cpcl_ad" string 11 true
0029d0cc s_is_podcast_advertisement_0029d0cc ds "is_podcast_advertisement" "is_podcast_advertisement" string 25 true
00383e60 s_isAvailableInMetadataCatalogue_00383e60 ds "isAvailableInMetadataCatalogue" "isAvailableInMetadataCatalogue" string 31 true
00354ff7 s_isLoading_00354ff7 ds "isLoading" "isLoading" string 10 true
00326080 s_isLoadingContents_00326080 ds "isLoadingContents" "isLoadingContents" string 18 true
002abad0 s_isPremiumOnly_002abad0 ds "isPremiumOnly" "isPremiumOnly" string 14 true
002cead5 s_skippable_ad_delay_002cead5 ds "skippable_ad_delay" "skippable_ad_delay" string 19 true
002b3f8e s_spotify:ad:_002b3f8e ds "spotify:ad:" "spotify:ad:" string 12 true
00290693 s_spotify:ad:%s_00290693 ds "spotify:ad:%s" "spotify:ad:%s" string 14 true
002ba87b s_test_ad_002ba87b ds "test_ad" "test_ad" string 8 true
0028c2af s_The_ad_slot_could_not_be_trigger_0028c2af ds "The ad slot could not be triggered" "The ad slot could not be triggered" string 35 true
002ce91c s_The_ad_slot_has_not_been_created_002ce91c ds "The ad slot has not been created yet" "The ad slot has not been created yet" string 37 true
002bd10d s_too_many_redirect_ads_002bd10d ds "too_many_redirect_ads" "too_many_redirect_ads" string 22 true
002c811c s_TriggerAdNotSuccessEvent_002c811c ds "TriggerAdNotSuccessEvent" "TriggerAdNotSuccessEvent" string 25 true
002bd172 s_TriggerAdSuccessEvent_002bd172 ds "TriggerAdSuccessEvent" "TriggerAdSuccessEvent" string 22 true
0028e51d s_triggered_ad_duration_0028e51d ds "triggered_ad_duration" "triggered_ad_duration" string 22 true
002b40a5 s_triggered_dummy_ad_duration_002b40a5 ds "triggered_dummy_ad_duration" "triggered_dummy_ad_duration" string 28 true
00295837 s_UpdatePendingAd_NextContext_00295837 ds "UpdatePendingAd_NextContext" "UpdatePendingAd_NextContext" string 28 true
002a6f36 s_UpdatePendingAd_Stream_002a6f36 ds "UpdatePendingAd_Stream" "UpdatePendingAd_Stream" string 23 true
002af8ec s_UpdatePendingAdEvent_002af8ec ds "UpdatePendingAdEvent" "UpdatePendingAdEvent" string 21 true
Hmm, another URI? This looks like a callback redirect URI
002cc5b9 s_Usage:_GET_sp://ads/v1/ads/<slot_002cc5b9 ds "Usage: GET sp://ads/v1/ads/<slot>" "Usage: GET sp://ads/v1/ads/<slot>" string 34 true
Oh, you thought that was it for ad related strings...
00337150 s_use_new_podcast_ad_segments_prov_00337150 ds "use_new_podcast_ad_segments_provider" "use_new_podcast_ad_segments_provider" string 37 true
002af805 s_useAdvertiserImage_002af805 ds "useAdvertiserImage" "useAdvertiserImage" string 19 true
0029cad1 s_user_space_0029cad1 ds "user space" "user space" string 11 true
002caadc s_Users_002caadc ds "Users" "Users" string 6 true
002cc185 s_video/ad_002cc185 ds "video/ad" "video/ad" string 9 true
002b6492 s_VND.Spotify.Ads-Payload_002b6492 ds "VND.Spotify.Ads-Payload" "VND.Spotify.Ads-Payload" string 24 true
002ca2bc s_voice_ad_002ca2bc ds "voice_ad" "voice_ad" string 9 true
002920ac s_voice_ad_audio_sink_002920ac ds "voice_ad_audio_sink" "voice_ad_audio_sink" string 20 true
00293151 s_VoiceAdBuilder_00293151 ds "VoiceAdBuilder" "VoiceAdBuilder" string 15 true
002af483 s_VoiceAdCosmosBuilder_002af483 ds "VoiceAdCosmosBuilder" "VoiceAdCosmosBuilder" string 21 true
Now this string is particularly interesting and mildly concerning:
00334190 s_voice_ad_inaudible_tone_enabled_00334190 ds "voice_ad_inaudible_tone_enabled" "voice_ad_inaudible_tone_enabled" string 32 true
An inaudible tone huh?!
I highly suspect this to be an Ultrasonic Beacon:
Ultrasonic beacons are sounds with frequencies from 18 kHz to 20 kHz. Humans canāt hear it, but most mobile devicesā microphones can easily detect the ultrasonic beacons. When emitting from retail stores or embedded to advertisements and even websites, these inaudible sounds are picked up by microphones of mobile devices.
I have not confirmed this.
When I find the time I might revisit this. Iād like to maybe set up some sort of test with a microphone to confirm. Techniques for detecting this are described here: https://www.sec.cs.tu-bs.de/pubs/2017a-eurosp.pdf