5

I have attempted to decrypt traffic between two .NET applications (both on Windows platforms) using Wireshark but due to the Diffie Hellman with perfect forward secrecy, I cannot use my private key from the server to decrypt the session keys. The applications are communicating using HTTP over TLS 1.2. My only hope is to get hold of the pre-master secrets from either the client or the server to do that. Unfortunately I have not been successful in this endeavour.

My need is to be able to observe what happens over a network and not necessarily see the contents of the messages but I do need to be able to identify requests which I only seem to know how to do when it is decrypted.

I know that Chrome and Firefox browsers can export a sslkeylog file that can be consumed by Wireshark if I set an environment variable SSLKEYLOGFILE to do so. This is useful to know but it won't help me in my case. I have a .NET client and server component and I've tried to google for ways to get IIS and .NET to extract those secrets but to no avail (they do have a feature request logged for .NET Core/5). There is a way using the SslStream and combining it with Bouncy castle's library but I am not using the TcpClient so that won't help me.

My only avenue (that I can think of) is to setup a reverse-proxy on the client side and let my client app connect to this reverse-proxy and let this reverse-proxy do the call and extract the secrets as well. I came across this question where people have answered by saying that nginx can be used to "intercept" the call and then write out to a sslkeylog file. You either attach the gdb to the running instance and hook in to some callback event OR you use some workaround by using a library that can override the existing library that nginx would have used. Problem with all those are that they are for Linux environments and not for Windows.

Is there a way for me to achieve the same but from a Windows perspective? I almost want to say using any tool, method, etc. (to get hold of the pre-master secrets)

I have noticed that there is this solution which is great if I need to look at the message dump (and there are ways to do that without using this method) but it only confines itself to the application itself.

Dandré
  • 171
  • 6
  • Two quick questions: 1. Are the messages using HTTPS protocol or something else (and if something else, what)? 2. Do you need Wireshark in particular (possibly due to a dissector is has for an uncommon protocol) or would some other tool that can capture the plain-text network traffic be acceptable? I ask because active interception is generally the way to go for stuff like this, and while Wireshark doesn't support that there are lots of tools that do, especially for HTTPS. – CBHacking Feb 28 '21 at 08:12
  • Thanks for the response. I have updated my question accordingly. In short, its HTTPS using TLS 1.2 and I need to observe a certain behaviour over a network, not view the contents of the message. Though for future reference I would like that as well. I only know how to trace messages when they are decrypted which is why I need them to be decrypt-able. If that makes sense. – Dandré Feb 28 '21 at 09:20

3 Answers3

4

Assuming the applications aren't using certificate / public key pinning (or that you can alter the pins if they are), your best bet is almost certainly an intercepting proxy.

There are a number of intercepting proxies out there, but I'm most familiar with Portswigger's "Burp Suite" and the free version of it will work fine for this, so I'll generally assume you're using that (you could probably also make Fiddler or Zap work here). I'm going to write these instructions from the assumption that you've never used an intercepting proxy before, but note that there are tons of guides online to how to use these tools.

Install the proxy on a machine in the same network as your two applications (it can be on the same machine as the client - the one that sends the requests - but you will need to change the server app's listening port or the client's request port if you want to install it on a machine that ever acts as a server) and start it up. If you're using Burp, it's a Java app and will run on anything (Win/Mac/Linux/etc.) with a suitable Java installation. The proxy will generate a "fake" CA key pair for HTTPS; you'll need to export that public key and install it as a trusted root certificate authority on the client machine(s). Set the browser proxy settings to use the IP address and port where Burp is listening (let its listening port through the firewall if needed) and test whether you can browse HTTPS sites using the browser, and whether they show up in Burp's log. If so, you're good to go.

It's possible your .NET app will respect the system proxy setting, in which case you don't need to change anything else; when it tries to talk to the server it will route through the proxy, and you can see everything it sends and receives. However, most apps aren't proxy-aware. To handle that, you can set the proxy to run in "invisible" mode, where it just acts as a web server and forwards the request appropriately (you can also explicitly configure it to forward requests, as a "reverse proxy"). If your app listens on 443 or a similarly low-numbered port, you may need to run Burp as Admin/root. Once Burp is listening on the port that the client sends requests to, go to the HOSTS file on the client (\Windows\System32\drivers\etc\hosts on Windows) and edit it (will need Admin/root privileges). Add an entry for the hostname of the server, pointing to the IP address of the Burp proxy.

The client will now connect to Burp when it's trying to connect to the real server. Burp will accept the connection, negotiate TLS using its own certificates (this is why you had to install Burp's CA cert), log every request, and forward them on to the expected destination (the server) over its own HTTPS connection (which Burp opens as a client). Burp will also log the server responses, and forward them back to the client as its own responses.

