Sunday, February 10, 2019

Cisco Identity PSK and Freeradius


Cisco rolled out a feature called Identity PSK which tries to straddle the typical two authentication methods available today:
  1.  WPA2-Personal (also referred to as WPA2-PSK)
  2.  WPA2-Enterprise
With the Personal variant, we would typically enter a passphrase or preshared key (hence the PSK name) on both wireless client and DS (i.e. access point and/or controller system) and this passphrase is used for mutual authentication and is also part of the key derivation process. The major drawback here is that all devices on this network (SSID) have the same passphrase; if compromised, anyone could then access the network, as well as potentially snoop on other wireless clients' communications by decrypting their unicast traffic (see https://wiki.wireshark.org/HowToDecrypt802.11). In this case, the PMK, or pairwise master key, would be the same for all clients which leads to the ability to decrypt. Note that the PMK is not used to encrypt data, but along with the EAPOL 4-way handshake, is used to generate the keys that actually do encrypt the data.

This is improved upon by using WPA2-Enterprise with one of the supported EAP methods, such as EAP-TLS, EAP-PEAP, EAP-TTLS, etc. These can provide for different credentials (such as an x509 cert, username/password, etc.) used in the authentication process and each client could (should) have a unique credential; each wireless client then gets a unique PMK as well instead of sharing one with all clients. Decryption is thus significantly more difficult now because we not only need the EAPOL 4-way handshake, but the PMK. The PMK is delivered to the AP/controller system and the wireless client device for use, often protected via a TLS tunnel; this PMK has to be recovered to decrypt. There are several ways to possibly get at this PMK, such as
  1. Debug the RADIUS server or the AP/controller and have it log the PMK. If using Freeradius, try debugging with -X switch from the CLI.
  2. Capture and decrypt the RADIUS server to AP traffic (this traffic is protected by a secret that is shared between the AP and the RADIUS server).
Exact steps are left for future discussion but the recovered PMK can be used to decrypt wireless traffic even when WPA2-Enterprise is in use.

What if the wireless client does not support WPA2-Enterprise? Is there anything we can do to improve upon WPA2-Personal, and overcome the shared secret requirement so that if one passphrase is compromised, the whole system is compromised?

The idea here is to continue to use WPA2-Personal, but have some system in place that is able to support a per-device passphrase. As a client connects, it has it's own, possibly (hopefully) unique PMK, and the AP is able to use this to authenticate the device to allow encrypted communications. To do this, Cisco uses a RADIUS server which delivers a passphrase to the AP based on the MAC address of the client. In addition, a normal passphrase could be used so devices that do not have unique passphrases could use the standard one, just like a typically WPA2-Personal deployment. But if the standard passphrase is used as a fall-back, then we really have not taken our security to the next level as many of the issues are still present: rogue clients can still connect to the network with the compromised shared passphrase and access the network. There is still a slight improvement in that it would not be possible to decrypt other clients' unicast communications because they would still be using a different PMK based on this feature providing for unqiue passphrases, per device.

There are plenty of web resources for this, such as Cisco documentation which is typically very good:

As well as other websites which details some ways to configure the feature using Cisco ISE or ACS backends as RADIUS servers. Unfortunatly, my Cisco ACS is in production use and I do not want to go playing with the configuration. Over the years, I have found Freeradius running on Linux to be a great tool, especially for test, as it is very flexible and easy to use. So the idea here is to see if we can make use of this new iPSK feature but use Linux with Freeradius as the RADIUS server to deliver the unique passphrases which are then converted to PMKs, for the various clients.


WLC Controller setup


Make sure a supported version of code is used; not all of them support this feature. I think it was released with 8.5; I am using 8.8 series code on a WLC3504 platform with AP3802. The link above shows the screenshots for configuring the feature and it is pretty straightforward. There are basically three steps on top of what you would do for a typical WPA2-Personal deployment:

