Inverse geotagging from Akaso V1 (2019 version) dashcam footage

Started by Mickey1962, June 14, 2020, 03:53:47 AM

Previous topic - Next topic

Phil Harvey

I think you are right.  We must be able to decipher this without an internet connection.

The GPSPlayer contacts the domain that I mentioned.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mickey1962

Hello,

I checked further. It seems that host 47.254.88.82 is called every seconds when starting viewing a file, but only 12 times, no more after that (see screen shot of Private Eye).

So I used Wireshark to check the exchange with that server, this is the result. It seems that it exchange some key :-( BUT always the same: p2524489676671331816

And the requests sent by the application already contain the correct LAT/LONG (jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664) hence, the decoding has already taken place before the calls (which seem to be only a "phone home" to track use of their dashcam (as the requests contain also my cam serial number)... BTW, as I never agreed to send my trip locations, this is in perfect violation of the current privacy laws !!!

I included the PCAP file with the exchange.

Here are the text data of the HTTP exchanges: (only 2, all in an attachment as it is too many characters)

Frame 4: 382 bytes on wire (3056 bits), 382 bytes captured (3056 bits)
Ethernet II, Src: Apple_17:cf:8e (80:e6:50:17:cf:8e), Dst: DrayTek_ee:d7:a0 (00:1d:aa:ee:d7:a0)
Internet Protocol Version 4, Src: 192.168.1.10, Dst: 47.254.88.82
Transmission Control Protocol, Src Port: 53941, Dst Port: 80, Seq: 1, Ack: 1, Len: 316
Hypertext Transfer Protocol
    GET /api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664 HTTP/1.1\r\n
    Content-Type: application/json\r\n
    X-GPS-Secret: 4b1281bb170e7e30ee42f811ae7ff156\r\n
    host: agps.goodcam.net\r\n
    Connection: close\r\n
    \r\n
    [Full request URI: http://agps.goodcam.net/api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664]
    [HTTP request 1/1]
    [Response in frame: 5]
Frame 5: 280 bytes on wire (2240 bits), 280 bytes captured (2240 bits)
Ethernet II, Src: DrayTek_ee:d7:a0 (00:1d:aa:ee:d7:a0), Dst: Apple_17:cf:8e (80:e6:50:17:cf:8e)
Internet Protocol Version 4, Src: 47.254.88.82, Dst: 192.168.1.10
Transmission Control Protocol, Src Port: 80, Dst Port: 53941, Seq: 1, Ack: 317, Len: 214
Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Content-Type: application/json; charset=utf-8\r\n
    Server: Microsoft-IIS/8.5\r\n
    X-Powered-By: ASP.NET\r\n
    Date: Sat, 20 Jun 2020 10:58:50 GMT\r\n
    Connection: close\r\n
    Content-Length: 22\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.162687000 seconds]
    [Request in frame: 4]
    [Request URI: http://agps.goodcam.net/api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664]
    File Data: 22 bytes
JavaScript Object Notation: application/json
Line-based text data: application/json (1 lines)
    "p2524489676671331816"

Frame 12: 382 bytes on wire (3056 bits), 382 bytes captured (3056 bits)
Ethernet II, Src: Apple_17:cf:8e (80:e6:50:17:cf:8e), Dst: DrayTek_ee:d7:a0 (00:1d:aa:ee:d7:a0)
Internet Protocol Version 4, Src: 192.168.1.10, Dst: 47.254.88.82
Transmission Control Protocol, Src Port: 53945, Dst Port: 80, Seq: 1, Ack: 1, Len: 316
Hypertext Transfer Protocol
    GET /api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664 HTTP/1.1\r\n
    Content-Type: application/json\r\n
    X-GPS-Secret: 4b1281bb170e7e30ee42f811ae7ff156\r\n
    host: agps.goodcam.net\r\n
    Connection: close\r\n
    \r\n
    [Full request URI: http://agps.goodcam.net/api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664]
    [HTTP request 1/1]
    [Response in frame: 13]
Frame 13: 280 bytes on wire (2240 bits), 280 bytes captured (2240 bits)
Ethernet II, Src: DrayTek_ee:d7:a0 (00:1d:aa:ee:d7:a0), Dst: Apple_17:cf:8e (80:e6:50:17:cf:8e)
Internet Protocol Version 4, Src: 47.254.88.82, Dst: 192.168.1.10
Transmission Control Protocol, Src Port: 80, Dst Port: 53945, Seq: 1, Ack: 317, Len: 214
Hypertext Transfer Protocol
    HTTP/1.1 200 OK\r\n
    Content-Type: application/json; charset=utf-8\r\n
    Server: Microsoft-IIS/8.5\r\n
    X-Powered-By: ASP.NET\r\n
    Date: Sat, 20 Jun 2020 10:58:51 GMT\r\n
    Connection: close\r\n
    Content-Length: 22\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.161264000 seconds]
    [Request in frame: 12]
    [Request URI: http://agps.goodcam.net/api/gpscode/getgpstoken?clientid=dbehf9dd4b2216559c89f93gb8e19ee6fb80&clienttype=2&gpscode=4XC1O71551266575YNDS&jd=4.433328166666667&timestamp=1559140784&wd=50.830141166666664]
    File Data: 22 bytes
JavaScript Object Notation: application/json
Line-based text data: application/json (1 lines)
    "p2524489676671331816"


HTH,
Michel


-- Michel

Phil Harvey

I've confirmed that the latitude is definitely stored in bytes 0x50-0x57, and the longitude in 0x58-0x5f.

I've run a number of tests.  Setting all of the lat/lon values to the same as the first sample results in a constant lat/long that all of a sudden jumps at 14:41:35 in the video.  The same thing happens if I set all the values to the lat/lon from the 2nd or 3rd sample.  But if I leave the 1st sample alone and set the remaining ones to the same as the 2nd sample, then the jump occurs at 14:41:45 (ie. 10 seconds later).  And if I leave the first 2 samples alone and set the rest according to the 3rd sample, it jumps at 14:41:29.  So somehow the history of these values influences the future values.  There appears to be some sort of rolling encryption applied to the lat/lon values.

Latitude seems to be relatively independent of longitude (I can mess with one and it doesn't affect the other), except that if I screw things up too badly the lat/lon stop changing in GPSPlayer.  I guess this happens if it finds an illegal value.

I can play with the lower-order bytes and the position shifts only by a little (eg. from 50.830023 to 50.830100 when bytes 0x50-0x53 are set to 0x00 and 0xff respectively), but incrementing byte 0x54 by 1 results in a shift that is larger than expected (from 50.830010 to 50.844503).

This is all a lot of fun, but I think I'm learning that I the encryption scheme is complex enough that I may not have time to figure it out. :(

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mickey1962

 :'( So sad.

I still remain puzzled by the very first sample is decoded from thin air (no previous value to rely on.

Maybe the timestamp is a kind of seed (the one the camera put to the samples) ?

So you definitely think there is no way to guess ? (And Akaso refuses to give away the scheme).

Anyway a big big thank you for having tried  :D :)
-- Michel

Phil Harvey

I've not given up totally, but I'm not very optimistic at the moment.  My last attempt was to write down the lat/lon values for the first 39 samples, convert them to DDDMM.MMMMM format, turn these into a double-precision floating-point numbers, then xor this with the actual data for each sample and take a look at the differences.  I was hoping it was a simple xor scheme with some key, and if so this would reveal the key, but no such luck.  I expect round-off errors in the first few lower-order bytes, but was hoping for some pattern in the upper bytes.  Here is the result of the XOR in hex:

XOR 5aa99aca5d667900 d4b04cc80391da00
XOR 74d1bd5bb25a6300 45dd8f0b0291da00
XOR 6faee3575c547500 f21d5c130e91da00
XOR 6c7ef3b0a7776500 08b788d30491da00
XOR 0b35751e2e6a5300 5030a5160a91da00
XOR 038fbcd3fe3a5600 074d8c721f91da00
XOR f1acad9957547500 401d3026e7aeda00
XOR 48cae2631c056800 900d6c76daaeda00
XOR ecf39f73d8f25000 f101fdc933afda00
XOR 08081ef791a30f00 bfa785cf4eafda00
XOR 6fbb4b0761ec5300 33bc5c0a54afda00
XOR b15f2b8c47627800 364653b8b9afda00
XOR 8484ed21c7667900 30b4b76aeaafda00
XOR b1449f06b88d6d00 4aa0c65a9fafda00
XOR 39d21dabb4fb6900 c206fde281afda00
XOR 613305be35fe5700 f49a854e78aeda00
XOR 21175d2e8faa0d00 610f0b89f2b2d000
XOR 93bbcb25c25f7b00 2efbde0034b5d000
XOR 42de063027606200 1952e22354b5d000
XOR 840f55df7c736400 1e0a796f52b5d000
XOR 197ce57fdf5f7b00 2eb091c632b5d000
XOR 0a375c8f92980900 ac4018f8d3b5d000
XOR b423940996980900 28981bc9f6b5d000
XOR 19c793ccc05f7b00 52bbde8fd2b5d000
XOR 2cf467a54f8a6d00 6cda4b4c31b5d000
XOR 93844426b7e86700 3b0a4cac53b5d000
XOR c7faa14fd04d7700 34626f0470b5d000
XOR 95a724bd4b836f00 7040620a5cb5d000
XOR 2cc9b25aa9bf7300 631e763c32b5d000
XOR f2da182dd6617f00 657a32ca2db5d000
XOR d4833783e5f56400 1d013607d6b6d000
XOR 79aeba1f495b7a00 929d09a5d4b6d000
XOR d4b8c7d72b747c00 2cfae029ebb6d000
XOR 069f3d535a5b7a00 cbfb686ee8b6d000
XOR 97e0b8db5e5b7a00 a4daf79fe0b6d000
XOR 8cd88942ab617f00 f6529105deb6d000
XOR eccc2218cdaf5300 aa92571c26b5d000
XOR 7549d76638627800 2a2b007639b5d000
XOR 26e88f8093910b00 c254549f2bb5d000


I also tried this in DDD.DDDDDD format, but things looked even a bit more random.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

The real way to solve this is to step through the GPSPlayer source code in a debugger to see what it is doing, but I lack the expertise to do this efficiently.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

AH HA!!!  A bit of a breakthrough!

When I plot the values decoded as double, there are strong periodic features:

The latitude follows a pattern that repeats every 60 samples! -- so the time in seconds is the encryption key.  We just need to figure out the encryption scheme.

The longitude follows a pattern that jumps every 60 samples -- so the time in minutes is the encryption key for this.

There is hope...

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mickey1962

Excellent ! You brightened my day. I do not want to jinx it but cheers already !

Michel R.
-- Michel

Phil Harvey

It is possible that the hour is also convoluted into the mix.  Do you have a video that crosses into the next hour?

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mickey1962

Hello Phil,

sure, I uploaded 2 files:

https://rabozee.net/dashcamGPS/2019_0524_125730_086.MOV
https://rabozee.net/dashcamGPS/2019_0524_175737_096.MOV

Hope those meet the requirements :-) (the 2019_0524_175737_096.MOV is interesting because the car is quite still when time changes...)
-- Michel

Phil Harvey

...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

OK.  A bit more information:

1. The hours are not part of the encryption key.  So it looks like only the minutes and seconds of the time are used.

2. The storage format is definitely IEEE 64-bit floating point in DDDMM.MMMMM format.  I have confirmed this by twiddling bits in byte 6 (starting from byte  0) of the latitude value and observing the output in GPSPlayer.  The upper 3 bits of byte 6 are the exponent as expected.  The lower 5 bits behave in expected binary fashion, and the latitude increases/decreases with a predictable pattern when these are changed.  However, changing individual bits in byte 4 doesn't have the expected result.  I'm not sure what is going on here, but more work is needed.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Mickey1962

Thank you for keeping me updated, Phil !

Crossing fingers, but take your time, I guess it is a nice challenge ;-)
-- Michel

Mickey1962

Hi, just passing by to see if you were able to get something new with this ?

Hope you are well, have a nice day

- Michel
-- Michel

Phil Harvey

No word, sorry.  I don't hold out much hope but I still have this on my list for things to work on.  I'll be spending more time indoors now that the summer is over so hopefully I'll find time for this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).