Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hello list! I wanted to share my progress on schannel session keys extraction. First of all, I've written a two-part series that documents my efforts, see [1] and [2]. They are rather lengthy and mainly focus on the debugging and reversing parts. Secondly, the current iteration of the tool ([3]) is able to extract both TLS1.2 and TLS1.3 key material in the format digestible by vanilla Wireshark at least on Win10 (but should work on any x64 windows) for both client and server connection. My experiments on schannel's experimental TLS1.3 support seem to show that it currently lacks support for session resumption (see [2]), but I I'm not quite certain if this is not something that I did wrong. Any feedback on the tool and especially any feedback regarding schannel + TLS1.3 + session resumption is very much appreciated. I'd like to thank Peter for continuous interest and for the links shared. George. [1] https://b.poc.fun/decrypting-schannel-tls-part-1/ [2] https://b.poc.fun/decrypting-schannel-tls-part-2/ [3] https://github.com/sldlb/win-frida-scripts/tree/master/lsasslkeylog-easy On 19.06.2020 00:58, Peter Wu wrote: > Hi George, > > On Thu, Jun 18, 2020 at 08:29:41PM +0300, webpentest wrote: >> Hello again, Peter and wireshark-dev! >> >> While testing and extending my schannel-sslkeylog tool that I previously >> mentioned in the list ([1]), I found that in some cases I'm currently >> not able to reliably tie extracted master secret to a client random, >> because of the TLS Session Hash being in use (a.k.a "Extended Master >> Secret", see RFC 7627). >> In these cases I can only currenty reliably get a pair of session_hash, >> master_secret, but this format is currently not supported by wireshark's >> keylogfile parser. >> >> I was wondering whether a patch implementing this kind of sslkeylog >> format (e.g. SESSION_HASH ) would be considered for >> inclusion into wireshark? The amount of changes needed seem to be rather >> small -- much smaller than my previous patch we discussed. > That sounds reasonable. The session_hash (hash over all handshake > messages) can indeed easily be implemented in the current form. In fact, > it appears that this is currently unconditionally calculated when the > secret is not yet available. > > It could potentially be useful when the Client Random collides (in the > Go crypto/tls test suite it is all zeroes). > >> Of course some workarounds exist and extracting a client secret or a >> session id must be possible, but it probably would make my tool much >> less portable, because the API that I currently hook (namely, >> SslGenerateMasterKey[2] and SslImportMasterKey [3] from ncrypt.dll) is >> at least partially documented and more or less stable, whereas >> extracting client secret or a session id for sessions that use Extended >> Master Secret would require tapping into less-documented and less-stable >> schannel.dll APIs. >> >> Regards, George. >> >> >> [1] http://b.poc.fun/sslkeylog-for-schannel/ >> [2] >> https://docs.microsoft.com/en-us/windows/win32/seccng/sslgeneratemasterkey >> [3] https://docs.microsoft.com/en-us/windows/win32/seccng/sslimportmasterkey > Based on these two docs, I was not able to see where the session_hash is > available. Would you mind elaborating on the (reverse engineered?) > details? There are already a couple of formats, so ideally those can be > reused. If not, then hopefully the proposed new addition covers this and > future cases. ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hi George, On Thu, Jun 18, 2020 at 08:29:41PM +0300, webpentest wrote: > Hello again, Peter and wireshark-dev! > > While testing and extending my schannel-sslkeylog tool that I previously > mentioned in the list ([1]), I found that in some cases I'm currently > not able to reliably tie extracted master secret to a client random, > because of the TLS Session Hash being in use (a.k.a "Extended Master > Secret", see RFC 7627). > In these cases I can only currenty reliably get a pair of session_hash, > master_secret, but this format is currently not supported by wireshark's > keylogfile parser. > > I was wondering whether a patch implementing this kind of sslkeylog > format (e.g. SESSION_HASH ) would be considered for > inclusion into wireshark? The amount of changes needed seem to be rather > small -- much smaller than my previous patch we discussed. That sounds reasonable. The session_hash (hash over all handshake messages) can indeed easily be implemented in the current form. In fact, it appears that this is currently unconditionally calculated when the secret is not yet available. It could potentially be useful when the Client Random collides (in the Go crypto/tls test suite it is all zeroes). > Of course some workarounds exist and extracting a client secret or a > session id must be possible, but it probably would make my tool much > less portable, because the API that I currently hook (namely, > SslGenerateMasterKey[2] and SslImportMasterKey [3] from ncrypt.dll) is > at least partially documented and more or less stable, whereas > extracting client secret or a session id for sessions that use Extended > Master Secret would require tapping into less-documented and less-stable > schannel.dll APIs. > > Regards, George. > > > [1] http://b.poc.fun/sslkeylog-for-schannel/ > [2] > https://docs.microsoft.com/en-us/windows/win32/seccng/sslgeneratemasterkey > [3] https://docs.microsoft.com/en-us/windows/win32/seccng/sslimportmasterkey Based on these two docs, I was not able to see where the session_hash is available. Would you mind elaborating on the (reverse engineered?) details? There are already a couple of formats, so ideally those can be reused. If not, then hopefully the proposed new addition covers this and future cases. -- Kind regards, Peter Wu https://lekensteyn.nl ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hello again, Peter and wireshark-dev! While testing and extending my schannel-sslkeylog tool that I previously mentioned in the list ([1]), I found that in some cases I'm currently not able to reliably tie extracted master secret to a client random, because of the TLS Session Hash being in use (a.k.a "Extended Master Secret", see RFC 7627). In these cases I can only currenty reliably get a pair of session_hash, master_secret, but this format is currently not supported by wireshark's keylogfile parser. I was wondering whether a patch implementing this kind of sslkeylog format (e.g. SESSION_HASH ) would be considered for inclusion into wireshark? The amount of changes needed seem to be rather small -- much smaller than my previous patch we discussed. Of course some workarounds exist and extracting a client secret or a session id must be possible, but it probably would make my tool much less portable, because the API that I currently hook (namely, SslGenerateMasterKey[2] and SslImportMasterKey [3] from ncrypt.dll) is at least partially documented and more or less stable, whereas extracting client secret or a session id for sessions that use Extended Master Secret would require tapping into less-documented and less-stable schannel.dll APIs. Regards, George. [1] http://b.poc.fun/sslkeylog-for-schannel/ [2] https://docs.microsoft.com/en-us/windows/win32/seccng/sslgeneratemasterkey [3] https://docs.microsoft.com/en-us/windows/win32/seccng/sslimportmasterkey On 02.05.2020 02:22, Peter Wu wrote: > On Sat, May 02, 2020 at 01:48:12AM +0300, webpentest wrote: >>> Since it relies on undocumented structures, maybe you could make an >>> automated test that you run with GitHub Actions to check whether it >>> keeps working? That can act as usage documentation as well. >> Some automated testing is a good idea, not sure how applicable would GH >> Actions be, because this probably needs to be eventually tested across >> multiple different versions of windows... > Based on https://github.com/actions/virtual-environments, it looks like > Windows Server 2016 and Windows Server 2019 are supported. There are > other CI platforms such as AppVeyor, they offer Windows Server 2012 R2, > 2016 and 2019: https://www.appveyor.com/docs/windows-images-software/ > > I'll leave it up to you to figure out a CI platform. Worst-case, you > don't have regression tests for older platforms. Best case, you catch > issues with newer platforms. And in any case, you could keep a local > fleet of machines and run the same automated scripts :-) > >>> With TLS 1.2, it resumes with the same master secret. So as long as you >>> have extracted the master secret from previous sessions, you should be >>> able to use the same master secret if you combine it with the Client >>> Random from the second session. >> By the way, if wireshark sees both the original handshake and the new >> resumed one, but the keylog file only contains master key for the first >> client random, I assume it will still decode the resumed session correctly? > Correct, Wireshark will associate the Session ID (or session tickets, if > there are any) with the master secret. It basically implements what a > normal client would do for session resumption. > >> My current understanding is that as I'm hooking the key creation >> procedure in lsass, it is not triggered during a resumption, because the >> key does not need to be recomputed for resumption. > That sounds reasonable, all that lsass would have to export is a session > ID or session ticket. Maybe you can extract these and use the "RSA > Session-ID:" format I mentioned before? (And "RSA" is really a misnomer, > it is independent of the key exchange.) > >> Also, for my testing it would be really nice to be able to quickly find >> out from wireshark's ssl debug log if there was any session not >> decrypted. Or, even better - is there a way to filter not-decrypted tls >> in the UI? > The Finished message is normally encrypted, you could match that as > quick test: > > tshark -r your.pcap -otls.keylog_file:keys.txt -Ytls.handshake.verify_data > > These are usually directly sent together with the ChangeCipherSpec > message. Assuming that is the case, then the following filter will show > non-empty output if there are sessions that fail decryption: > > tls.change_cipher_spec and not tls.handshake.verify_data > > Example info column for that case (tshark -Tfields -e_ws.col.Info ...): > > Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message > Change Cipher Spec, Encrypted Handshake Message > > Example info column for the case where decryption succeeds: > > Client Key Exchange, Change Cipher Spec, Finished > Change Cipher Spec, Finished > > Hope it helps! ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe:
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
On Sat, May 02, 2020 at 01:48:12AM +0300, webpentest wrote: > > Since it relies on undocumented structures, maybe you could make an > > automated test that you run with GitHub Actions to check whether it > > keeps working? That can act as usage documentation as well. > > Some automated testing is a good idea, not sure how applicable would GH > Actions be, because this probably needs to be eventually tested across > multiple different versions of windows... Based on https://github.com/actions/virtual-environments, it looks like Windows Server 2016 and Windows Server 2019 are supported. There are other CI platforms such as AppVeyor, they offer Windows Server 2012 R2, 2016 and 2019: https://www.appveyor.com/docs/windows-images-software/ I'll leave it up to you to figure out a CI platform. Worst-case, you don't have regression tests for older platforms. Best case, you catch issues with newer platforms. And in any case, you could keep a local fleet of machines and run the same automated scripts :-) > > With TLS 1.2, it resumes with the same master secret. So as long as you > > have extracted the master secret from previous sessions, you should be > > able to use the same master secret if you combine it with the Client > > Random from the second session. > > By the way, if wireshark sees both the original handshake and the new > resumed one, but the keylog file only contains master key for the first > client random, I assume it will still decode the resumed session correctly? Correct, Wireshark will associate the Session ID (or session tickets, if there are any) with the master secret. It basically implements what a normal client would do for session resumption. > My current understanding is that as I'm hooking the key creation > procedure in lsass, it is not triggered during a resumption, because the > key does not need to be recomputed for resumption. That sounds reasonable, all that lsass would have to export is a session ID or session ticket. Maybe you can extract these and use the "RSA Session-ID:" format I mentioned before? (And "RSA" is really a misnomer, it is independent of the key exchange.) > Also, for my testing it would be really nice to be able to quickly find > out from wireshark's ssl debug log if there was any session not > decrypted. Or, even better - is there a way to filter not-decrypted tls > in the UI? The Finished message is normally encrypted, you could match that as quick test: tshark -r your.pcap -otls.keylog_file:keys.txt -Ytls.handshake.verify_data These are usually directly sent together with the ChangeCipherSpec message. Assuming that is the case, then the following filter will show non-empty output if there are sessions that fail decryption: tls.change_cipher_spec and not tls.handshake.verify_data Example info column for that case (tshark -Tfields -e_ws.col.Info ...): Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message Change Cipher Spec, Encrypted Handshake Message Example info column for the case where decryption succeeds: Client Key Exchange, Change Cipher Spec, Finished Change Cipher Spec, Finished Hope it helps! -- Kind regards, Peter Wu https://lekensteyn.nl ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
On 01.05.2020 23:24, Peter Wu wrote: > I wrote a script to do that and documented its usage on >> http://b.poc.fun/sslkeylog-for-schannel/. It is in now way generic >> (yet), but I successfully use in my research. Feel free to give it a go! >> The main problem really is to get crandom and correlate it with master key. > Thanks, right now I cannot test it but I'll keep this as reference! > > As for the linking with a session, if obtaining the Client Random is too > complicated, but a ClientHello.SessionID is available, consider using > the "RSA Session-ID:" format as done by the earlier SChannel work [1]. I think I've found an alternative way get the client random in a more reliable way. Preliminary testing is promising, but I'll need some additional time to flesh out the details. > Since it relies on undocumented structures, maybe you could make an > automated test that you run with GitHub Actions to check whether it > keeps working? That can act as usage documentation as well. Some automated testing is a good idea, not sure how applicable would GH Actions be, because this probably needs to be eventually tested across multiple different versions of windows... > > (Aside: maybe you can slap a Let's Encrypt certificate on your domain > and make it available over HTTPS?) Thanks for the heads-up, enabled https back. >> It is currently win-10 only, TLS1.2-only, does not work with resumed TLS >> sessions and poorly handles simultaneous connects. > With TLS 1.2, it resumes with the same master secret. So as long as you > have extracted the master secret from previous sessions, you should be > able to use the same master secret if you combine it with the Client > Random from the second session. By the way, if wireshark sees both the original handshake and the new resumed one, but the keylog file only contains master key for the first client random, I assume it will still decode the resumed session correctly? My current understanding is that as I'm hooking the key creation procedure in lsass, it is not triggered during a resumption, because the key does not need to be recomputed for resumption. Also, for my testing it would be really nice to be able to quickly find out from wireshark's ssl debug log if there was any session not decrypted. Or, even better - is there a way to filter not-decrypted tls in the UI? ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
On Fri, May 01, 2020 at 02:39:28PM +0300, webpentest wrote: > Hello Peter, > On 01.05.2020 01:23, Peter Wu wrote: > > > >> 1. A generic way to export schannel key material in SSLKEYLOG-like > >> format using elevated privilege and lsass.exe debugging / memory. > >> Preferably - the data that wireshark supports already - master secret > >> for tls <= 1.2 and the intermediate traffic secrets for tls 1.3 > > That would be great :-) > > I wrote a script to do that and documented its usage on > http://b.poc.fun/sslkeylog-for-schannel/. It is in now way generic > (yet), but I successfully use in my research. Feel free to give it a go! > The main problem really is to get crandom and correlate it with master key. Thanks, right now I cannot test it but I'll keep this as reference! As for the linking with a session, if obtaining the Client Random is too complicated, but a ClientHello.SessionID is available, consider using the "RSA Session-ID:" format as done by the earlier SChannel work [1]. The various available mappings can be found in the source code, but they are also summarized at https://security.stackexchange.com/a/42350/2630 [1]: https://www.blackhat.com/docs/us-16/materials/us-16-Kambic-Cunning-With-CNG-Soliciting-Secrets-From-SChannel.pdf Since it relies on undocumented structures, maybe you could make an automated test that you run with GitHub Actions to check whether it keeps working? That can act as usage documentation as well. (Aside: maybe you can slap a Let's Encrypt certificate on your domain and make it available over HTTPS?) > It is currently win-10 only, TLS1.2-only, does not work with resumed TLS > sessions and poorly handles simultaneous connects. With TLS 1.2, it resumes with the same master secret. So as long as you have extracted the master secret from previous sessions, you should be able to use the same master secret if you combine it with the Client Random from the second session. -- Kind regards, Peter Wu https://lekensteyn.nl ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hello Peter, On 01.05.2020 01:23, Peter Wu wrote: > >> 1. A generic way to export schannel key material in SSLKEYLOG-like >> format using elevated privilege and lsass.exe debugging / memory. >> Preferably - the data that wireshark supports already - master secret >> for tls <= 1.2 and the intermediate traffic secrets for tls 1.3 > That would be great :-) I wrote a script to do that and documented its usage on http://b.poc.fun/sslkeylog-for-schannel/. It is in now way generic (yet), but I successfully use in my research. Feel free to give it a go! The main problem really is to get crandom and correlate it with master key. It is currently win-10 only, TLS1.2-only, does not work with resumed TLS sessions and poorly handles simultaneous connects. ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hi George, On Thu, Apr 30, 2020 at 03:10:44PM +0300, webpentest wrote: [..] > Thanks for these additional resources! Just to clarify: extraction of > secrets from lsass.exe is absolutely possible; I was able to do that > successfully for on current windows 10. > > The problem here is the increasing layers of protection from accessing > lsass memory, such as Protected Process Light and others. Disabling > these protections is not trivial and in some cases might even be > impossible. Thus the main objective of my research was to explore ways > to not touch the memory of lsass.exe. Specifically for Protected Process Light, I found https://github.com/Mattiwatti/PPLKiller. It will probably not be suitable for production machines, but I see your point. Having all potential mechanisms documented would help :-) [..] > > The traffic secret is described in > > https://tools.ietf.org/html/rfc8446#section-7.3, it is the same > > handshake and application data secret that Wireshark already supports! > > So for TLS 1.3 support, hopefully you can use this mechanism without > > requiring further modifications to Wireshark. > > So, just to make sure that I understand you correctly, what you are > implying is that for TLS1.3 connections I might be able to extract not > the write keys, but the derived secrets, which would be preferable for > wireshark as it would enable using already-existing sslkeylog-parsing > functionality. Indeed. These are the keys for a simplified TLS 1.2 handshake: premaster secret = shared secret from RSA or DH key exchange master secret = hash(premaster secret) client/server write key/iv = hash(master_secret) Wireshark allows application data decryption when either the first secret or the second secret is provided. The "CLIENT_RANDOM" label maps to the second case. In TLS 1.3, not only the application data is encrypted, but part of the handshake as well. Both use different write key/iv values with different "master secrets". To complicate things, there are also different master secrets for the client->server and server->client directions. While TLS 1.3 decryption in Wireshark could be implemented with just the "premaster secret" (the (EC)DHE secret) and the optional PSK, at some point we settled with the hashes of those two secrets. That is why TLS 1.3 decryption in Wireshark needs at least four keys. As you can see in the simplified handshake, the master key alone is sufficient to compute the "write key" and "write iv". > I agree, but I fear that these structures you mention above are, alike > the tls1.2 master key, may exist only in the memory of lsass, but not > the application that uses schannel API - because of the same key > isolation feature. Indeed the secrets are available in lsass, but apparently for TLS 1.3 there exists a way to export these secrets. Maybe not purely passively though, I did not check whether this information is always communicated. In fact, I don't know much about Windows programming at all. > > Maybe something similar is > > available for TLS 1.2 and earlier support. If not, then we could add > > support for write key/iv, but only as a last resort. > > Seems to me that we have two separate (although, related) tasks at hand: > > 1. A generic way to export schannel key material in SSLKEYLOG-like > format using elevated privilege and lsass.exe debugging / memory. > Preferably - the data that wireshark supports already - master secret > for tls <= 1.2 and the intermediate traffic secrets for tls 1.3 That would be great :-) > 2. A generic way to export schannel key material for a particular > process _without_ using elevated privilege. Here I'm almost certain that > for TLS <= 1.2 exporting master secret is not possible, and I strongly > suspect that for TLS1.3 exporting traffic secrets is not possible as > well (but this I haven't yet verified). So if wireshark is to support > keys extracted this way, we need a patch that will allow using write > key/iv from a keylog - both for tls <= 1.2 and 1.3 As mentioned before, TLS 1.3 has double the number of keys (handshake and application data) while TLS 1.2 only has keys for application data. I guess that for simplicity, perhaps it is better to restrict this mechanism to TLS 1.2 for now. As a side note, I just realized that this mechanism could also be used for kTLS in the Linux kernel. That depends on the userspace application to perform the TLS handshake and provide (effectively) the write key and IV to the kernel. If one can tap into the kernel that way, it can transparently extract secrets without modifying userspace applications. https://www.kernel.org/doc/html/latest/networking/tls.html [..] > So, i would need to extend ssl_session->state with an additional flag > for cases where only the write keys are available (say, SSL_WRITE_KEYS) > and account for this situation in ssl_generate_keyring_material. > > I'll also have to extend SslDecryptSession to accomodate for write keys > and ivs,
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hello Peter, thanks for your answer. I have truncated some of the quoting in order to avoid inflating the size of the message. On 30.04.2020 12:58, Peter Wu wrote: > This would be the ideal approach as access to the master secret provides > full functionality. Apart from the links shared before, I found these > references in my notes which might help with such an implementation: > https://reverseengineering.stackexchange.com/questions/211/decryping-tls-packets-between-windows-8-apps-and-azure > https://reverseengineering.stackexchange.com/questions/2681/is-it-possible-to-decrypt-an-ssl-connection-short-of-bruteforcing > > Yes it will require some privileges, but someone with more expertise on > Windows might know their ways. Thanks for these additional resources! Just to clarify: extraction of secrets from lsass.exe is absolutely possible; I was able to do that successfully for on current windows 10. The problem here is the increasing layers of protection from accessing lsass memory, such as Protected Process Light and others. Disabling these protections is not trivial and in some cases might even be impossible. Thus the main objective of my research was to explore ways to not touch the memory of lsass.exe. >> 2. The derived keys, however, are available to the actual process that >> uses schannel. Notably, I can extract the client and server write keys >> and IV's, as well as the client random (see section 6.1 of RFC 5246, >> page 17). > In my notes I also found this reference describing extraction of the > "write keys", I suppose that is what you are using? > https://social.technet.microsoft.com/Forums/en-US/4041d78a-21bb-44fd-9a96-6579ea8129d1/obtaining-sslkeylogfilelike-data-from-edge-et-al-schannel-clients Thanks for this link, I've never encountered it before. It also has some additional motivation on why it might be preferable to lift the secrets from the process itself, not lsass. My approach is a little bit different to the one suggested, it does not envolve calls to ExportSecurityContext. Using a debugger I monitor local RPC communication between mstsc (in my example case) and lsass.exe. These messages contain both the client random and the write keys/ivs I am interested in. > Just to be clear about what "derived keys" are. You are referring to the > "write keys". The "derived keys" in that [3] link for TLS 1.3 are > comparable to the "master secret" in TLS 1.2. In TLS 1.2 and before the > master secret is sufficient to derive all those write keys that may be > used in the TLS session. In TLS 1.3, there are many more different > secrets for handshake encryption, application data encryption, and so > on: https://tools.ietf.org/html/rfc8446#page-93 > > The same write keys are present for TLS 1.3 though (see RFC 8446, > Section 7.3). Thanks for the clarification. So, if I understood correctly, tls 1.3 derives a set of intermediate secrets from master secret and then derives the keys for encryption from those secrets. And the keylog for tls1.3 contains the intermediate secrets, not the (write) keys themselves. I must admit that I haven't yet looked closely into TLS1.3 - I'm not yet ready to comment in detail on this and on your following suggestions regarding TLS1.3 and QUIC. > The idea could certainly be considered. There are limitations, but I > suppose that these would be preferable over having no decryption > capability at all. I think that this idea could be extended for TLS 1.3 > as well. > > Microsoft added an experimental implementation of TLS 1.3 in Windows 10, > version 1909: > https://docs.microsoft.com/en-us/windows/whats-new/whats-new-windows-10-version-1909 > > > typedef struct _SEC_TRAFFIC_SECRETS { > wchar_t SymmetricAlgId[SZ_ALG_MAX_SIZE]; // Negotiated symmetric > key algorithm. e.g. BCRYPT_AES_ALGORITHM. > wchar_t ChainingMode[SZ_ALG_MAX_SIZE]; // Negotiated symmetric > key algorithm chaining mode. e.g. BCRYPT_CHAIN_MODE_GCM or > BCRYPT_CHAIN_MODE_CCM. > wchar_t HashAlgId[SZ_ALG_MAX_SIZE]; // Negotiated hash > algorithm. e.g. BCRYPT_SHA256_ALGORITHM or BCRYPT_SHA384_ALGORITHM. > unsigned short KeySize; // Size in bytes of the > symmetric key to derive from this traffic secret. > unsigned short IvSize; // Size in bytes of the > IV to derive from this traffic secret. > unsigned short MsgSequenceStart; // Offset of the first > byte of the TLS message sequence to be protected with a key derived from > TrafficSecret. Zero to indicate the first byte of the buffer. > unsigned short MsgSequenceEnd; // Offset of the last > byte of the TLS message sequence to be protected with a key derived from > TrafficSecret. Zero if the secret is for the encryption of application data > or decryption of incoming records. > SEC_TRAFFIC_SECRET_TYPE TrafficSecretType; // Type of traffic > secret from the
Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hi George, On Thu, Apr 30, 2020 at 10:37:49AM +0300, webpentest wrote: > Hello list, > > I'm currently working on implementing a SSLKEYLOGFILE-like functions for > TLS connections that use Windows SChannel APIs (e.g. IE/Edge, as well as > other windows apps such as RDP client). SChannel does not expose its > keys, though some research was done on recovering them (see [1] and [2]). > > > I won't describe here the inner workings of schannel and key isolation > in Windows, but the bottom line is as follows: > > 1. The master key is only available to the lsass.exe process and > accessing it thus requires elevated privileges. Furthermore, there might > be additional restrictions that prevent event admins from accessing the > memory of lsass. This would be the ideal approach as access to the master secret provides full functionality. Apart from the links shared before, I found these references in my notes which might help with such an implementation: https://reverseengineering.stackexchange.com/questions/211/decryping-tls-packets-between-windows-8-apps-and-azure https://reverseengineering.stackexchange.com/questions/2681/is-it-possible-to-decrypt-an-ssl-connection-short-of-bruteforcing Yes it will require some privileges, but someone with more expertise on Windows might know their ways. > 2. The derived keys, however, are available to the actual process that > uses schannel. Notably, I can extract the client and server write keys > and IV's, as well as the client random (see section 6.1 of RFC 5246, > page 17). In my notes I also found this reference describing extraction of the "write keys", I suppose that is what you are using? https://social.technet.microsoft.com/Forums/en-US/4041d78a-21bb-44fd-9a96-6579ea8129d1/obtaining-sslkeylogfilelike-data-from-edge-et-al-schannel-clients > This means that it is possible to decrypt schannel traffic without the > need for elevated privilege, by extracting and using those derived keys, > but wireshark currently lacks the ability to ingest these values from a > keylog file. Currently it can use derived keys for decryption only for > TLS1.3 connections (see [3]). Just to be clear about what "derived keys" are. You are referring to the "write keys". The "derived keys" in that [3] link for TLS 1.3 are comparable to the "master secret" in TLS 1.2. In TLS 1.2 and before the master secret is sufficient to derive all those write keys that may be used in the TLS session. In TLS 1.3, there are many more different secrets for handshake encryption, application data encryption, and so on: https://tools.ietf.org/html/rfc8446#page-93 The same write keys are present for TLS 1.3 though (see RFC 8446, Section 7.3). > I've thrown together a quick and dirty implementation of using derived > keys to decrypt TLS1.2 (see [4]) and verified that it works: with the > keys that I extracted I was able to decrypt successfully the RDP > connection that I made from a windows client. > > So, now my question is as follows: > > 1. Considering the limited use-case for this functionality (using > derived keys to decrypt TLS1.2), does it have a chance of being merged > into upstream? The idea could certainly be considered. There are limitations, but I suppose that these would be preferable over having no decryption capability at all. I think that this idea could be extended for TLS 1.3 as well. Microsoft added an experimental implementation of TLS 1.3 in Windows 10, version 1909: https://docs.microsoft.com/en-us/windows/whats-new/whats-new-windows-10-version-1909 The following instructions to enable TLS 1.3 support was taken from https://github.com/microsoft/msquic/blob/master/docs/BUILD.md#test-instructions reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" /v Enabled /t REG_DWORD /d 1 /f reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" /v DisabledByDefault /t REG_DWORD /d 0 /f reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" /v Enabled /t REG_DWORD /d 1 /f reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" /v DisabledByDefault /t REG_DWORD /d 0 /f That document is part of Microsoft's QUIC stack which they opensourced two days ago under the MIT license, https://techcommunity.microsoft.com/t5/networking-blog/msquic-is-open-source/ba-p/1345441 QUIC relies on TLS 1.3 for keys an encryption (see https://tools.ietf.org/html/draft-ietf-quic-tls), so it might be worth checking out those sources to understand the current situation: https://github.com/microsoft/msquic/blob/master/src/platform/tls_schannel.c A particularly interesting starting point is the QuicTlsWriteDataToSchannel function which calls AcceptSecurityContext (for a server) or InitializeSecurityContextW (for clients). There is a BufferType =
[Wireshark-dev] Support for TLS1.2 decryption using derived keys
Hello list, I'm currently working on implementing a SSLKEYLOGFILE-like functions for TLS connections that use Windows SChannel APIs (e.g. IE/Edge, as well as other windows apps such as RDP client). SChannel does not expose its keys, though some research was done on recovering them (see [1] and [2]). I won't describe here the inner workings of schannel and key isolation in Windows, but the bottom line is as follows: 1. The master key is only available to the lsass.exe process and accessing it thus requires elevated privileges. Furthermore, there might be additional restrictions that prevent event admins from accessing the memory of lsass. 2. The derived keys, however, are available to the actual process that uses schannel. Notably, I can extract the client and server write keys and IV's, as well as the client random (see section 6.1 of RFC 5246, page 17). This means that it is possible to decrypt schannel traffic without the need for elevated privilege, by extracting and using those derived keys, but wireshark currently lacks the ability to ingest these values from a keylog file. Currently it can use derived keys for decryption only for TLS1.3 connections (see [3]). I've thrown together a quick and dirty implementation of using derived keys to decrypt TLS1.2 (see [4]) and verified that it works: with the keys that I extracted I was able to decrypt successfully the RDP connection that I made from a windows client. So, now my question is as follows: 1. Considering the limited use-case for this functionality (using derived keys to decrypt TLS1.2), does it have a chance of being merged into upstream? 2. If yes, is there a person familiar with wireshark's tls dissector, who is willing to advise me on what is the best way to implement these changes? I'm ready to spend time on reimplementing the patch, but I'll need someone for guidance and review. Regards, George Noseevich. [1] https://www.blackhat.com/docs/us-16/materials/us-16-Kambic-Cunning-With-CNG-Soliciting-Secrets-From-SChannel.pdf [2] https://osqa-ask.wireshark.org/questions/61698/decrypting-website-accessed-through-internet-explorer [3] https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12779#c17 [4] https://github.com/ngo/wireshark/commit/1d86cc67fac2bff5a3ceb392e469b0d443cd9d22 ___ Sent via:Wireshark-dev mailing list Archives:https://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://www.wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe