ID3 Tag Messages

by Donald Blake

Here's a riddle...

What's the most annoying type of specification for a developer and the best type of specification for a hacker?

Answer: An informal specification.

It's difficult for the developer because they have to write code that matches the specification and they have to provide enough leeway in their code so that when it's reading a file that somewhat uses the informal specification it can still read it.  However, it's great for a hacker because they can decide what parts of the specification they want to use and throw as much of it away as they want and their application will still follow the specification.

This is why informal specifications are great vehicles for secret messages.  There are three traits to a secret message that make it a great message:

  1. Existence - No one knows about it except for the sender and receiver.
  2. Readability - No one can read it except the sender and receiver.
  3. Transportation - One that is easily transmitted, received, and destroyed.

This is why ID3 tags are awesome for secret messages.

The sizes of MP3 libraries are enormous.  My collection is around 20 gigabytes, so have fun going through it looking for secret messages.  You need a program to be able to read the ID3 tags or have an extremely keen eye.  If the ID3 tag is messed up, the MP3 will still work and MP3s are everywhere.  It's the standard media for listening to music today and it's growing.  Another added benefit of ID3 tags is they can carry any type of data.

ID3 tags are used to hold the informational data about the MP3 file.

The standard can be found at id3.org.  There have been some revisions to the standard over time.  I'm just going to go over the two most popular ones: ID3v1 and ID3v2.  ID3v1 is located at the end of the MP3 and it's the easiest one to work with because it doesn't provide very much leeway.  It has to be in total length 128 bytes long, must start with the word TAG, only has nine fields and each field has a defined set length.  And as a developer, I love this form.

The ID3v2 tag header, which should be the first information in the file, is 10-bytes as follows:

ID3v2 File Identifier: ID3 
        ID3v2 Version: $03 00
          ID3v2 Flags: %abc00000
           ID3v2 Size: 4 * %0xxxxxxx

As a hacker, I'd rather work with ID3v2 or greater.  ID3v2 tag frames should be no larger than 16 MB each and the total length of the tag should not exceed 256 MB.  They start at the beginning of the MP3 file and each ID3v2 or greater starts with a header.  The header should be 10-bytes long.  The first 3-bytes are "ID3", then the version which is 2-bytes, a byte for flags, followed by 4-bytes for the size.


MP3 Header Layout

Within each ID3v2 tag there are frames that hold the specific information for the MP3 file, such as the title of the song and/or band name.  These frames shouldn't be any larger than 16 MB each.  Each frame header is also 10-bytes long.  They start with a 4-byte frame name, 4-bytes for the size, and 2-bytes for flags.

As the tag consists of a tag header and a tag body with one or more frames, all the frames consists of a frame header followed by one or more fields containing the actual information.  The layout of the frame header:

Frame ID: $xx xx xx xx (four characters)
    Size: $xx xx xx xx
   Flags: $xx xx

The best way to understand what these things look like is to open any MP3 file in a hex editor and you'll see exactly what I'm talking about.  Just look for the word "ID3" and any of the 100+ declared tag names defined in Section 4 on id3.org/id3v2.3.0.  Some popular ones are the title "TIT1" and album art "APIC" frames.  Another cool feature of the specification states that there can be more than one instance of a specific frame.

It's important to realize that an ID3 tag or any data that precedes or ends after the MP3 header and data is not needed to play the MP3 file.  An MP3 player will play any file as long as it has valid MPEG-1 data within that file.  MPEG-1 data always has a header and then data after it and these repeat for the rest of the file.  The first 13-bits that are all set to one in a row is the header of the MPEG-1 data.  This header includes all the data that the MP3 player will need to play the data such as version, bit rate, frequency, and many other fields.  I included a layout of what an MPEG-1 header looks like, but you can find more information on it at Wikipedia (en.wikipedia.org/wiki/MPEG-1_Audio_Layer_3.  The MPEG data usually starts right after the ID3v2 tag.  So as long as we don't mess with the MPEG-1 data, our MP3 file will still play and it gives us plenty of space and leeway to hide a secret message.

Strings are either space- or zero-padded.  Unset string entries are filled using an empty string.  ID3v1 is 128 bytes long.

Field Length Description
header 3 "TAG"
title 30 30 characters of the title
artist 30 30 characters of the artist name
album 30 30 characters of the album name
year 4 A four-digit year
comment 28 or 30 The comment.
zero-byte 1 If a track number is stored, this byte contains a binary 0.
track 1 The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0.
genre 1 Index in a list of genres, or 255

There are a lot of MP3s and MP3 players out there.  MP3s are copied and recopied over and over and people have a tendency to change the ID3 data in their MP3 files and the ID3 tag gets rewritten.  Plus, every MP3 player implements the ID3 "Informal Standard" differently.

Depending on which MP3 player you use, it may not care about all the tags that are defined in the ID3v2 standard because normally it only shows maybe a dozen of these tags and the rest get ignored.  Depending on the MP3 player, it may not care about the size and flags in the ID3 tag header frame simply because it can't display the whole contents of that frame because of design restrictions.  If that frame is rewritten, it may not care about what was there before.  This is fine from a listening standpoint because the MP3 player will only play the MPEG-1 data and the rest of the file is just informational.  Therefore, ID3 tags are usually a mess.  Which means a secret message would hide very well among the garbage that is included in most ID3 tags.

We could copy our message into an MP3 file while keeping the MPEG-1 data intact and forget about the ID3 tag.  The only problem with this idea is that if our MP3 song is only four minutes long and the file is 20 MB large, it's going to look a little funny.  If it doesn't have any ID3 tag, it will look funny too.  So to avoid our message from being detected, we need to make it look like an ordinary everyday MP3 file.

Since MP3 players can be selective about what they read before and after the MPEG-1 data and the file can be as big as we want it to be and ID3 is an informal standard, we can create our own ID3 frame.  Since there are over a hundred different defined ID3v2 frames this makes it easy for our own defined frame to hide out among the real ID3 frames.  The size and flag data of the ID3 frames aren't always correct and, as long as we start with four characters followed by 6-bytes of data, we can make our frame look like an ordinary ID3 frame and use the other 6-bytes of data for whatever we want.

We could do something cool like use it for an encryption layout.  Or maybe we're lazy and just want to use one of the preexisting ID3 frames that go along with what we're doing.  We would still be able to hide our message pretty well.  Since MP3s are relatively small we can break up our message over a number of different MP3s, thus hiding our message even further.  We could even define a decoding order and make another ID3 frame to specify just that information.  We can also use a song that drives most people crazy for another layer of security.  The possibilities and complexity are endless.

This is why MP3s make the perfect place to hide secret messages.

It's interesting that ID3's motto is "The Audience is informed."  More than they realize.

Thanks for reading.

Shout out to Violet.

Return to $2600 Index