Nemirwen's corner

Computer graphics, linux, and more from the cyberwitch's hut

Retrieving MMS from the CLI on android

While debugging an issue with Silence who stubbornly refused to download any MMS, it started to look a lot like those multimedia messages were simply downloaded from a server using familiar internet protocols.

And to my surprise, I was somewhat right!

A bit of background

The act of "recieving an MMS" is actually a two step process:

The URL in question looks something like this: http://<mmsc_ip>/mms.php?xxxxxxxxxxxxxxxxxxxxxx

The devil is in the details

That "simple HTTP GET request" I just mentioned? Yeah, well there are a few subtleties to get right. Most importantly, your requests need to actually originate from the device that was the recipient of the MMS, and to be coming from inside the service provider's network (though some service providers support an option called "wifi calling" that apparently allows you to retrieve MMS from the internet).

Additionally, even if you ask the MMSC nicely for your precious MMS, connecting from the correct interface, you might still end up empty-handed. Indeed, you need to provide a few specific headers for your request to be considered acceptable.

I got those headers from Silence's source code, and ended up with this barebone script (fortunately busybox's wget supports --header):

#!/system/bin/sh

wget \
--header="Accept: */*, application/vnd.wap.mms-message, application/vnd.wap.sic" \
--header="x-wap-profile: http://www.google.com/oha/rdf/ua-profile-kila.xml" \
--header="Content-Type: application/vnd.wap.mms-message" \
--header="x-carrier-magic: http://magic.google.com" \
-O mms.bin \
"$1"

Running it netted me the following (edited for privacy):

A screenshot of the file opened in vim,
showing a mix of binary, html,
and the nearly plaintext message at the end.
The file we got back from the MMSC

Also, keep in mind that MMS aren't kept for long on the MMSC. From what I heard (don't quote me on that), they last around a week.

Also also, some service providers put their MMSC behind a proxy, check your APN settings and add export http_proxy=<proxy>:<port> and -Y as needed.

Meet WSP and SMIL

After we get our response from the MMSC, this is where things take a turn away from the "nice and standard", and right into "weird and legacy".

On the one hand, you have the Wireless Session Protocol (WSP) (sometimes called the WAP Session Protocol), which in our case is mainly relevant as a bandwidth saver. As a matter of fact, one of the main pros of WSP in this context is its use of binary tokens and values to replace string headers in something that would otherwise look a lot like HTTP. For example the first two bytes of the message, 0x8c 0x84, are used to represent the X-MMS-Message-Type: m-retrieve.conf string.

On the other hand, you've got the Synchronized Multimedia Integration Language (SMIL), which is a markup language that originated as a way to make presentation slides, and somehow ended up being used as the backbone of MMS distribution...

I won't look any further into parsing the combination of WSP encoding and SMIL markup because the encoded plaintext was readable enough for my needs, though I'm curious to see what an image or video MMS looks like.

Further reading

How MMS Works by now.sms

Downloading an MMS using a USB modem by Lain Dooley on StackOverflow

breakthesilence: a tool to extract MMS notification messages from Silence's encrypted data exports

MMS Protocol overview by now.sms