Tuesday, February 4, 2014

Decoding GSM/SMS Timestamps

GSM timestamps (TP-SCTS)

Probably one of the most common timestamps found within mobile phones is the GSM/SMS timestamp format. Within the GSM specification 03.40, it's referred to specifically as the SCTS, or Service Center Time Stamp. The format is pretty simple, but I've gotten a lot of questions about parts of it, especially the timezone offset.

Let's look at a few examples in some feature phones. First, from a Samsung SGH-T429:

SMS records from a Samsung SGH-T429 phone - Highlighted portions are the timestamps

Here you can see two timestamps highlighted. By the way, the obfuscated portions are SMSC numbers and phone numbers that I felt it best to eliminate.

Now, looking at those timestamps, we have the following:

9001425100704A and 9001723165954A. Now to the formatting... These timestamps are stored in a reverse-nibble, binary-coded decimal format. Let's break down what that means by breaking it into bytes first:

90 01 42 51 00 70 4A

Now, each of these bytes represents, in order, the year, the month, the day, the hours, the minutes, and the seconds, followed by the last byte, which is the timezone offset. But... we have to reverse the order of the digits within each byte first (and we'll ignore the timezone for now).

09 10 24 15 00 07

Now, this makes more sense: 2009-10-24 at 15:00:07. Or, in good, old-fashioned American: October 24th, 2009 at 15:00:07 hours. Just remember that they are listed in descending order, biggest unit to smallest.

Now, the second timestamp we can decode easily as 2009-10-27 at 13:56:59. The reverse-nibbling... you get used to it after a while.

OK, now on to the timezone offset. That seventh byte represents the offset from Universal Coordinated Time, UTC, GMT (not really), or whatever you want to call it. This last byte is reverse-nibbled as well, but it's signed to indicate whether it's a negative or positive offset. Let's check it out.

First, starting with 4A, then reverse nibbling, we have A4, which in binary is 1010 0100. That first bit, if it's a 1, means it's a negative offset. If it's a 0, it means it's a positive offset. So, we know this is a negative offset. So, what I do is, in my mind, is convert that first bit to a sign, thusly: -010 0100, which converted back into decimal, gives us 010 = 2 and 0100 = 4, or -24. We just combine those nibbles as decimal digits (that's the binary-coded decimal part) Now, the easy bit. We multiply that by 1/4 hour increments to get the offset in hours. -24 x 1/4 = -6, so this offset is -6 hours from UTC. So, as a review:

Offset in the timestamp:        4A

Reverse nibble it:                   A4

Convert to binary:                  1010 0100

"1" equals negative:               -010 0100

Convert digits to decimal:      -24

Multiply by .25 hours:            -24 x .25 = -6 hours offset from UTC

Let's do another one from a random Mediatek Chinese phone:

Three SMS records in a Mediatek-based phone

OK, this one has three records on screen (from Cellebrite's Physical Analyzer). The three dates are as follows:

21 20 41 41 33 62 02 = 12 02 14 14 33 26 20 (2012-02-14, 14:33:26) with 20 x .25 = UTC +5 offset.

21 20 41 41 33 72 02 = 12 02 14 14 33 27 20 (2012-02-14, 14:33:27) with the same UTC +5

21 20 41 41 33 82 02 = 12 02 14 14 33 28 20 (2012-02-14, 14:33:27) again UTC +5

These were system messages, BTW.

Looking at the 02 offset code, it's easy to see that when we reverse nibble it (20), then look at the binary, 0010 0000, we see that the zero is the leading bit, which means it's positive. Then we just take the decimal digits 2 and 0 represented by these nibbles (decimal 20) and multiply them by .25 hours and we have UTC +5.

Half-hour timezones?

OK, one more that I thought was interesting. This one comes from one of those countries in the world where they have half-hour offset timezones. Here's a link to a page that describes some of those: http://www.timeanddate.com/time/time-zones-interesting.html.

Anyway, this is interesting to me because in this particular example, which is from Iran, PA shows the offset erroneously as UTC+5, when it's actually UTC + 5:30. Since Iran is either UTC+3:30 or UTC+4:30, maybe somebody somewhere set a clock wrong.

Screenshot from a popular mobile forensics application, showing UTC+5, when it should be UTC+5:30
We can clearly see the timestamp (11119190046422) which decodes as (2011-11-19 at 09:40:46). But... the timezone offset is 22... 22 x .25 hours is 5 and a half hours, not the five hours shown here. Anywho, probably something to take a look at if you're dealing with phones in those parts of the world with strange timezones.

Lastly, there is one good application for working with timestamps and verifying the ones you're getting from your mobile forensics tool of choice. That program is called Clocksmith, which comes with most of the common timestamp formats that you will probably see in phones, as well as some computer ones. You can get it from Evigator (http://www.evigator.com/free-apps/). Most of the time the main tools will break out the dates and times just fine, but... you have to be able to verify it yourself if need be.

Greg Thomson
H-11 Digital Forensics




  1. Just for clarification. When you say convert the digits to decimal, you mean to say, convert each nibble set to decimal and jam them together. 1010 0100 Ignoring the leading bit (1) because it denotes positive/negative, 0100100 converted to decimal is 36, not 24. However if you convert each nibble (0010 0100), it is a 2 and a 4 which can be read 24. Am I correct?

  2. Since it's BCD encoded, each nibble will represent a decimal digit. It's really just like converting to hex, but the only values are going to be decimal. So, your example is 1010 0100... the leading 1 just gives us the sign, in this case a negative. Then, we convert the remaining three bits to a 2, then the other four bits to a four. So, yeah, that's correct. The habit, of course would be to convert all 7 bits to decimal, but that doesn't happen in the case of binary-coded decimal (BCD). Thanks for the question.

  3. Added a reference to BCD encoding on wikipedia.