Some months ago I bought a peripheral device for my Windows 10 computer (think of something like a game controller). My home router has a function that allows it to capture all incoming and outgoing traffic of my home network.

By chance I was capturing traffic right when my Windows 10 PC was starting up. When I later analyzed my router's traffic log in Wireshark I noticed a TLS encrypted packet was sent from the Windows 10 PC to an API of the peripheral device's manufacturer. I figured this out through the packet's Server Name Indication field (SNI). The protocol is TLS 1.2 according to Wireshark.

I am quite sure that this connection was established by a Windows service that was created during the driver installation of the peripheral device. Now I want to know what information the service is sending to/ receiving from the API.

My first try was to use an SSLKEYLOGFILE. The SSLKEYLOGFILE worked for browsers like Firefox or Chrome, but not for said Windows service. Would it be possible to perform a man-in-the-middle attack (MITM) against myself? Or would it be easier to capture the traffic directly on the Windows 10 machine before it gets encrypted?

What would be a viable solution to intercept and decrypt this TLS traffic originating from a Windows service?

1 Answer 1


You have several possibilities. Each of them with their own Pros and Cons.

Reverse Engineering the Service

The service is just an executable file, so you can load up the binary into a reverse engineering tool of choice (for example, Ghidra, which was developed by our good "friends" over at the NSA) and have a look at what it does.

This has the advantage that you can see exactly what the service does. As an upside, you don't need to worry about any cryptography, since you can see exactly what the service sends as plain text. If you debug it, it may be even simpler.

The downside, of course, is that the service is most likely shipped without debug symbols, and if you're unlucky, in a language that compiled directly to assembler. So debugging may not be a simple task.

Man-in-the-Middle - Naïve Approach

A lot of software has constructs like this:

HttpClient httpClient = new HttpClient();       
httpClient.BaseAddress = new Uri("https://example.com/");

var task = httpClient.PostAsXmlAsync<DeviceRequest>("api/GetCurrentVersion", request);

Just standard "How to send a HTTP POST request in C#?" code, right? Notice how the code itself never checks which server certificate is used. What that means is that the runtime will check if the certificate is valid and whether or not it is signed by a Certificate Authority that is trusted by your OS.

So what you can do is to use a proxy server, which serves as an endpoint to the actual server, and then generates a new connection to the service running on your machine. The server will think it is communicating with the service (which is fine, since the service doesn't authenticate itself). The service will think it is communicating with the server, even though it's communicating with the proxy. This is made possible by the fact that the proxy can generate a certificate for the server that is trusted by your local machine.

The exact proxy software used is up to personal preference, as well as the actual protocol being used. TLS merely encapsulates another protocol, which could be HTTP or some other proprietary protocol. HTTPS Proxies are common like sand on a beach, you can use mitmproxy, OWASP ZAP, Burp Suite or any other tool you like or are familiar with. If the protocol is not HTTP, then you need to find another tool. I'm sure Google knows a bunch.

Man-in-the-Middle - Technical Approach

Some companies think they're hot stuff by doing things like mutual authentication and certificate pinning. To quote a colleague of mine:

You're not stopping me, you're just pissing me off.

Mutual authentication means that not only does the client authenticate the server (the default scenario in TLS), but the server also authenticates the client. This is usually done via a client certificate and a private key.

The client certificate, if required, is sent in the Client Hello packet. You can use Wireshark to see if a client certificate is requested and sent (and dump the certificate form there). Since you mentioned that the service uses TLS 1.2, this is easily possible. TLS 1.3 would have made this a bit harder.

Next, you have to have a look at the binary. Since a certificate needs a private key, the private key is either stored as a file somewhere on your file system (the easy way) or inside the binary. There is a great question on Security.SE on how to extract a private key from a binary. Since there are many ways how to store a private key, you might need to poke around a little. (If the service used TLS 1.3, you could also use this to search for the certificate.)

Now that you have the certificate and the private key, you can hand those over to your proxy and the server will believe you are the proper service.

However, there is still the matter of certificate pinning. Roughly speaking, certificate pinning refers to the act of saying that a server must respond either with a specific public key in its certificate, or a certificate signed by a specific CA.

In either case, you have the binary, and you have the public key of your proxy's certificate. All you need to do is overwrite whatever the service expects to whatever you have, and all is fine. Alternatively, you could just completely remove the function that does the certificate check and replace it with a stub that always returns that the certificate is valid. The possibilities are endless.

Making an Educated Guess

A lot of software, when it first starts, contacts the developer to see if a new version is available. It wouldn't be that far-fetched to assume that that's what the software does. If you aren't interested in the exercise and just want to see if the service does anything malicious - this is probably what it's doing.

  • A colleague of mine pointed me towards sslproxy and ghostunnel. I have never used these tools personally, but they could be a stepping stone.
    – user163495
    Commented Jan 20, 2021 at 14:26
  • Thank you for this detailed answer! Do you think it would also be possible to use the Raspion by the German publishing house / computer magazine Heise c't?
    – luke359
    Commented Jan 22, 2021 at 8:02
  • Hi @MechMK1 , I asked a friend about this topic and he recommended me mitmproxy. Heise ct Raspion (mentioned above) also uses mitmproxy so that seems like another possible solution.
    – luke359
    Commented Jan 23, 2021 at 19:56
  • @luke359 Yes, I mentioned mitmproxy in my answer. The "problem" (if you can call it that), is that it only works for HTTP. If the traffic is not HTTP (e.g. a proprietary protocol), then you have to use a "generic" proxy.
    – user163495
    Commented Jan 23, 2021 at 21:48
  • If the source code checks the server certificate, you've got more work to do.
    – Joshua
    Commented Oct 23, 2021 at 23:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .