After my first post on relaying YubiKeys, I got a suggestion to see if it was possible to also relay FIDO2-based logins, after confirming that FIDO2 are not only used for web-based authentication I went and bought a newer YubiKey and got into testing. A FIDO2 YubiKey can be used as a second factor or used for passwordless authentication and is supposed to be immune to phishing, the screenshot below from yubico.com
Knowing anything claiming to be “not subjected to phishing” is a scam I started to look at the authentication flow. The server responses with a challenge that we sign and send back, metadata and tamper protection is included in both packets.
The problem to solve was navitor.credentials.get used by Chrome and Firefox to sign FIDO2 authentications only works in HTTPS(works with self-signed), in the server response there is a
"rpId":"demo.yubico.com" value that must match the sign-in URL or at least some parts of it, and there is a timeout so the phishing server needs to ask for a new challenge when the timeout is reached.
demo.yubico.com allow subdomains to authenticate against the domain due to not verifying the origins value in our response so if we could compromise or hijack a subdomain, for example,
verification.demo.yubico.com then we could use that to relay the FIDO2 packets to
demo.yubico.com, making it vulnerable to phishing. Just because subdomains can be used for
demo.yubico.com doesn’t necessary means that it’s the same for xyz.
Demo below demonstrates a subdomain takeover that’s being used to phish passwordless FIDO2 logins for
demo.yubico.com. The attacker is on the left panel and the victim is on the right panel
FIDO2 is not only used to authenticate against useless social media sites such as Facebook or blockchain wallets full of un-liquid shitcoins but It’s also used in enterprise environments that host their own Certificate Authority and DNS server. An Active Directory environment has the 2 things needed for FIDO2 phishing, a DNS Server to add a record for the phishing domain and an ADCS(trusted as a Root CA) to enroll web server SSL certs. If your enterprise uses FIDO2 YubiKey to authenticate to internal network resources and an attacker gets a foothold on a workstation and wants to move latterly he could have the challenge signed less suspiciously by sending crafted APDU packets to the connected YubiKey device and use the built-in prompt asking for touch verification.
(In real life this would be injected as a DLL and have the I/O via named pipes and also have an extra prompt to encourage the user to insert the YubiKey instead of waiting for it to be inserted(or asking for touch verification after a process such as Firefox or Chrome as been started), to simplify the POC it was executed as a .exe and with a single prompt)
After the YubiKey has been touched we have our signed packet that we can send back to the server to establish an authenticated session.
Using hardware keys to authenticate against critical business systems, cloud or whatever estate will have their workstations targeted by attackers, and if an attacker accomplishes establishing foothold it doesn’t matter if you use a smartcard/hardware key as they will be used by the attacker. Any somewhat safe internal authentication must be combined with monitoring to detect suspicious behavior, without monitoring you are trusting the authentication key to be 100% protected which is never the case.
All code has been uploaded to https://github.com/cube0x0/YubiKey-Relay