WireGuard Archive on lore.kernel.org
 help / color / Atom feed
* Deterministic Cryptographically Authenticated Network Signatures on Windows NLA
@ 2019-06-27 14:26 Jason A. Donenfeld
  2019-06-28 16:25 ` zrm
  0 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2019-06-27 14:26 UTC (permalink / raw)
  To: WireGuard mailing list

Hi,

Recently there's been a decent amount of Windows reverse engineering
and research in order to come up with some rather simple but important
results. I figure it might be useful to document parts of this
somewhere.

On Windows, when an interface connects to an endpoint, it generates a
"Network Signature", which is supposed to uniquely identify a network.
This is done through the conjunction of the nla and network list
services, and the kernel. For wifi, it uses aspects about the AP and
SSID. For wwan, it uses details from there. And in general, for layer
2 connections, it hashes the mac address of the default gateway.  This
is sort of a terrible way to identify a network, since mac addresses
can be spoofed. It looks like Microsoft has toyed with trying to make
this less bad, with various papers and patents and whatnot for
"authenticated dhcp" with some fancy/dated crypto, but it doesn't
appear that these have gone anywhere. For layer 3 networks, nla
doesn't really know what to do and so winds up just hashing the GUID
of the NetCfgInstanceId for the interface. This means that every
particular layer 3 interface instance implies only a single network.

This Network Signature stuff matters because Windows will
automatically fiddle with firewall rules based on which network you're
connected to. Forge a network, and you can perhaps get a victim to
have a more permissive firewall.

For WireGuard, we're using Wintun interfaces [1]. We could roll with a
single interface, which then would have the same Network Signature and
hence firewall settings, no matter which WireGuard peers its hooked up
with. Or, we could have a new interface for every new connection
event, but this means adding an unbounded amount of garbage to the
registry and cluttering people's interface names with things like
"Local Area Connection 28912", because this is the 28912th time you've
used WireGuard. Neither is so ideal.

Since Wintun is a layer 3 interface, it turns out "all" we need to do
is deterministically generate the GUID at adapter installation time. I
couldn't find any documented way of doing this. After reversing 3
kernel drivers and 5 userland DLLs, I found that Windows is using a
certain registry value as a sort of temporary storage in between two
phases that it runs serially. By using the super old and ugly
SetupAPI, we're actually able to split these phases up, so that we can
modify this registry key before the next phase sees it. This is sort
of like exploiting a race condition, except we're able to entirely
pause the race while making our modifications, so we have 100%
reliability. This winds up looking something like:

CallClassInstaller(DIF_REGISTER_COINSTALLERS)
key = OpenDevRegKey(DICS_FLAG_GLOBAL, DIREG_DRV)
key.SetString("NetSetupAnticipatedInstanceId", deterministicGUID)
CallClassInstaller(DIF_INSTALLINTERFACES)

At the time of writing, other than our own source code, there are no
hits for NetSetupAnticipatedInstanceId on Google, Bing, Yandex, or
Baidu, so this might be the first description of such a technique.

So, now that we can control the GUID and hence the NetworkSignature,
we have to decide what determines a network. It turns out that in
WireGuard, we can do this with much higher cryptographic assurance
than any of the crazy "authenticated dhcp" proposals of Microsoft.
Specifically, we know our own interface public key, the public keys of
everyone we're willing to talk to, and which IP addresses we'll accept
from those peers. If that doesn't perfectly define a network, I don't
know what else does.

Therefore, we sort the public keys, and sort the allowed IPs for each
one, and then hash together a big block that looks like:

 label || len(interface name) || interface name ||
 interface public key || number of peers ||
 peer public key || number of peer allowed ips ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 ...
 peer public key || number of peer allowed ips ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 len(allowed ip string) || allowed ip/cidr in canonical string notation ||
 ...
 ...

We pick a stable encoding for each of those elements (32-bit little
endian integers, canonical IP address strings, well-known label
identifier, etc), pass it all to BLAKE2, and mint ourselves a fully
network-determined GUID.

Hopefully this should eliminate a class of firewall attacks on Windows
systems when using WireGuard. Perhaps this post will help others out
somewhere down the line.

By the way, since Windows security is pretty complex and hard to get
right -- and hard to even keep all of it in your head at the same time
-- we're maintaining an attacksurface.md [2] file, which evolves over
time to contain our latest understanding. Hopefully this will help
people point out where we're wrong, and also what areas we've
neglected to consider. If something there piques your interest, don't
hesitate to get in touch with security {at} wireguard ^dot^ com.

Regards,
Jason

[1] https://www.wintun.net/
[2] https://git.zx2c4.com/wireguard-windows/about/attacksurface.md
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Deterministic Cryptographically Authenticated Network Signatures on Windows NLA
  2019-06-27 14:26 Deterministic Cryptographically Authenticated Network Signatures on Windows NLA Jason A. Donenfeld
@ 2019-06-28 16:25 ` zrm
  2019-06-28 20:15   ` Jason A. Donenfeld
  0 siblings, 1 reply; 5+ messages in thread
From: zrm @ 2019-06-28 16:25 UTC (permalink / raw)
  To: wireguard

On 6/27/19 10:26, Jason A. Donenfeld wrote:
> So, now that we can control the GUID and hence the NetworkSignature,
> we have to decide what determines a network. It turns out that in
> WireGuard, we can do this with much higher cryptographic assurance
> than any of the crazy "authenticated dhcp" proposals of Microsoft.
> Specifically, we know our own interface public key, the public keys of
> everyone we're willing to talk to, and which IP addresses we'll accept
> from those peers. If that doesn't perfectly define a network, I don't
> know what else does.

The drawback of this approach is that if anything in the configuration 
changes at all, it becomes a different network. In theory that's the 
idea, but in practice changes to the configuration will sometimes happen 
that shouldn't change which network it is.

For example, if a peer suffers a key compromise then its key will have 
to change (and so thereby will the network GUID when calculated this 
way) but all of the firewall rules and things like that should remain as 
they are.

It may help to add a config option to allow the GUID for an interface to 
be manually assigned a specific value. That way it's possible to 
explicitly choose whether the configuration has changed in a way that 
should cause it to be treated as a different network or not.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Deterministic Cryptographically Authenticated Network Signatures on Windows NLA
  2019-06-28 16:25 ` zrm
