Record and re-use TLS profiles
clouedoc opened this issue · comments
I am looking to inspect an HTTPS flow with Mitmproxy without altering the TLS fingerprint.
So, I am looking for this kind of setup:
Android device --> Mitmproxy --> proxychains(utlsproxy)
I will document my findings here.
From what I read, the main change happens here: saucesteals/goproxy@804168e#diff-9eb708469ebd17cf090b3e0e1a04c074850beb22e94ea3d327ad0610ec7bad32
![image](https://private-user-images.githubusercontent.com/13921610/334065322-6e56b926-4471-47e1-92ea-6422fb3c29e7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjMyMTkxNzIsIm5iZiI6MTcyMzIxODg3MiwicGF0aCI6Ii8xMzkyMTYxMC8zMzQwNjUzMjItNmU1NmI5MjYtNDQ3MS00N2UxLTkyZWEtNjQyMmZiM2MyOWU3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODA5VDE1NTQzMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTlkM2I5NWRjZTczNjFhYjZiZTExOGUzNWE3YTE4MDlhMTc4YzAwOTliMjgyODY0NzQ4NmY5ZWI2MzFjOWM1YzgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.YlpCetKeamdk6Epwp2wdbmeuU9ICr3k-v8igCNufTY4)
- The connection is established between the client and goproxy
- The ClientHello of the connection gets sniffed
- The ClientHello gets fingerprinted and converted to a
ClientHelloSpec
, which is a blueprint to create new ClientHello matching the fingerprint. - A new connection gets dialed with our interception certificate and a UTLS client using the
clientHelloSpec
I think I can simply record the ClientHello into a file and fingerprint it again and again at runtime.
This would have the benefit of keeping ground-truth data in-tree rather than only possibly faulty specs.
TODO
- Add environment variable to record the ClientHello to a given folder
- Add environment variable to re-use a saved ClientHello rather than using the TLS ClientHello
Managed to make it work!
I managed to make everything work.
My testing command:
curl -k --proxy localhost:8080 https://tls.peet.ws/api/tls | jq .tls.peetprint_hash
I first set my computer's global proxy to UTLSProxy and directed Safari to a website.
It saved the client hello.
I then relaunched with an environment variable that overwrites the ClientHello, pointed to the one I saved.
I then used cURL with utlsproxy and managed to get a Safari fingerprint
Next step
- Publish fork
- Check possibility of using an upstream proxy natively (net/http transport? I saw that it was removed in a commit in the goproxy fork — why, can I revert this? Is there an option in uTLS that natively allows to use an upstream proxy? Can I just hack it and add yet another environment variable?)
- If above fails, check out proxychains
I will leave this PR open to discuss ClientHello reuse and open a new one concerning upstream proxies.