In iTunes shop, all musics and ringtones have 30 seconds preview. Ringtones are always less than 30 seconds. That means the ringtone previews are always in full length. If we can hear it, we can download it (for free, of course). This article is to share on how to download ringtones and add to your iPhone for free. It works for all ringtones in iTune Store. The main intention is to use this as an example to illustrate common practices in network hacking.
First, get a network log of iPhone’s ringtone preview traffic. To do this, setup a sniff-able wifi environment. This might be difficult for some people, but I have an existing environment. All my internet traffic goes through my linux router, so I simply run tcpdump there. I use wireshark to analyze the saved dump file.
When I play a ringtone preview, I see the this request:
http://a1778.phobos.apple.com/us/r1000/031/Music/9c/22/14/mzi.wphahwgb.aac.p.m4p. (Lucky it’s not https. If it’s https, I have to try self signed certificate and see if it can pass the check.) Quickly do a direct wget. I get error 403 forbidden. First reaction is user agent. Change UA to iPhone. succeed.
$ wget -U 'Apple iPhone OS v3.1.3 CoreMedia v188.8.131.52E18' 'http://a1778.phobos.apple.com/us/r1000/031/Music/9c/22/14/mzi.wphahwgb.aac.p.m4p'
--2010-04-09 01:53:43-- http://a1778.phobos.apple.com/us/r1000/031/Music/9c/22/14/mzi.wphahwgb.aac.p.m4p
Resolving a1778.phobos.apple.com... 184.108.40.206, 220.127.116.11
Connecting to a1778.phobos.apple.com|18.104.22.168|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 493781 (482K) [text/plain]
Saving to: “mzi.wphahwgb.aac.p.m4p”
100%[=============================================================>] 493,781 256K/s in 1.9s
2010-04-09 01:53:45 (256 KB/s) - “mzi.wphahwgb.aac.p.m4p” saved [493781/493781]
Feed the m4p to a media player. It plays.
Up to here, we can already download the ringtone. Just follow previous steps and get the m4p url. It’s not very convenient though, as we have to use iphone and sniff to get the url. I want to get rid of the iphone step. I want to have a script to download a ringtone given it’s name, or have a script to download top 100 ringtone of a given genre.
For the top 100 script, I found out the url of top ringtone listing by genre to be something like
http://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewTop?selected-tab-index=0&top-ten-m=1%27%3B1&genreId=8004. However, the viewTop page requires sign-in. There are two ways to deal with sign-in. The hardworking way is to figure out the sign-in protocol and implement it. Usually it requires posting user id and password and get a session id. The dirty way is to sniff and get the session id, but we can only use the session before it expires. I’m not going into details about this. Here is the wget command to download the page. It’s a bit long because of those special X-apple-* headers. You can’t use it because 1. the session has expired; and 2. I have modified some of those IDs for my privacy. The page is an xml containing titles, artists, purchasing information, preview-url (the most important one for us), user ratings, etc.
wget -O - --header 'X-Apple-Store-Front: 143441-1,2' --header 'X-Apple-Partner: origin.0' --header 'X-Apple-Connection-Type: WiFi' --header 'X-Apple-Cuid: 068c5db16ca2b6956f7d582690613b68' --header 'X-Apple-Software-Cuid: 6a26ef98bfc6b1ef6f00694e61735a64' --header 'X-Dsid: 1369530585' --header 'X-Apple-Client-Application: WiFi-Music' --header 'Cookie: mz_at0=xQQUAABxlwAABABLsXbOCow79QEJcf6OqeR9C9ya+U87hxY=; mzf_in=180805; X-Dsid=1369530585; a=A2dAjgAAABtjAlRWMEsHtXFZZzAvdWlodAFxSTs5Ak1yOTjaSG9lYmtLdWcjKgsQAAdAJ5BiPTt=; Pod=18; s_cvp35b=%5B%5B%27google%253A%2520organic%27%2C%271369276708021%27%5D%2C%5B%27192.168.0.1%253A8000%27%2C%274278433477967%27%5D%5D; s_vi=[CS]v1|25C941528801054F-70001710E0178F3F[CE]; s_vnum_sg=ch%3Dip%26vn%3D1%3B; s_vnum_us=ch%3Dlegal%26vn%3D1%3Bch%3Dwebapps%26vn%3D3%3Bch%3Dip%26vn%3D2%3Bch%3Ddeveloper%26vn%3D1%3B' -U 'iTunes-iPhone/3.1.3 (2)' 'http://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewTop?selected-tab-index=0&top-ten-m=1%27%3B1&genreId=8004'
There are many articles teaching how to add ringtones to iphone. I briefly describe here.
- Rename to .m4r
- Import (drag) to iTunes. It should appear under the ringtone directory in iTunes. Note: Don’t manually manage music and ringtone. Add to iTunes and sync. I tried the first way and failed miserably. I hate iTunes.
- You may want to change the metadata. Alternatively, before importing to iTunes, you can use opensource tools like mp4tags from libmp4v2 to change metadata. I prefer mp4tags, because it works in command line so that I can run in batch.
- You should see the new ringtone in your iPhone.
So is it possible for apple to prevent this? I can think of a few solutions, but none of them work well.
- Do not provide preview. Customers won’t be happy.
- Add noise to preview. Shorten it to 10 seconds. Customers won’t be so happy.
- Use https or a custom protocol. “If we can hear it, we can download it.” It only makes hackers taking longer time. But, hey, hackers are the group of people having least money and most time.