So a friend of mine recently competed in a 10mile race (supposedly) and he thinks he tracked the “ACTIVITY” on his watch but after the race deleted it by mistake.

He brought the watch immediately over to me to see if there was anything I could do. Well the watch seems to be pretty nifty and has built in GPS, bluetooth and some other bells and whistles.

The watch comes with a charging dock which i noticed had 4 pins so must have had USB data lines as well las the power. As such I connected the device, mounted it read only, and then cloned the disk and made a working backup:

1
2
sudo dd if=/dev/rdisk3 of=backup.dump
cp backup.dump working.dump

The next thing I ran was foremost against the file system to see if it could find anything interesting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@KaliMJP:/mnt/hgfs/temp# foremost -v -i working.dump
Foremost version 1.5.7 by Jesse Kornblum, Kris Kendall, and Nick Mikus
Audit File

Foremost started at Mon Feb  6 09:16:41 2017
Invocation: foremost -v -i working.dump
Output directory: /mnt/hgfs/temp/output
Configuration file: /etc/foremost.conf
Processing: working.dump
|------------------------------------------------------------------
File: working.dump
Start: Mon Feb  6 09:16:41 2017
Length: 10 MB (11508224 bytes)
 
Num  Name (bs=512)         Size  File Offset     Comment

*|
Finish: Mon Feb  6 09:16:41 2017

0 FILES EXTRACTED
   
------------------------------------------------------------------

Foremost finished at Mon Feb  6 09:16:41 2017

That didn’t work so I decided to have a look on the filesystem to see an example of the type of files I should be looking for.

1
2
3
4
5
6
7
8
9
10
root@KaliMJP:/mnt/hgfs/temp# mkdir filesystem ; mount working.dump filesystem
root@KaliMJP:/mnt/hgfs/temp# ls filesystem/
AUTORUN.INF  ERR_LOG.TXT  GARMIN
root@KaliMJP:/mnt/hgfs/temp# ls filesystem/GARMIN/
ACTIVITY  COURSES     EVNTLOGS          GOALS     MLTSPORT  NEWFILES     RECORDS   SCHEDULE  SPORTS   TEXT    WIFI
APPS      DEVICE.FIT  GarminDevice.xml  LOCATION  MONITOR   NRF_ERR.TXT  REMOTESW  SETTINGS  TEMPFIT  TOTALS  WORKOUTS
root@KaliMJP:/mnt/hgfs/temp# ls filesystem/GARMIN/ACTIVITY/
6CRC0101.FIT  712G0619.FIT  71865606.FIT  71FE4602.FIT  71J72457.FIT  71N72941.FIT  71RD2701.FIT  71VC3005.FIT
6CS95823.FIT  71495133.FIT  719B3605.FIT  71GC1249.FIT  71JB1310.FIT  71OG4701.FIT  71T73357.FIT  72370402.FIT
6CVE0513.FIT  716I5616.FIT  71D70320.FIT  71I64149.FIT  71K70156.FIT  71P72020.FIT  71V92016.FIT

