Wireshark-dev: Re: [Wireshark-dev] Support for TLS1.2 decryption using derived keys

From: webpentest <webpentest@xxxxxxxxx>
Date: Thu, 18 Jun 2020 20:29:41 +0300
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 <hash> <master_key>) 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!