Myspace plugin - help needed
#1
Hey,
I'm planning to write a plugin for myspace so you can listen to bands before going to concerts etc.
Does anyone have a flash decompiler handy and could help me to circumvent their weird mp3 url hiding/obfuscation?
I'd be happy to do the python coding and I would really appreciate your help with this!
Reply
#2
Maybe this helps? I'm scared of AJAX.
http://www.myspace-mp3-downloader.com/sr...bandmp3.js
http://www.myspace-mp3-downloader.com/
Reply
#3
There is nothing special about AJAX... its just an HTTP get that gives you back an XML file. It looks like that gets parsed and "purl" points to the mp3... still there are several stages in this thing... it'd be good to step through it a bit in a debugger.

Actually that purl has to be unencrypted in some weird thing...

Code:
function decodeUrl(bandid, songid, token, durl) {
  var key = hexToByteArray('ba44f75f53e02be7871f241ccbed2debe44b50035af66e932a438e55bb4e76cb');
  var ct = hexToByteArray(encodeHex(decodeBase64(token)));
  var result = rijndaelDecrypt(ct, key, "CBC");
  var trim = byteArrayToString(result).substring(16, 59);
  var p = encodeBase64(durl);
  return durl + '?bandid=' + bandid + '&songid=' + songid + '&token=' + trim + '&p=' + p + '&a=0';
}

wtf is "rijndaelDecrypt"?
Reply
#4
Asteron Wrote:wtf is "rijndaelDecrypt"?
This is actually AES.
Reply
#5
I just sniffed some packets. Looks like they're really desperately trying to hide this URL. Now that's what I call link protection. damn it. This ajax thing is even worse. It doesn't contact myspace directly, but through some proxy php script. I'm not sure if we should use that..
Here is a CSV with the GET request, but without the responses (was too lazy to pick them all out):
Code:
"53", "5.054162", "192.168.1.129", "216.178.38.121", "HTTP", "GET /prostituiertengang HTTP/1.1"
"80", "5.920820", "192.168.1.129", "81.169.145.72", "HTTP", "GET /media/myspace_thx.jpg HTTP/1.1"
"89", "6.068342", "192.168.1.129", "195.50.169.72", "HTTP", "GET /music/musicplayer.swf?n=aHR0cDovL211c2ljLm15c3BhY2UuY29t&t=1mjRAmxrajzCyg1+mRBA5enXeYTDCdUUpJxkvhoPv929PBDZbCh0gXqcdDjvC33qoJ9bIXcFMIX9gjfXusq+2Q==&u=LTE=&a=0&d=ODI2Nzg5ODJeMTE5MDA1NzE5MQ== HTTP/1.1"
"186", "6.295223", "192.168.1.129", "195.50.169.80", "HTTP", "GET /isf.gif HTTP/1.1"
"196", "7.151980", "192.168.1.129", "216.178.38.230", "HTTP", "GET /services/media/musicplayerxml.ashx?b=82678982 HTTP/1.1"
"202", "7.755287", "192.168.1.129", "216.178.38.230", "HTTP", "GET /services/media/mediahitcounter.ashx?i=MIGdBgorBgEEAYI3WAOjoIGOMIGLBgorBgEEAYI3WAMBoH0wewIDAgABAgJmAwICAMAECNMmF4m00iwGBBBtRlEXvULzFp2Q0bFfFn4EBFDOhGmkK%2bh3jyl3DnhlCgWVmQ3mCWXse%2fX%2blfi85re2Pu8%2bh5qLIgrABViNry%2ftkqIlEff3aCJDXrO%2b9jb4mnJUstuFJdArFJgQy%2brNiPqRtg%3d%3d HTTP/1.1"
"208", "7.786097", "192.168.1.129", "195.50.169.82", "HTTP", "GET /BandSongs/28/98/82678982/bs14786337_m.gif HTTP/1.1"
"212", "7.952421", "192.168.1.129", "216.178.38.230", "HTTP", "GET /services/media/token.ashx?b=82678982&s=14786337&f=0 HTTP/1.1"
"217", "7.978253", "192.168.1.129", "195.50.169.82", "HTTP", "GET /BandSongs/28/98/82678982/bs14786337_m.gif HTTP/1.1"
"222", "8.198279", "192.168.1.129", "195.50.169.72", "HTTP", "GET /music/start_beacon.txt?c=22966259 HTTP/1.1"
"233", "8.259963", "192.168.1.129", "193.108.95.55", "HTTP", "GET /63/std_9eb6f885d7216d9771b4ce1d7e3d38f8.mp3?bandid=82678982&songid=14786337&token=1190081854_295e6fbf5da4718f49ee58a200418ed1&p=aHR0cDovL2NhY2hlMDgtbXVzaWMwMi5teXNwYWNlY2RuLmNvbS82My9zdGRfOWViNmY4ODVkNzIxNmQ5NzcxYjRjZTFkN2UzZDM4ZjgubXAz&a=0 HTTP/1.1"
Reply
#6
This is also interesting:
http://64.233.183.104/search?q=cache:tCp...d=13&gl=de
Reply
#7
Okay, so here is how it works:
1. get http://myspace.com/[friendname]
2. extract numeric friend_id from html
3. get the song list: http://mediaservices.myspace.com/service...ml.ashx?b=[friendid]
4. curl=song url, token=token, encrypted with Rijndael
5. Download URL will be:
[songurl]?bandid=[bandid]&songid=[songid]&token=1[decrypted token]&p=[song url on base64]

