Introduction
A geo-tagged image is an image which holds geographical identification metadata. This data consists of latitude and longitude co-ordinates (sometimes altitude also). Though there are some extremely powerful tools available for extracting geo-tag information from geo-tagged images but the insight knowledge of how a tool actually works and gets the data for us is always a plus.
We know validation is core of any forensics. One may use other tools and/or manually extract the data at byte level to validate the findings. This article exhibits how to go about parsing geo-tags of the images at byte level.
Collection of Geo-tag images
For the purpose of this experiment we took pictures from multiple devices such as
- iPhone 3GS
- iPod 4
- Nessus 7
- LG Optimus
- HTC
We turned on the location service on every device in order to capture geo-tagged pictures.
It was interesting to note that in Nessus 7 did not have local camera application so the application ‘Cameringo’ was installed which has a feature to attach geo-tag in the pictures. Not all camera applications have this feature.
Geo-tag analysis of the images
- Easiest and quickest way of checking geo location of a picture in Windows OS is to right click on the picture and select properties. Then under the detail tab, you will find the info.
- One can also use tool to extract geo-tag and other metadata, for instance, exiftool is a free powerful tool.
- One might have to validate or deal with cases where automatic recovery of geo-tag is not possible and manual parsing of raw image is required. This is what the article focuses on.
Manually parsing raw image
All devices that are used in this experiment found to have EXIF (Exchangeable Image File Format) standard of metadata logging.
Since the length and content of metadata (for example, make and model of camera, software, author, time etc.) vary from device to device, it is not surprising to see different starting offsets of geo-tag data. In other words, we could not find the consistency in the location offset of geo-tag in the image. But we did find a pattern to understand and get closer to the geo-tag offsets.
Scheme
We used following approach in our analysis.
1 Find the two direction letters i.e. N, S, E or W.
2 Then look proceeding offsets values for the pattern 00 00 xx xx 00 00 00 01 00 00 xx xx 00 00 00 01 a00 00 00 xx xx 00 00 64 or 00 00 03 E8. There is no predefined offset location to start with. The values are usually in big endian but we encountered a case involving little endian and reverse reading order.
3 Do your calculation and convert those values to something that makes sense.
Couple of things to keep in mind before jumping to calculation part are
- Read set of 4 bytes for every value
- The hex values given could be in big endian or little endian
- 00 00 00 64 = 100 decimal (Don’t convert it every time – a friendly advice J )
- 1 minute = 60 seconds
- 00 00 03 E8 = 1000 decimal
4 Use the direction letter for latitude and longitude respectively in order.
Proceeding sections demonstrate parsing of images from different sources.
Tools used
WinHex (any basic hex editor can be used)
Calculator (native application in Windows OS)
Image from iPhone
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00001120 32 30 31 33 3A 30 35 3A 33 30 20 31 34 3A 30 39 2013:05:30 14:09
00001136 3A 31 39 00 32 30 31 33 3A 30 35 3A 33 30 20 31 :19 2013:05:30 1
00001152 34 3A 30 39 3A 31 39 00 00 00 31 8D 00 00 05 B1 4:09:19 1 ±
00001168 00 00 10 B9 00 00 05 A1 00 00 26 0D 00 00 05 26 ¹ ¡ & &
00001184 00 00 00 4D 00 00 00 14 03 FF 02 FF 02 66 02 66 M ÿ ÿ f f
00001200 00 0A 00 01 00 02 00 00 00 02 4E 00 00 00 00 02 N
00001216 00 05 00 00 00 03 00 00 02 CE 00 03 00 02 00 00 Î
00001232 00 02 57 00 00 00 00 04 00 05 00 00 00 03 00 00 W
00001248 02 E6 00 05 00 01 00 00 00 01 00 00 00 00 00 06 æ
00001264 00 05 00 00 00 01 00 00 02 FE 00 07 00 05 00 00 þ
00001280 00 03 00 00 03 06 00 10 00 02 00 00 00 02 54 00 T
00001296 00 00 00 11 00 05 00 00 00 01 00 00 03 1E 00 1D
00001312 00 02 00 00 00 0B 00 00 03 26 00 00 00 00 00 00 &
00001328 00 1C 00 00 00 01 00 00 00 25 00 00 00 01 00 00 %
00001344 0B F4 00 00 00 64 00 00 00 51 00 00 00 01 00 00 ô d Q
00001360 00 17 00 00 00 01 00 00 15 53 00 00 00 64 00 00 S d
00001376 34 E9 00 00 01 12 00 00 00 12 00 00 00 01 00 00 4é
00001392 00 09 00 00 00 01 00 00 00 13 00 00 00 01 00 04
00001408 1D 6F 00 00 03 74 32 30 31 33 3A 30 35 3A 33 30 o t2013:05:30
00001424 00 00 FF E1 02 B0 ÿá °
Step 1
Scroll down till you find direction letter which is usually present near the date/time stamp. We found N and W.
Step 2
Look for the pattern 00 00 00 01 00 00 xx xx 00 00 00 01 … 00 00 00 64. Once the pattern is identified, find 4 bytes before the first set of 00 00 00 01 (highlighted with Turquoise) i.e. byte offset 1326 here.
Step 3
This is the most interesting step of calculation.
a) Let’s start converting hex to dec from offset 1326.
00 00 00 1C => 28 and next 4 bytes are 00 00 00 01 => 1 (Divisor)
Thus the value of degree is 28/1 = 28.
Go to next 4 byte set whose value corresponds to 00 00 00 25 => 37, followed by another set of 00 00 00 01 => 1 (divisor). Thus 37/1 = 37 is the value of minutes.
Now calculating decimal value of seconds. Convert next 4 byte set 00 00 0B F4 => 3060. This set is followed by 00 00 00 64 => 100 (divisor). This time when you divide, you get, 3060/100 = 30.60 seconds.
This completes the latitude calculation which is 28:37:30.60
b) We will continue, reading and converting the hex values for longitude and altitude.
00 00 00 51 => 81, next we have, 00 00 00 01 => 1. Degree is 81/1 = 81.
Then we have 00 00 00 17 => 23 and 00 00 00 01 => 1. Minutes comes out to be 23/1 = 23.
For seconds we have, 00 00 15 53 => 5459. Divisor is 00 00 00 64 => 100. Thus seconds is 5459/100 = 54.59.
Thus longitude is 81:23:54.59
c) Similarly calculate altitude. The value we have in hex is 00 00 34 E9 => 13545. Divisor is 00 00 01 12 => 274. Altitude becomes 13545/274 = 49.4343
Step 4
Finally assigning the direction in order and co-relate the information from what properties is displaying in the below capture.
Latitude: 28:37:30.60 N
Longitude: 81:23:54.59 W
Altitude: 49.4343
Image from iPod
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000512 00 00 00 05 32 30 31 33 3A 30 38 3A 32 32 20 31 2013:08:22 1
00000528 33 3A 32 37 3A 30 37 00 32 30 31 33 3A 30 38 3A 3:27:07 2013:08:
00000544 32 32 20 31 33 3A 32 37 3A 30 37 00 00 00 E0 FF 22 13:27:07 àÿ
00000560 00 00 30 FC 00 00 12 ED 00 00 07 7E 00 00 07 8E 0ü í ~ Ž
00000576 00 00 07 25 00 00 00 4D 00 00 00 14 00 07 00 01 % M
00000592 00 02 00 00 00 02 4E 00 00 00 00 02 00 05 00 00 N
00000608 00 03 00 00 02 9A 00 03 00 02 00 00 00 02 57 00 š W
00000624 00 00 00 04 00 05 00 00 00 03 00 00 02 B2 00 05 ²
00000640 00 01 00 00 00 01 00 00 00 00 00 06 00 05 00 00
00000656 00 01 00 00 02 CA 00 07 00 05 00 00 00 03 00 00 Ê
00000672 02 D2 00 00 00 00 00 00 00 1C 00 00 00 01 00 00 Ò
00000688 0D 90 00 00 00 64 00 00 00 00 00 00 00 01 00 00 d
00000704 00 51 00 00 00 01 00 00 04 D5 00 00 00 64 00 00 Q Õ d
00000720 00 00 00 00 00 01 00 00 38 FC 00 00 01 B5 00 00 8ü µ
00000736 00 11 00 00 00 01 00 00 00 1A 00 00 00 01 00 00
00000752 13 3C 00 00 00 64 00 06 01 03 00 03 00 00 00 01 < d
00000768 00 06 00 00 01 1A 00 05
Step 1
Look for direction letters (yellow highlighted).
Step 2
Identify the pattern (green highlighted).
Step 3
a) Start with the set of 4 bytes, offset 678-681 (highlighted Turquoise).
00 00 00 1C => 28
Next 4 bytes 00 00 00 01 gives divisor, 28/1= 28 degrees
Count from offset 690-693, 00 00 0D 90 => 3472
Again the next 4 bytes gives divisor 00 00 00 64 => 100 and the value of minute will be 3472/100 = 34.72.
Note that we have minutes in decimal and we know that
I degree = 60 minutes
I minute = 60 seconds.
Therefore converting minutes to seconds as 0.72 * 60 = 43.2 seconds.
Since we have already calculated seconds by minutes here, next 8 bytes are of no use which is 00 00 00 00 00 00 00 01.
That completes our latitude calculation which is 28:34:43.2
b) Moving forward to longitude bytes located at offset 702.
00 00 00 51 => 81 and 81/1 (next 4 bytes 00 00 00 01) = 81
Next, 00 00 04 D5 => 1237 and 1237/100 (next 4 bytes are 00 00 00 64) = 12.37.
Minutes = 12
Seconds = 0.37*60 = 22.2
Again, since the seconds has been calculated from the minutes, there is no separate 8 bytes for seconds calculation and you will see ‘00 00 00 00 00 00 00 01’ there.
Longitude is 81:12:22.2
c) For altitude,
00 00 38 FC => 14588
Divisor is 00 00 01 B5 => 437
14588/437 = 33.38215
Step 4
Use the direction letters,
Latitude: 28:34:43.2 N
Longitude: 81:12:22.2 W
Altitude: 33.38215
Finally co-relating the findings from the one we get in picture properties.
Image from Nessus
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000144 00 00 32 30 31 33 3A 30 38 3A 32 32 20 31 33 3A 2013:08:22 13:
00000160 33 34 3A 30 36 00 43 61 6D 65 72 69 6E 67 6F 20 34:06 Cameringo
00000176 44 65 6D 6F 00 00 04 00 01 00 02 00 02 00 00 00 Demo
00000192 4E 00 00 00 04 00 05 00 03 00 00 00 E0 00 00 00 N à
00000208 03 00 02 00 02 00 00 00 57 00 00 00 02 00 05 00 W
00000224 03 00 00 00 F8 00 00 00 00 00 00 00 51 00 00 00 ø Q
00000240 01 00 00 00 0C 00 00 00 01 00 00 00 6C 54 00 00 lT
00000256 E8 03 00 00 1C 00 00 00 01 00 00 00 22 00 00 00 è “
00000272 01 00 00 00 CA A0 00 00 E8 03 00 00 02 00 01 02 Ê è
00000288 00 04 00 01 00 00 2E 01 00 00 02 02 04 00 01 00 .
00000304 00 00 00 00 00 00 00 00 00 00 FF ÿ
Step 1
Look for direction letters (yellow highlighted).
Step 2
Identify the pattern (green highlighted).
Step 3
Reading of bytes is totally reversed here. One may have to read backwards to get the latitude and longitude. In addition, the values are saved in little endian.
a) Starting with offset 283 and going backwards. Thus from 283 – 280 (4 bytes) we have,
00 00 03 E8 (divisor) => 1000
From offset 279 – 276, 00 00 A0 CA => 41162
41162/1000 => 41.162 seconds
00 00 00 01 (divisor) = 1
00 00 00 22 => 34
34/1 = 34 minutes
Then we have 00 00 00 01 = 1
00 00 00 1C = 28
28/1 = 28 degrees
We got our latitude = 28:34:41.162
b) Continue going backwards where we left from,
00 00 03 E8 => 1000
00 00 54 6C => 21612
21612/1000 = 21.612 seconds
Then 00 00 00 01 is the divisor
00 00 00 0C => 12
12/1 = minutes
Next we have 00 00 00 01 (divisor) and
00 00 00 51 => 81
81/1 = 81 degrees
Longitude becomes
81:12:21.612
Step 4
With direction,
Latitude: 28:34:41.162 N
Longitude: 81:12:21.612 W
Finally matching the extracted information with the one windows identified locally, as shown below.
Image from LG
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00001216 00 00 03 00 00 00 01 00 00 00 00 00 00 00 01 00
00001232 00 01 CC 00 00 00 64 00 00 03 E8 00 00 00 01 00 Ì d è
00001248 00 00 00 00 00 00 00 00 01 00 00 00 00 FF FF 00 ÿÿ
00001264 08 00 01 00 02 00 00 00 02 4E 00 00 00 00 02 00 N
00001280 05 00 00 00 03 00 00 06 5D 00 03 00 02 00 00 00 ]
00001296 02 57 00 00 00 00 04 00 05 00 00 00 03 00 00 06 W
00001312 75 00 05 00 01 00 00 00 01 00 00 00 00 00 06 00 u
00001328 05 00 00 00 01 00 00 06 8D 00 07 00 05 00 00 00
00001344 03 00 00 06 95 00 1D 00 02 00 00 00 0B 00 00 06 •
00001360 AD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001376 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001392 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001424 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001456 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001472 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001488 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001504 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001536 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001552 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001568 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001584 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001616 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001632 00 00 00 00 00 00 00 00 00 00 00 00 1C 00 00 00
00001648 01 00 00 00 22 00 00 00 01 00 00 A2 21 00 00 03 “ ¢!
00001664 E8 00 00 00 51 00 00 00 01 00 00 00 0C 00 00 00 è Q
00001680 01 00 00 56 FE 00 00 03 E8 00 00 00 12 00 00 00 Vþ è
00001696 01 00 00 00 11 00 00 00 01 00 00 00 17 00 00 00
00001712 01 00 00 00 18 00 00 00 01 32 30 31 33 3A 30 38 2013:08
00001728 3A 32 32 00 00 08 01 00 00 04 00 00 00 01 00 00 :22
00001744 00 A0 01 01 00 04 00 00 00 01 00 00 00 78 01 03 x
00001760 00 03 00 00 00 01 00 06 00 00 01 1A 00 05 00 00
00001776 00 01 00 00 08 3E 01 1B 00 05 00 00 00 01 00 00 >
00001792 08 46 01 28 00 03 00 00 00 01 00 02 00 00 02 01 F (
00001808 00 04 00 00 00 01 00 00 08 4E 02 02 00 04 00 00 N
00001824 00 01 00 00 13 A8 00 00 00 00 00 00 00 00 00 00 ¨
00001840 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001856 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Step 1
Look for direction letters (yellow highlighted).
Step 2
Identify the pattern (highlighted green). You must have noticed that in this case, we found the pattern quite farther from the direction letters (at offset 1640) unlike previous examples.
Step 3
a) 00 00 00 1C => 28
00 00 00 01 => 1 (divisor)
28/1 = 28 degrees
00 00 00 22 => 34
00 00 00 01 = 1
34/1 = 34 minutes
00 00 A2 21 => 41505
00 00 03 E8 => 1000
41505/1000 = 41.505 seconds
Thus latitude is 28:34:41.505
b) Continue reading hex,
00 00 00 51 => 81
00 00 00 01 => 1 (divisor)
81/1 = 81 degrees
Next 4 bytes are
00 00 00 0C => 12
00 00 00 01 => 1
12/1 = 12 minutes
00 00 56 FE => 22270
00 00 03 E8 => 1000
22270/1000 => 22.27 seconds
Thus longitude = 81:12:22.27
c) Altitude is 18
Because,
00 00 00 12 => 18
00 00 00 01 => 1
18/1 = 18
Step 4
With direction,
Latitude: 28:34:41.505 N
Longitude: 81:12:22.27 W
Altitude: 18
Finally match the values to verify.
Image from HTC phone
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00004528 31 31 3A 30 34 3A 31 32 20 31 31 3A 30 37 3A 31 11:04:12 11:07:1
00004544 39 00 32 30 31 31 3A 30 34 3A 31 32 20 31 31 3A 9 2011:04:12 11:
00004560 30 37 3A 31 39 00 00 00 01 EC 00 00 00 64 00 01 07:19 ì d
00004576 00 02 00 07 00 00 00 04 30 31 30 30 00 00 00 00 0100
00004592 00 00 00 00 00 0B 00 00 00 01 00 00 00 03 02 02
00004608 00 00 00 01 00 02 00 00 00 02 4E 00 00 00 00 02 N
00004624 00 05 00 00 00 03 00 00 12 72 00 03 00 02 00 00 r
00004640 00 02 57 00 00 00 00 04 00 05 00 00 00 03 00 00 W
00004656 12 8A 00 05 00 01 00 00 00 01 00 00 00 00 00 06 Š
00004672 00 05 00 00 00 01 00 00 12 A2 00 07 00 05 00 00 ¢
00004688 00 03 00 00 12 AA 00 12 00 02 00 00 00 07 00 00 ª
00004704 12 C2 00 1B 00 07 00 00 00 0F 00 00 12 CA 00 1D Â Ê
00004720 00 02 00 00 00 0B 00 00 12 DA 00 00 00 00 00 00 Ú
00004736 00 26 00 00 00 01 00 00 00 2A 00 00 00 01 00 00 & *
00004752 0A 45 00 00 00 64 00 00 00 4D 00 00 00 01 00 00 E d M
00004768 00 04 00 00 00 01 00 00 0D 7C 00 00 00 64 00 00 | d
00004784 00 00 00 00 00 01 00 00 00 0F 00 00 00 01 00 00
00004800 00 07 00 00 00 01 00 00 00 13 00 00 00 01 57 47 WG
00004816 53 2D 38 34 00 00 41 53 43 49 49 00 00 00 4E 45 S-84 ASCII NE
00004832 54 57 4F 52 4B 00 32 30 31 31 3A 30 34 3A 31 32 TWORK 2011:04:12
00004848 00 00 00 00 00 06 01 03 00 03 00 00 00
Step 1
Look for direction letters (yellow highlighted).
Step 2
Identify the pattern (highlighted green).
Step 3
a) For latitude
00 00 00 26 => 38
38/1 (divisor) = 38 degrees
00 00 00 2A => 42
42/1 = 42 minutes
00 00 0A 45 => 2629
2629/100 (divisor) = 26.29 seconds
Latitude is 38:42:26.29
b) For longitude
00 00 00 4D => 77
77/1 = 77 degrees
00 00 00 04 => 4
4/1 = 4 minutes
00 00 0D 7C => 3452
3452/100 = 34.52 seconds.
Longitude is 77:4:34.52
Step 4
Match the calculated value with the one given by image properties.
References
http://en.wikipedia.org/wiki/Geotagging
