httptoolkit / frida-interception-and-unpinning

Frida scripts to directly MitM all HTTPS traffic from a target mobile application
https://httptoolkit.com/android/
GNU Affero General Public License v3.0
1.06k stars 198 forks source link

Kayo Sports - au.com.kayosports.tv #77

Open Shporterator opened 6 months ago

Shporterator commented 6 months ago

Hi! Kayo servers require forced use of TLS1.2. In the case of PHP this is easily solved CURL_SSLVERSION_MAX_TLSv1_2. Using basic scripts, HTTP Toolkit returns 403. How can I fix this?

pimterry commented 6 months ago

Hmmm, that would be very surprising. Are you sure? Can you share some documentation or demonstration (e.g. a curl command) to reproduce this issue?

It's surprising because TLS versions are actively negotiated. So if it's possible to open a TLS 1.3 connection to Kayo, that means that their servers do support TLS 1.3, and are telling clients to use that when they connect. If they don't support TLS 1.3 then clients (including HTTP Toolkit) will all downgrade TLS 1.2 automatically anyway. It would be very odd for them to enable TLS 1.3 connections on their servers that don't work!

Because of that, right now there's no way to do this with HTTP Toolkit. There might be some workarounds possible, but I'm not sure. If you can share more information so I can test and confirm this, I'll see what I can come up with.

Shporterator commented 6 months ago

Can you share some documentation or demonstration (e.g. a curl command) to reproduce this issue?

Required australian proxy This return json

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://resources.streamotion.com.au/production/kayo/auth0-configs/device-flow-settings.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'accept: */*',
    'content-type: application/json',
]);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_2);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
curl_close ($ch);

This return 403

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://resources.streamotion.com.au/production/kayo/auth0-configs/device-flow-settings.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'accept: */*',
    'content-type: application/json',
]);
#curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_2);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
curl_close ($ch);
pimterry commented 6 months ago

Converting this into a runnable CLI command (minus the proxy args) I think gives:

curl -X GET "https://resources.streamotion.com.au/production/kayo/auth0-configs/device-flow-settings.json" \  
     -H "accept: */*" \
     -H "content-type: application/json" \
     --compressed \
     --tls-max 1.2 \
     --max-time 20

On my machine, either locally (Spain), or using a VPN to connect via from Australia, this returns a 403 and a detailed JSON response with more info. When I remove the --tls-max 1.2 line it still works exactly the same, that doesn't seem to be required..

Removing that argument and then adding -v, I can see that the connection actually does use TLS 1.3, and it still works just fine and returns the 403 and data.

Is it possible the specific proxy you're using is the problem? If your proxy is blocking connections with TLS 1.3 then that could cause this (but that would be a very weird & suspicious thing to do...). The server you're talking about seems to work just fine with TLS 1.3 though.

Shporterator commented 6 months ago

and it still works just fine and returns the 403 and data.

It returns this? { "configRefreshIntervalInSeconds": 10, "deviceFlow": { "enabled": true, "refreshIntervalInSeconds": 10, ...

Is it possible the specific proxy you're using is the problem?

I have my own server in Australia and I have tried paid proxies, the problem is the same everywhere. When I run the app directly (also via proxy), it works fine. But through the HTTP ToolKit, requests start returning 403. So there is still a problem.

pimterry commented 6 months ago

Ah, I see - I was just testing curl by itself with & without the TLS limitation. I'm pretty sure that's not required and not related to this - it does indeed return that JSON with no TLS options required.

Separately though, I can reproduce the HTTP Toolkit intercepted issue in this case. Looking at the headers, this comes from Akamai. I suspect that means that they have enabled very strict TLS fingerprinting on this endpoint. This is just not related to TLS 1.2 or 1.3 or any similar setting - TLS fingerprinting is a technique that allows a server to recognize and allow only certain types of clients to connect. Unfortunately it looks like that's being applied here and causing issues.

There's not much HTTP Toolkit itself can do about this. You may be able to set up a proxy that can emulate TLS fingerprints in more advanced ways (such as https://github.com/Carcraftz/TLS-Fingerprint-API) and use this as your upstream proxy, but this tends to be a cat-and-mouse game where the working options break frequently as fingerprints and server detections change, so there's no easy answer and I haven't can't vouch for any working solutions.