1. Configure MAC Filtering on the WPA2-Personal SSID; be sure to set a passphrase here as well (though we won't use it - we will use the per-client passphrase from the RADIUS server):



2. Configure AAA servers at the SSID level.  Also be sure to configure more details, such as the RADIUS secret, under Security ~> AAA ~> RADIUS ~> Authentication: 



3. Select Allow AAA Override




Freeradius Configuration


As all the examples are for Cisco ISE or ACS that I could find (with Google as my friend), we are on our own here. Some sites indicated what was needed for the feature to work: the RADIUS server has to reply with an Access-Accept RADIUS message, along with the top two cisco-av-pair attributes:


I had to reverse engineer what the Cisco controller was sending to the RADIUS server so I could figure out how to get Freeradius to accept it, and then return the correct values based on the information provided (i.e. a specific client MAC address requires return of a specific PSK or passphrase).

The RADIUS Access-Request from the Cisco WLC – via Wireshark.  This is sent from the wireless controller to the RADIUS server to obtain the passphrase that this specific client will use to authenticate to the WiFi system:

  • Frame 12209: 286 bytes on wire (2288 bits), 286 bytes captured 
  • Ethernet II, Src: 00:11:22:14:3f:40 (00:11:22:14:3f:40), Dst: 00:11:22:17:8e:b7 (00:11:22:17:8e:b7)
  • Internet Protocol Version 4, Src: 192.168.107.26, Dst: 192.168.206.12
  • User Datagram Protocol, Src Port: 56525, Dst Port: 1812
  • RADIUS Protocol
    • Code: Access-Request (1)
    • Packet identifier: 0x1 (1)
    • Length: 244
    • Authenticator: 2b91a2ce6163492a4249b6c5ac0db3d6
    • [The response to this request is in frame 12210]
  • Attribute Value Pairs
    • AVP: t=User-Name(1) l=14 val=00112208d12d
    • AVP: t=Called-Station-Id(30) l=26 val=0c-d0-f8-95-3a-40:LWAPV7
    • AVP: t=Calling-Station-Id(31) l=19 val=00-11-22-08-d1-2d
    • AVP: t=NAS-Port(5) l=6 val=1
    • AVP: t=NAS-IP-Address(4) l=6 val=192.168.107.26
    • AVP: t=NAS-Identifier(32) l=8 val=lwapv7
    • AVP: t=Vendor-Specific(26) l=12 vnd=Airespace, Inc(14179)
    • AVP: t=User-Password(2) l=18 val=Encrypted
      • Type: 2
      • Length: 18
      • User-Password (encrypted): 2add9b0280e6b540582183b55676fdee
    • AVP: t=Service-Type(6) l=6 val=Call-Check(10)
    • AVP: t=Framed-MTU(12) l=6 val=1300
    • AVP: t=NAS-Port-Type(61) l=6 val=Wireless-802.11(19)
    • AVP: t=Tunnel-Type(64) l=6 Tag=0x00 val=VLAN(13)
    • AVP: t=Tunnel-Medium-Type(65) l=6 Tag=0x00 val=IEEE-802(6)
    • AVP: t=Tunnel-Private-Group-Id(81) l=4 val=30
    • AVP: t=Vendor-Specific(26) l=49 vnd=ciscoSystems(9)
    • AVP: t=Acct-Session-Id(44) l=32 val=5c5f5cb0/00:11:22:08:d1:2d/211

We can see the request is for a specific user, which is the client MAC address with no separators, and then what appears to be an encrypted password. We would need the decrypted password as part of the Freeradius configuration if we want to use this in authenticating a device. There are Freeradius instructions for simple MAC filtering; but, if we have a username and password, we might be able to put these in the users config file and then it might just work.

To get the encrypted user-password to see what the Cisco WLC is sending over, we can use either Wireshark or radsniff to decrypt it. For Wireshark, under Edit ~> Preferences ~> Protocols ~> Radius, enter in the RADIUS shared secret in use for this installation and this field will then show as decrypted. Alternatively, use radsniff like so:

user@LinuxVM:~$ radsniff -x -s <secret> radius.pcap

This will decrypt the fields and we can evaluate them. In this case, from radsniff, we have:
2019-02-09 18:05:20.261808 (35) Access-Request Id 1 radius.pcap:192.168.107.26:56525 -> 192.168.206.12:1812 +103.219User-Name = "00112208d12d"User-Password = "00112208d12d"NAS-IP-Address = 192.168.107.26NAS-Port = 1Service-Type = Call-CheckFramed-MTU = 1300Called-Station-Id = "0c-d0-f8-95-3a-40:LWAPV7"Calling-Station-Id = "00-11-22-08-d1-2d"NAS-Identifier = "lwapv7"NAS-Port-Type = Wireless-802.11Acct-Session-Id = "5c5f5cb0/00:11:22:08:d1:2d/211"Tunnel-Type:0 = VLANTunnel-Medium-Type:0 = IEEE-802Tunnel-Private-Group-Id:0 = "30"Airespace-Wlan-Id = 3Cisco-AVPair = "audit-session-id=c0a8011a000000165c5f5cb0"Authenticator-Field = 0x2b91a2ce6163492a4249b6c5ac0db3d6


We can see that the password is the same as the username – the client MAC address. Easy enough; let's add this to the /etc/freeradius/3.0/user file and fill in the parts we need. Included is the VLAN for the client, but this is not necessary:

   00112208d12d Cleartext-Password := "00112208d12d"
      Calling-Station-ID == "00-11-22-08-d1-2d",
      Tunnel-Type = VLAN,
      Tunnel-Medium-Type = IEEE-802,
      Tunnel-Private-Group-ID = 30,
      Cisco-AVPair = "psk-mode=ascii",

      Cisco-AVPair = "psk=SuPeRs3cRet"

Now we have a username and password for RADIUS to check against; on accept, we should get the passphrase to use for deriving the PMK. This passphrase is what we enter into the WiFi password field on the device:
  • Frame 12210: 126 bytes on wire (1008 bits), 126 bytes captured (1008 bits)
  • Ethernet II, Src: 00:11:22:17:8e:b7 (00:11:22:17:8e:b7), Dst: 00:11:22:14:3f:40 (00:11:22:14:3f:40)
  • Internet Protocol Version 4, Src: 192.168.206.12, Dst: 192.168.107.26
  • User Datagram Protocol, Src Port: 1812, Dst Port: 56525
  • RADIUS Protocol
    • Code: Access-Accept (2)
    • Packet identifier: 0x1 (1)
    • Length: 84
  • Authenticator: c3278bfd79b54079a5a3b80009959c55
    • [This is a response to a request in frame 12209]
    • [Time from request: 0.000256000 seconds]
  • Attribute Value Pairs
    • AVP: t=Tunnel-Type(64) l=6 Tag=0x00 val=VLAN(13)
    • AVP: t=Tunnel-Medium-Type(65) l=6 Tag=0x00 val=IEEE-802(6)
    • AVP: t=Tunnel-Private-Group-Id(81) l=4 val=30
    • AVP: t=Vendor-Specific(26) l=22 vnd=ciscoSystems(9)
      • Type: 26
      • Length: 22
      • Vendor ID: ciscoSystems (9)
      • VSA: t=Cisco-AVPair(1) l=16 val=psk-mode=ascii
    • AVP: t=Vendor-Specific(26) l=26 vnd=ciscoSystems(9)
      • Type: 26
      • Length: 26
      • Vendor ID: ciscoSystems (9)
      • VSA: t=Cisco-AVPair(1) l=20 val=psk=SuPeRs3cRet




Notice that the PSK value is not encrypted when returned to the WLC. Hopefully, the wired network between the WLC and the RADIUS server is protected to prevent disclosure of this cryptographic information. I experimented with encrypting this in different ways within Freeradius (via entries in the dictionary file) but none of them worked.  Perhaps an IPSec tunnel?

Once the AP has this value, and the wireless client was already programmed with this, the typical WPA2-Personal authentication process can succeed. To add more devices, copy the lines from the users file and change the relevant bits: username/password with the new MAC address, the new PSK value to use, etc. If there are lots of devices, we probably need to look into integrating a database.

Results


We are able to use Freeradius as the RADIUS backend for a Cisco iPSK installation. There were some issues to note:

  1. With this method, the regular or standard passphrase entered into the controller does not work. As MAC filtering is enabled, the RADIUS server is consulted for each client and if there is not a proper entry of username/password in the users file, an Access-Reject message is returned and the client never gets to use the regular shared passphrase. For my tests and my possible production use, this is fine: we want all devices to use a unique authenticator so this is actually preferred behavior. To overcome this, if needed, we would probably need to implement some form of MAC authentication fall-through where specific MACs are allowed, or even any MAC is allowed and then the shared passphrase is used to authenticate not at the RADIUS server, but at the AP.
  2. There were some timing difficulties identified. As this feature is generally geared toward devices that don't support WPA2-Enterprise, we would not likely see this on a laptop or newer wireless devices such as smartphones, etc. However, on some embedded devices tested, some just could never get into the network. Debugging, it was observed that there is now a longer delay in answering an Association Request with a Response, and then EAPOL Key 1. With a typical WPA2-Personal configuration, it was usually <5ms to respond to the Association Request; here, with the iPSK feature in this environment, it was more on the order of 75ms at a minimum, up to 150ms observed. Not all clients could support this delay so would not be a candidate for this feature. This test network is small; there are few wireless devices, channel utilization is low, all wired infrastructure is GigE, and the RADIUS server has plenty of CPU and memory and is lightly loaded, really doing nothing else. Based on this test setup, it is expected that these latencies might be on the lower end of what might be observed, so if a client runs into this timing issue, I would start by debugging the client instead of trying to reduce the RADIUS process latency.