Running a mitm proxy to retrieve run data from Paiactive app
I have my runs set to sync from Paiactive to Strava; but can not sync past runs and there is no export option within the app.
The main options:
- check to see if the file is stored locally on the phone, but requires root access.
- check if there is a website to download the data from, but there is not.
- intercept the traffic to capture the data as it is loaded
The third option is the only viable option, and that the run data was stored remotely was indicated by a delay in the app displaying the run data suggesting it was stored remotely.
The steps to take:
- install mitm proxy
- point phone to proxy server
- use the app and analyse the traffic between phone and server
Using the mitmweb tools on the server I can see traffic succesfully, and just how much data is transmitted from my phone to a whole multiude of servers!
Anyway, curiosuly the login request from the app is as follows:
POST https://lseur.laisitech.com/account/login?appId=129XXXXXX288×tamp=1642XXXXXX310&version=v1&language=en&sign=D28A156EC0B2430BF9E38C12345D670C HTTP/1.1
{
"deviceId": "e3SdaUZdRAafe6pVXnSdRW:APA93dHUm33FBl3Y3jU8dApQgdaA9ZNdMamaVaAa3BaE_ZdMX3DMikO7RmNadNakaLJ8SZaaeZ7XT-qBak3aAMTpadaAdm6RddkCk3Da-adhL0H8NQERanaoEaTlJF9j3SPhaIgaTdaq",
"email": "user@example.com",
"password": "ABC0D98D72434E88E1F9805BD63321A"
}
The issue being that I am not sure how the ‘sign=’ is generated and so can only replay messages to the server where I know the full data being sent, and the full HTTP POST details including the value of ‘sign’.
If I could work out how the ‘sign’ is generated, I could make an app in whatever language to login in the future without having to use a proxy.
That being said, I can still replay the request with curl once I have captured it with the proxy.
So on my phone I browse to my running history, select a date and then a particular run. This is downloaded to the phone with the traffic being visible in the proxy.
I can then copy and save the request data JSON into a file, and use the POST request details to replay the request with curl. There is a limited opportunity to do so though as each request is timestamped and faces expiry. Any new request from the app will have a new timestamp, and new sign value.
curl "https://lseur.laisitech.com/sportwatch/run/detail?appId=129XXXXXXXXX\
×tamp=1612319141933\
&version=v1\
&timeZone=Europe%2FParis\
&token=dtG0eZAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.dtG1aWQiOiIxMDAwMzYyOSIsInR5cGUiOiJhY2Nlc3NUb2tlbiIsImlzcyI6IlBoaWNvbW0iLCJuYmYiOjE2NDIyMjA2NTUsImV4cCI6MTY0MjczOTA1NSwicmVmcmVzaFRpbWUiOiIyMDIyLTAxLTE3IDA0OjI0OjE1In0.l1dY5uIWetOwTj8tzJ-FKpxKiv1C1icUiOvSHBnM6N5\
&userId=10003XXX\
&platform=android\
&appVersion=1.0.2074\
&language=en\
&sign=A12419C5BC315B7C533A5818F8C4DDA7" \
-H 'Accept: : gzip, deflate' \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Host: lseur.laisitech.com' \
-H 'Connection: Keep-Alive' \
-H 'User-Agent: okhttp/5.0.0-alpha.2' \
--data @request.json \
--output response.json.gz
Alternatively, I can now use the package mitmdump to run a python script which will do the hard work for me, useful when trying to get a whole bunch of run history.
I can even use the python script to decompress the data response into plain text/JSON and then manipulate that into a GPX (XML based) file.
Running from a windows command prompt, I can launch the script and proxy with:
mitmdump --quiet --flow-detail 0 --scripts mitm-paiactive.py "~u https://lseur.laisitech.com/"
Then, as I’m using the app on my phone, the output directory is filling with GPX files for each run which I can then upload manually to Strava.
Included below is the script; mitm-paiactive.py