As I now had some example files I will check the headers and footers of each to see if there are any similarities so that I can create
Headers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in *.FIT ; do xxd -l 16 $i >> heads.txt ; done
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in *.FIT ; do xxd -l 16 $i; done
00000000: 0e10 d607 a81b 0000 2e46 4954 01dc 4000  .........FIT..@.
00000000: 0e10 d607 a03d 0000 2e46 4954 47b8 4000  .....=...FITG.@.
00000000: 0e10 d607 a81b 0000 2e46 4954 01dc 4000  .........FIT..@.
00000000: 0e10 d607 9843 0000 2e46 4954 db0d 4000  .....C...FIT..@.
00000000: 0e10 d607 4e29 0000 2e46 4954 9c7d 4000  ....N)...FIT.}@.
00000000: 0e10 d607 3022 0000 2e46 4954 a015 4000  ....0"...FIT..@.
00000000: 0e10 d607 668f 0000 2e46 4954 59c9 4000  ....f....FITY.@.
00000000: 0e10 d607 ffce 0000 2e46 4954 c1cb 4000  .........FIT..@.
00000000: 0e10 d607 931d 0000 2e46 4954 257b 4000  .........FIT%{@.
00000000: 0e10 d607 4612 0000 2e46 4954 1718 4000  ....F....FIT..@.
00000000: 0e10 d607 d747 0000 2e46 4954 dabd 4000  .....G...FIT..@.
00000000: 0e10 d607 a81a 0000 2e46 4954 111c 4000  .........FIT..@.
00000000: 0e10 d607 f910 0000 2e46 4954 7fec 4000  .........FIT..@.
00000000: 0e10 d607 3dbd 0000 2e46 4954 0e85 4000  ....=....FIT..@.
00000000: 0e10 d607 6b25 0000 2e46 4954 925a 4000  ....k%...FIT.Z@.
00000000: 0e10 d607 e00d 0000 2e46 4954 738b 4000  .........FITs.@.
00000000: 0e10 d607 9241 0000 2e46 4954 78b2 4000  .....A...FITx.@.
00000000: 0e10 d607 700f 0000 2e46 4954 5927 4000  ....p....FITY'@.
00000000: 0e10 d607 1acc 0000 2e46 4954 2c7c 4000  .........FIT,|@.
00000000: 0e10 d607 4079 0000 2e46 4954 4df4 4000  ....@y...FITM.@.
00000000: 0e10 d607 1511 0000 2e46 4954 6131 4000  .........FITa1@.
00000000: 0e10 d607 89ac 0000 2e46 4954 0503 4000  .........FIT..@.
00000000: 0e10 d607 5b22 0000 2e46 4954 e78e 4000  ....["
...FIT..@.
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# cut heads.txt -d" " -f 2-9 | sed 's/ //g' | sed 's/.\{2\}/& /g' > heads_snip.txt

Footers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in *.FIT ; do xxd -s -16 $i >> tails.txt ; done
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in *.FIT ; do xxd -s -16 $i; done
00001ba8: f077 1000 3912 c532 0100 011a 01ff 315c  .w..9..2......1\
00003da0: 0100 f056 0400 c440 c632 0000 0101 b81b  ...V...@.2......
00001ba8: a253 1000 d174 ca32 0100 001a 01ff 469d  .S...t.2......F.
00004398: 0100 845e 0400 e434 cd32 0000 0100 2e8b  ...^...4.2......
0000294e: 4155 1c00 1683 cf32 0100 011a 01ff 9a1c  AU.....2........
00002230: 01a0 1a00 27a6 d232 0100 011a 01ff 89d7  ....'..2........
00008f66: 0100 90b1 0400 9996 d432 0000 0100 eacb  .........2......
0000ceff: ffff 1502 0000 a529 d632 0200 0201 4122  .......).2....A"
00001d93: 3661 2400 c93b db32 0100 011a 01ff 068c  6a$..;.2........
00001246: 06a6 1100 0144 de32 0100 011a 01ff e9e9  .....D.2........
000047d7: 0100 9f18 0400 f56d df32 0000 0101 11dd  .......m.2......
00001aa8: 6207 1b00 96c9 e132 0100 011a 01ff 3cba  b......2......<.
000010f9: 0100 cabb 0400 971e e332 0000 0100 2e4a  .........2.....J
0000bd3d: ffff 5202 0000 4653 e332 0200 0201 d1e8  ..R...FS.2......
0000256b: 9b6d 2900 1877 e432 0100 011a 01ff b57c  .m)..w.2.......|
00000de0: 8a06 0e00 c168 e832 0100 001a 01ff 7a6e  .....h.2......zn
00004192: 0100 e34b 0400 5639 ea32 0000 0100 fb3e  ...K..V9.2.....>
00000f70: 05c5 1100 580a eb32 0100 001a 01ff 10ae  ....X..2........
0000cc1a: ffff 5d03 0000 a5fe ed32 0200 0201 de55  ..]......2.....U
00007940: 0100 5bc6 0400 1e4f f032 0000 0100 e2b1  ..[....O.2......
00001115: 0f9e 1200 e90f f332 0100 001a 01ff 931f  .......2........
0000ac89: 3d00 c307 5100 c53e f332 0000 0200 43eb  =...Q..>.2....C.
0000225b: d57b 1a00 34ea f632 0100 011a 01ff a957  .{..4..2.......Wroot@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# cut tails.txt -d" " -f 2-9 | sed '
s/ //g' | sed 's/.\{2\}/& /g' > tails_snip.txt

This allows me to identify the following common fields: 0e 10 d6 07 ? ? 00 00 2e 46 49 54 ? ? 40 00

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in {1..16}; do cat heads_snip.txt | cut -d' ' -f$i | uniq -c | sort -nr | head -n 1; done
     23 0e
     23 10
     23 d6
     23 07
      1 ff
      1 ce
     23 00
     23 00
     23 2e
     23 46
     23 49
     23 54
      1 e7
      1 f4
     23 40
     23 00

Unfortunately the footers were not so common 🙁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@KaliMJP:/mnt/hgfs/temp/filesystem/GARMIN/ACTIVITY# for i in {1..16}; do cat tails_snip.txt | cut -d' ' -f$i | uniq -c | sort -nr | head -n 1; done
      2 01
      1 ff
      1 f0
      2 00
      1 e9
      2 00
      1 f6
      2 32
      2 e3
      2 32
      3 00
      2 1a
      7 01
      2 ff
      1 fb
      1 eb

As such I could only use a header in my custom scalpel.conf file:

1
2
root@KaliMJP:/mnt/hgfs/temp# grep -v "#" /etc/scalpel/scalpel.conf
y 100000 \x0e\x10\xd6\x07??\x00\x00\x2e\x46\x49\x54??\x40\x00

And then run scalpel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@KaliMJP:/mnt/hgfs/temp# scalpel -c /etc/scalpel/scalpel.conf -o scalpel_output working.dump
Scalpel version 1.60
Written by Golden G. Richard III, based on Foremost 0.69.

Opening target "/mnt/hgfs/temp/working.dump"

Image file pass 1/2.
working.dump: 100.0% |****************************************************************************************************************|   11.0 MB    00:00 ETAAllocating work queues...
Work queues allocation complete. Building carve lists...
Carve lists built.  Workload:
fit with header "\x0e\x10\xd6\x07\x3f\x3f\x00\x00\x2e\x46\x49\x54\x3f\x3f\x40\x00" and footer "" --> 93 files
Carving files from image.
Image file pass 2/2.
working.dump: 100.0% |****************************************************************************************************************|   11.0 MB    00:00 ETAProcessing of image file complete. Cleaning up...
Done.
Scalpel is done, files carved = 93, elapsed = 0 seconds.

Now that I had carved out the FIT files I wanted to see if any matched up with the date of the race (5th Feb 2017). To do that it’s worth using the perl module fitdump

Sadly nothing came out….:

1
root@KaliMJP:~/bin# ./fitdump /mnt/hgfs/temp/scalpel_output/fit-0-0/* | grep "2017-02-05"

However, this does teach me some of steps involved in data recovery.

Leave a Reply