The Qsslcaudit tool developed by my colleague Pavel provides an easy way for testing a client SSL implementation. To make testing of multiple connections even more straightforward, I created a proxy wrapper for this tool.
How it works
The user configures qsslcauditproxy as a proxy server on the device under test, for example a mobile device.
The script will then act as a non-intercepting proxy for all SSL traffic. For each new host it will redirect the SSL stream to an instance of qsslcaudit, so that the client connection can be tested. HTTP connections will just be forwarded to the intended host.
Once connection establishment to a specific host has been fully tested, the SSL traffic is sent to the intended target. This will make the affected functionality operational again and user can proceed with testing further flows.
The tool uses curses to provide dynamic output. This gives a nice overview of the different connections test status. It is also really convenient for a tester to see which actions in the app trigger an outgoing connection.
Practical example against WPS Office for iOS
As a practical example, we tested this against the latest version of WPS Office for iOS (10.6.0). Pavel has demonstrated issues with the Android app in his blog post Client-side TLS implementation assessment with qsslcaudit - The WPS Office case.
We will use qsslcauditproxy to easily test connections to multiple hosts consumed by this application.
We first configured our proxy on the iOS device. We then fired up qsslcauditproxy with the following command:
#python3 qsslcauditproxy.py --blacklist blacklist --user-cert subdomain.gremwell.com_cert+chain.pem --user-key subdomain.gremwell.com.key --selected-tests certs
We then opened the WPS Office application on our device and interacted with all functionality. We could track the qsslcaudit test progress via the output of the proxy script. We configured a blacklist file so that connections related to the OS were not tested.
After testing all connections, we stopped the script and looked at the results. The results for each host are stored in a .txt file with the output.
root@kali:~/# grep mitm *.txt logincdn.msauth.net.txt:| 1 | custom certificate trust | FAILED !!! | mitm possible | login.live.com.txt:| 1 | custom certificate trust | FAILED !!! | mitm possible
A quick check shows that no certificate validation is done for the following hosts:
These hosts are used as part of the “Cloud - Onedrive” functionality that allows users to login to Onedrive with Microsoft credentials.
The following is detailed output that was logged by the qsslcaudit instance, which shows data intercepted when connecting to login.live.com.
running test #1: certificate trust test with user-supplied certificate listening on 0.0.0.0:8450 connection from: 127.0.0.1:51674 SSL connection established received data: GET /oauth20_authorize.srf?client_id=00000000480F074F&scope=onedrive.readwrite&redirect_uri=https://login.live.com/oauth20_desktop.srf&display=ios_phone&response_type=code HTTP/1.1 Host: login.live.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us Connection: keep-alive Accept-Encoding: gzip, deflate, br User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
This is the start of the oAuth flow as described here.
We used Burp to intercept the entire flow which confirmed that the Onedrive credentials were submitted via this connection.
POST /ppsecure/post.srf?client_id=00000000480F074F&scope=onedrive.readwrite&redirect_uri=https://login.live.com/oauth20_desktop.srf&display=ios_phone&response_type=code&contextid=0839C321FF5E086E&bk=1583930585&uaid=f0782fda2305430caf156cff32d1ac02&pid=15216 HTTP/1.1 Host: login.live.com Content-Type: application/x-www-form-urlencoded Origin: https://login.live.com Cookie: wlidperf=FR=L&ST=1583930727671; MSPOK=$uuid-3f374112-2fea-44b5-8dd8-7623df786237$uuid-d2e2f676-f140-493b-9763-d11d614f01aa$uuid-74502d48-33c1-4275-889d-26f825eef438; MSPRequ=id=N<=1583930585&co=1; OParams=11DfEKBqYgtbToYPr0tnbgt7fweLsQdPDnkF1KoVqQoYc9k6kTLygsyzNKZy03nyf9Kx1Ojsz2g9qJJ2pzrCPtsDRBrnxDudaNBH60iHu2Nz1FnSJ49DMuB4Ezc5PYQRXRepOQrSDL3NY9waoW1pZ7jB8EUukccWfRtymVHWzyTX1AZEsmkGYhZyULeunhWFkVXbX5wOlGgOaYj3aXusG*5whMz8BtXzaRE8kGBmKlO6kB7fonvzgeiiSoeNV7*9thlY*3FzrIBXW7S4Wux2BvTCTe9D9u3HuDT9SXehTeCNy34ChJxOnMNQQGRB55THqcv6kH5!CDf*ctnq8xUDsHcf9RtkcviDPUnaF8zy7z1Navq1GKdj!qx9YMWg4lb65XP3vupej0VMww1vf1S5SVPts2Cql*xcrk7TBhuOuNt3SAMaoI0BKMD3UmXtjqmayhMw$$; uaid=f0782fda2305430caf156cff32d1ac02 Content-Length: 615 Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Referer: https://login.live.com/oauth20_authorize.srf?client_id=00000000480F074F&scope=onedrive.readwrite&redirect_uri=https://login.live.com/oauth20_desktop.srf&display=ios_phone&response_type=code Accept-Language: en-us Accept-Encoding: gzip, deflate i13=1&login=[redacted]%40outlook.com&loginfmt=[redacted]%40outlook.com&type=11&LoginOptions=1&lrt=&lrtPartition=&hisRegion=&hisScaleUnit=&passwd=[redactedpass]&ps=2&psRNGCDefaultType=&psRNGCEntropy=&psRNGCSLK=&canary=&ctx=&hpgrequestid=&PPFT=DdQTIiJG*70c9R9*2Hm*GQXec8sRDjZFMvkaLdBf0J2ByJryOaNpaXn1P91VApsv1DbvPgzgqVg%21YGFnLX*Y4vY7nmUCWTuLPJgI3K8vi5kLAYP3IDjI9iAi1%21oWFrk40tvtatKPP4*%21i0L7ev81nCsQZst4a0tvPf7h%21qB1m042mUgXsc7bGeLWeVe0cb4nZPKf*K32z5J87Yx2Wqw8TLw%24&PPSX=P&NewUser=1&FoundMSAs=&fspost=0&i21=0&CookieDisclosure=0&IsFidoSupported=0&isSignupPost=0&i2=39&i17=0&i18=&i19=122883
During testing we noted that this bug was not 100% reproducible, in some cases proper certificate validation was done for connections to this host. If you want to try to reproduce these results, you may have to launch the test a second time.
- 11 March 2020: Reported to KingSoft via firstname.lastname@example.org
- 11 March 2020: Received email reply with invite to private Hackerone program
- 11 March 2020: The private Hackerone program states the following “Kingsoft Office is taking a break and is not accepting new submissions.”
- 18 March 2020: Public disclosure via this blog post
Users of Qsslcauditproxy should be aware that not all client applications will honor the proxy configuration of the OS. We recommend to always perform traffic analysis when testing client applications to get an overview of all outgoing connections.