@ 2019-06-28 20:15   ` Jason A. Donenfeld
  2019-07-02 20:47     ` Ivan Labáth
  0 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2019-06-28 20:15 UTC (permalink / raw)
  To: zrm; +Cc: WireGuard mailing list

On Fri, Jun 28, 2019 at 6:33 PM zrm <zrm@trustiosity.com> wrote:
> The drawback of this approach is that if anything in the configuration
> changes at all, it becomes a different network. In theory that's the
> idea, but in practice changes to the configuration will sometimes happen
> that shouldn't change which network it is.

No, that's the entire point. If you change your network configuration
-- which public keys (identities) are allowed to send what traffic,
then this should not map to collided network signature. You're free to
configure Windows to apply the same network profile and conditions to
a variety of network signatures, of course.

> For example, if a peer suffers a key compromise then its key will have
> to change (and so thereby will the network GUID when calculated this
> way) but all of the firewall rules and things like that should remain as
> they are.

Remap the new signature to the same network profile as before, in that
case. In fact, remove the old signature from the trusted network
profile, since now ostensibly it's compromised, given your premise.

> It may help to add a config option

We generally don't add nobs when there are sane secure solid defaults.

> to allow the GUID for an interface to
> be manually assigned a specific value. That way it's possible to
> explicitly choose whether the configuration has changed in a way that
> should cause it to be treated as a different network or not.

Sounds like a "shoot yourself in the foot" situation.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Deterministic Cryptographically Authenticated Network Signatures on Windows NLA
  2019-06-28 20:15   ` Jason A. Donenfeld
@ 2019-07-02 20:47     ` Ivan Labáth
  2019-07-03  5:42       ` Matthias Urlichs
  0 siblings, 1 reply; 5+ messages in thread
From: Ivan Labáth @ 2019-07-02 20:47 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: WireGuard mailing list

Hi Jason,

while the idea of Deterministic Cryptographically Authenticated
Network Signatures is commendable, what is the *purpose* of the
network signature in Windows?

On Fri, Jun 28, 2019 at 10:15:39PM +0200, Jason A. Donenfeld wrote:
> On Fri, Jun 28, 2019 at 6:33 PM zrm <zrm@trustiosity.com> wrote:
> > The drawback of this approach is that if anything in the configuration
> > changes at all, it becomes a different network. In theory that's the
> > idea, but in practice changes to the configuration will sometimes happen
> > that shouldn't change which network it is.
> 
> No, that's the entire point. If you change your network configuration
> -- which public keys (identities) are allowed to send what traffic,
> then this should not map to collided network signature. You're free to
> configure Windows to apply the same network profile and conditions to
> a variety of network signatures, of course.

What would the procedure be when tweaking/changing the configuration
of the interface? If e.g. peer changes key, added ip, removed ip,
renumbered ip, ... some other trivial change. The more peers you have,
the more changes you have.

Using id from either local priv/pub key, interface name, both,
or possibly a config item seems most reasonable to me.

IMO, if you reuse the same key for different networks, then you are
shooting yourself in the foot, so it is a sufficient identifier.
Add short warning to documentation if appropriate:
"Interface public key is used as the network identifier in Windows.
Its reuse will reuse settings of e.g. firewall."

Regards,
Ivan
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Deterministic Cryptographically Authenticated Network Signatures on Windows NLA
  2019-07-02 20:47     ` Ivan Labáth
@ 2019-07-03  5:42       ` Matthias Urlichs
  0 siblings, 0 replies; 5+ messages in thread
From: Matthias Urlichs @ 2019-07-03  5:42 UTC (permalink / raw)
  To: wireguard

On 02.07.19 22:47, Ivan Labáth wrote:
> while the idea of Deterministic Cryptographically Authenticated
> Network Signatures is commendable, what is the *purpose* of the
> network signature in Windows?

The network signature's purpose depends on your network policy. For some
it's a strict "this network requires that firewalling and access policy
and whatnot", for others it's a far more fluid concept.

Thus, if you're in the latter situation and you use some program that
changes your WG setup, that same program can associate the new signature
with the existing rules, assuming it has the rights to do so. Problem
solved.

-- 
-- Matthias Urlichs

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27 14:26 Deterministic Cryptographically Authenticated Network Signatures on Windows NLA Jason A. Donenfeld
2019-06-28 16:25 ` zrm
2019-06-28 20:15   ` Jason A. Donenfeld
2019-07-02 20:47     ` Ivan Labáth
2019-07-03  5:42       ` Matthias Urlichs

WireGuard Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/wireguard/0 wireguard/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 wireguard wireguard/ https://lore.kernel.org/wireguard \
		wireguard@lists.zx2c4.com
	public-inbox-index wireguard

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.zx2c4.lists.wireguard


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git