mirror of
https://github.com/librespot-org/librespot.git
synced 2026-04-27 08:15:50 +03:00
[GH-ISSUE #36] Prevent MITM by authenticating Spotify servers #27
Labels
No labels
A-Alsa
SpotifyAPI
Tokio 1.0
audio
bug
can't reproduce
compilation
dependencies
duplicate
enhancement
good first issue
help wanted
high priority
imported
imported
invalid
new api
pull-request
question
reverse engineering
wiki
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/librespot#27
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @sashahilton00 on GitHub (Jan 29, 2018).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/36
Thursday Oct 27, 2016 at 12:29 GMT
Originally opened as https://github.com/plietar/librespot/issues/125
librespot doesn't have any way of authenticating Spotify's server, and will happily send the username and password to a MITM proxy. I don't know what the official client does about it.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Thursday Oct 27, 2016 at 12:54 GMT
The connection does not use TLS at all, so the certificate Spotify uses for their website is irrelevant.
My best guess is https://github.com/plietar/librespot/blob/master/protocol/proto/keyexchange.proto, the
gs_signaturefield in theLoginCryptoDiffieHellmanChallengestruct.We would need to find the public key and algorithm used to check that signature. Also relevant are the
server_keys_knownandserver_signature_keyfields in that same file.@sashahilton00 commented on GitHub (Jan 29, 2018):
Monday Nov 07, 2016 at 06:51 GMT
openssl s_client -connect apresolve.spotify.com:443presents a valid cert, but that's just *.spotify.com.Did you eavesdrop on the connection and auth-negotiation of a certified device? Our lab just got an onkyo-avr that has built-in spotify-support - so if need be I could try to set up wireshark to have a look at the connections beeing made during zeroconf auth.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Tuesday Nov 08, 2016 at 18:53 GMT
I'm not quite sure which part of the protocol you're referring to. There are basically 3 network connections :
Zeroconf authentication only runs on your local network, and is encrypted (not authenticated, but there's no way of doing that since you don't know the device anyway). Your password is never sent though, only a token.
Resolving the AP uses http, with optional TLS. librespot currently does not use https for reasons explained in #124. Encryption is pretty pointless, and like I explained there, there's no point authenticating that part if the connection to the AP in not authenticated, and similarily, authenticating it isn't necessary if we authenticate the next part.
Finally authenticating the connection to the AP is what I would like to implement, and is what this issue is about. This is a proprietary protocol, with it's own exotic encryption and authentication. It isn't based on SSL/TLS at all, and makes no use of certificates.
Encryption is already implemented (that was necessary to get it working), but authentication isn't, and I'm not 100% sure how it is done, but my comment just above describes my initial thoughts on it. The next steps would be disassemble the relevant part from Spotify's binaries, figure out the crypto algorithm, where the inputs come from, build a simple MITM and see how the client behaves, and implement it here.
@sashahilton00 commented on GitHub (Jan 29, 2018):
Wednesday Aug 16, 2017 at 01:34 GMT
If you're still interested in this:
server_keys_knownis a bitmask of all known signature keys (i.e.1 << server_signature_keyfor all keys the client knows). So far there's only one key being used (key id 0).gs_signatureis the RSA (RSASSA-PKCS1-v1_5) signature ofgs, signed using the key identified byserver_signature_key. The public key (e, n) is hardcoded inside the Spotify client.Here's a simplified version of the code I use to verify the signature:
@sashahilton00 commented on GitHub (Feb 8, 2018):
We should probably implement this at some point.
@devgianlu commented on GitHub (Apr 10, 2019):
@timniederhausen Can you confirm this still works?
The server key seems to be the same as it's still present inside the client.
@timniederhausen commented on GitHub (Apr 10, 2019):
Yes, nothing's changed.
My MITM tool still works (if I replace the public key in the client).
@devgianlu commented on GitHub (Apr 11, 2019):
What do you mean by that?
@timniederhausen commented on GitHub (Apr 11, 2019):
Instead of hooking functions in the client to dump the packets it sends/receives, I built a small tool that acts as a MITM between the Spotify client and the AP. For that to work, I have to replace the public key in the client with my own, as otherwise the MITM tool cannot create a correct
gs_signature.All of that still works, which means they haven't changed that process.
@devgianlu commented on GitHub (Apr 11, 2019):
Got it. Are you able to provide some debug values (
gs,gs_sig,gs_hash) from the script? I'm trying to implement this in Java and I can't get my head on top of it because crypto algorithms behave a bit differently.Sorry for bothering you.
@timniederhausen commented on GitHub (Apr 12, 2019):
I'm not sure what you mean.
gsandgs_signatureare insideLoginCryptoDiffieHellmanChallenge, so getting them is easy. Andgs_hashis simply the SHA-1 hash ofgs.If you really need some example values (all hex-encoded):
I guess you could use Java's Signature class to do the verification but I haven't really looked into that.
@sashahilton00 commented on GitHub (Apr 12, 2019):
@timniederhausen the proxy you have sounds interesting. I assume you're using it in conjunction with sp-analyze to examine the packets in realtime?
@devgianlu commented on GitHub (Apr 13, 2019):
Thank you @timniederhausen, I finally managed to implement it (
github.com/librespot-org/librespot-java@aa17da7f36)@timniederhausen commented on GitHub (Apr 14, 2019):
So far I'm only dumping all packets (including the initial ones, i.e. ClientHello etc.) to a
.pcapfile, which can be analyzed later on.I'll probably add support for the more complicated Hermes stuff as well, as I don't want to implement that in the Wireshark dissector.
I could post some binaries of the MITM tool if you're interested.