If the server is identified only by IP address, you can either change the IP address in the client and configure Burp to forward requests to the real IP address (reverse proxy mode), or you can install Burp on the server and either make the server listen on a different port (which you'll set Burp to forward to), or change the client to send requests to Burp's port (which Burp will forward to the usual server port). In the very unlikely case that the server listen and client request ports are hard-coded and the server address is hard-coded and the server is identified by IP address rather than hostname... you'll need to use something like ARP spoofing to get the request routed to you, and set things up so your proxy intercepts traffic for which its IP wasn't the actual destination. This is totally possible - SSLStrip does it, for example, though not using Burp - but you'll need to look into how to set it up.


Now, with all that said, there are a few other options.

  • Install on the client a modified version of the System.Net.Security assembly, such that all traffic through a TLS stream is logged to a file or similar. This might be complicated by assembly signing requirements, which would mean you'd need to modify the executable as well. This is all possible but could be a hassle. Also, if you don't have such a library to hand - one might exist out there but I don't know of it offhand - you'd need to decompile the official library and modify it, or install a shim library.
  • Decompile the client and/or server assembly and just read what requests it makes/receives and/or responses it expects/returns. Unless obfuscated, decompiling .NET is quite easy - recent versions of Visual Studio include built-in support, or you can use a third-party program like JustDecompile or similar - and even obfuscated code can usually be figured out with some work (the public symbols can't be renamed or hidden, which helps).
  • Decompile the client or server assembly and modify the function(s) that handle HTTPS requests/responses to additionally log the request/response text to a file or similar. Then recompile the assembly and run it instead of the original version (just move/rename the original, don't delete it).

(Obviously, if you would get in legal trouble for decompiling, don't do it)

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • Thank you for your response. Is there a way to tell Burp (what a strange name) to extract the pre-master secret keys used for the TLS key-exchange? That's what I'm really after. – Dandré Mar 05 '21 at 15:01
  • Burp itself? No. But you can probably make it use RSA key exchange, and you can definitely make it export the private key, so you'd be able to get the pMS from between the client and proxy. Proxy to original server will depend on what cipher suite they negotiate, as usual. I gotta ask though, why do you want the pMS? Anything useful you could do with it, you can also do by just having a full MitM position... – CBHacking Mar 05 '21 at 19:02
  • As stated in my question, I am faced with the TLS cipher suite that uses Diffie Hellman with perfect forward secrecy (ECDHE). I cannot use the private keys to decrypt that message, I can only accomplish this with the pMS (as I am not able to change the cipher suite). – Dandré Mar 05 '21 at 21:41
  • Well, you can control the cipher suites that Burp allows. If both the client and the server support ECDHE suites only then that makes it trickier; I don't think Burp offers a way (even via extension) to get the pMS. I still don't get why you want it, though; You say you need to be "able to identify requests", which is trivial when you've to a MitM position on the TLS stream. – CBHacking Mar 05 '21 at 22:58
  • The one concern is that I am not allowed to install such software on our production server, and even if I could I would have to open a port through our firewall and point our application through to the Burp app which is also another request we have to send off to our network providers. I wasn't even allowed to disable the ECDHE suite so that I could decipher the network traffic. So my only last option was to get hold of the pre-master secrets. I have solved our problem recently but for future reference I want to find out how to get hold of those secrets so I can decipher my network captures – Dandré Mar 06 '21 at 06:53
  • I think I finally found a tool that does exactly what I'm looking for and I think it was made possible after I started playing with Burp and doing further google searches. I noticed that python has a capability to dump those secrets in the same way your chrome browser would and then I finally found an app that works! I'll write up the answer. – Dandré Mar 06 '21 at 07:44
2

Story

After playing around with the Burp application (a great tool BTW, thanks CBHacking) I was disappointed to discover that it didn't offer the feature I needed which was to extract the pre-master keys. I did however (after some googling) discovered that Python (3.8+) has the capability to log those secrets to a text file like chrome would (I made the association when I stumbled across mitm_relay which used Burp as a viewer. I tried it after lots of effort only to come up short as it also didn't write out those keys like I hoped).

Solution

I then finally stumbled across mitmproxy. It is actually quite simple to get started. You don't have to setup a cert to use this reverse proxy since you just connect to it via normal HTTP and then you set it up to forward your requests as HTTPS AND it writes the keys to the file you specified using the SSLKEYLOGFILE environment variable (they were even considerate enough to add a separate variable to write to a separate file if you want to see your keys separately from all the other apps).

Setup

Follow these instructions for the ssl key logging.

Once you startup the application you will notice a browser window opening up (a nice way to monitor activity), so just select Options and Edit Options. With the editor opening up, scroll down till you see the field mode. In the value field, type in:

reverse:https://mydomain.com:443

reverse to indicate "Reverse proxy mode"

https://mydomain.com:443 to indicate the actual server you wish to target using a certain port.

Then I went to my client app and changed my address to:

http://localhost:8080/api/resource?id=xxx

http://localhost:8080 this is the default listening address for mitmproxy using normal HTTP.

api/resource?id=xxx is whatever your request string would look like for your HTTP request.

Fire up wireshark (while reading your sslkeylogging file) on your network adapter and start your client app and see how it decrypts your encrypted traffic (using ECDHE) in realtime.

Dandré
  • 171
  • 6
  • Hey mate! thanks for all the info. Obviously, your solution refers to HTTP protocol specifically. I'm trying to achieve the same thing but of a conversation using a different protocol (SMPP or TCP/IP) Any chance you know how? – Ben Aug 02 '22 at 13:13
-1

It is relativly simple to decrypt TLS/SSL traffic using Fiddler from Telerik. It works for any app running on Windows. Here are steps:

  1. Download Fiddler from https://www.telerik.com/download/fiddler .
  2. Install Fiddler
  3. Open Tools->Options-HTTPS menu
  4. Enable Capture HTTPS CONNECTs
  5. Set Decrypt HTTPS trafic
Sergey V.
  • 99
  • 1
  • The top voted answer explains Fiddler in *much* greater detail. And you do not explain if Fiddler, or your process, extracts the keys. – schroeder May 01 '22 at 10:39
  • The top voted answer provides details on Burp. It just mentions Fiddler as a possible alternative. I found Fiddler option much simpler to install/configure and use compare to other answers. – Sergey V. May 12 '22 at 17:49
  • And yet you don't go into any more detail than the other answer that mentions it ... – schroeder May 12 '22 at 18:34
  • Thank you for the feedback, I've revised the instruction to make it more clear. – Sergey V. May 17 '22 at 00:05