This seems to be only valid for a minute or so, then the token gets deleted I guess.
Man, that's really creepy.
Reply
#8
We can use this for rijndael:
http://www.postneo.com/2005/03/31/more-p...o-rijndael

and use the key from:
http://www.myspace-mp3-downloader.com/sr...bandmp3.js , search for "var key="

I already spent some hours fiddling around with this. I would be amazed and really appreciate it if somebody could write the routine to extract the friend_id from the myspace html! Anyone?
Reply
#9
Unbehagen Wrote:if somebody could write the routine to extract the friend_id from the myspace html! Anyone?

you mean something like this:

2 rather easy ways to get to the FriendID

make a HEAD request for the myspace.com/[friendname] page, and grab from the response-header this line: Set-Cookie: g23=[friendid]; path=/

or retrieve the whole html-page and search for it using some regex:
Code:
result = re.search(r'"DisplayFriendId":(\d+)', htmlpage)
if result:
    FriendId = result.group(1)

good luck! Smile
Reply
#10
Thanks for your help, mortael. Here's what I have yet, it runs on a pc, no xbmc yet:
Code:
import urllib
import httplib
import pyrijndael
import sys
import xml.dom.minidom
import base64

playlistattribs=["title","songid","plays","comments","rate","downloadable","imagename","imagedesc","filename","url","lyrics","purl","durl","token","curl"]

def getfriendid(bandname):
        conn = httplib.HTTPConnection("www.myspace.com")
        conn.request("GET", "/"+urllib.quote_plus(bandname))
        r1 = conn.getresponse()
        headers= r1.getheaders()
        conn.close()
        for header in headers:
                if header[0]=='set-cookie':
                        cookieelements=header[1].split("; ")
                        for element in cookieelements:
                                if element.startswith("path="):
                                        pathG23path=element.split(", ")
                                        for param in pathG23path:
                                                if not param.startswith("path"):
                                                        friendid=param.split("=")[1]
        return friendid

def HexToByte( hexStr ):
    bytes = []
    hexStr = ''.join( hexStr.split(" ") )
    for i in range(0, len(hexStr), 2):
        bytes.append( chr( int (hexStr[i:i+2], 16 ) ) )
    return ''.join( bytes )

def toHex(s):
    lst = []
    for ch in s:
        hv = hex(ord(ch)).replace('0x', '')
        if len(hv) == 1:
            hv = '0'+hv
        lst.append(hv)
    return reduce(lambda x,y:x+y, lst)

def decrypttoken(token):
        key = HexToByte('ba44f75f53e02be7871f241ccbed2debe44b50035af66e932a438e55bb4e76cb');
        ## don't know why the author of the javascript did this fromtohex, but i just copied it:
        tok= HexToByte(toHex(base64.decodestring(token)));  
        return pyrijndael.DecryptData(key,tok)

def getsonglist(friendid):
        conn = httplib.HTTPConnection("mediaservices.myspace.com")
        conn.request("GET", "/services/media/musicplayerxml.ashx?b="+friendid)
        r1 = conn.getresponse()
        return r1.read()

def parse_songlist(songlistdata):
        songlist=[]
        dom = xml.dom.minidom.parseString(songlistdata)
        plist = dom.getElementsByTagName("playlist")[0]
        songs=plist.getElementsByTagName("song")
        for song in songs:
                songdata={}
                for attrib in playlistattribs:
                        songdata[attrib]=song.getAttribute(attrib)
                songlist.append(songdata)
        return songlist

friendid=getfriendid(sys.argv[1])
songlist=parse_songlist(getsonglist(friendid))
for song in songlist:
        print song['title']
        print song['token']
        print decrypttoken(song['token'])
I tried two rijndael libraries without any luck....
http://jclement.ca/software/pyrijndael/p...1_4.tar.gz
http://www.postneo.com/2005/03/31/more-p...o-rijndael

They both give errors or complain about wrong block sizes. I figured out that the Rijndael-"CBC"-Encryption is used, but I could not find any library for that. All help is appreciated.
Reply
#11
http://fernyb.net/myspace/api/
For python coding questions first see http://mirrors.xbmc.org/docs/python-docs/
Reply
#12
I always knew MySpace had some weird methods used for the inner workings, but GOD DAMN thats crazy!
Catchy Signature Here
Reply
#13
SleepyP Wrote:I always knew MySpace had some weird methods used for the inner workings, but GOD DAMN thats crazy!
Yep I think it's because they want to create a shop later (or do they already have one?) for selling mp3s. But they don't actually seem to use their weird security token stuff; i commented out everything regarding that. Did anybody experience any difficulties with this plugin other than no title showing up for some artists (This is because of malformed XML or weird carachters. I currently don't have a solution for that.) ? Please report any problems playing MP3s here so I can fix that.
Reply

Logout Mark Read Team Forum Stats Members Help
Myspace plugin - help needed0