Introducing Qsslcauditproxy

Submitted by sean on Wed, 03/18/2020 - 11:14

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 --blacklist blacklist --user-cert subdomain.gremwell.com_cert+chain.pem --user-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                                                                                               |  1 | custom certificate trust           | FAILED !!! | mitm possible               ||  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

running test #1: certificate trust test with user-supplied certificate
listening on
connection from:
SSL connection established
received data: GET /oauth20_authorize.srf?client_id=00000000480F074F&scope=onedrive.readwrite&redirect_uri= HTTP/1.1
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= HTTP/1.1
Content-Type: application/x-www-form-urlencoded
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&lt=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
Accept-Language: en-us
Accept-Encoding: gzip, deflate


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
  • 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.

Qsslcauditproxy is available for download at It requires qsslcaudit (


+32 (0) 2 215 53 58

Gremwell BVBA
Sint-Katherinastraat 24
1742 Ternat
VAT: BE 0821.897.133.