age verifies your account automatically as an adult on any website using k-id
made by xyzeva and Dziurwa, hosted by Colbster937, greetz to amplitudes (for previous work)
project is now closed source to keep the bypass working longer
the age verifier is currently patched, we are working on a fix and will update this page when one is found.
k-id, the age verification provider discord uses, doesn't store or send your face to the server.
instead, it sends a bunch of metadata about your face and general process details. while this is
good for your privacy (considering some other providers send actual videos of your face to their servers), its also bad for them, because we can just send legitimate looking metadata to their servers
and they have no way to tell its not legitimate.
while this was easy in the past, k-id's partner for face verification (faceassure) has made this significantly
harder to achieve after amplitudes k-id verifier was released, (which doesn't work anymore because of it.)
with discord's decision of making the age verification requirement global, we decided to look into
it again to see if we can bypass the new checks.
the first thing we noticed that the old implementation doesn't send when comparing a legitimate
request payload with a generated one, is its missing encrypted_payload, auth_tag, timestamp and iv in the body.
looking at the code, this appears to be a simple AES-GCM cipher with the key being nonce + timestamp + transaction_id, derived using HKDF (sha256). we can easily replicate this and also create the missing
parameters in our generated output.
heres where it kind of gets tricky, even after perfectly replicating the encryption, our
verification attempt still doesn't succeed, so they must also be doing checks on the actual
payload.
after some trial and error, we narrowed the checked part to the prediction arrays, which are outputs, primaryOutputs and raws.
turns out, both outputs and primaryOutputs are generated from raws. basically, the raw
numbers are mapped to age outputs, and then the outliers get removed with z-score (once for primaryOutputs and twice for outputs).
there is also some other differences:
xScaledShiftAmt and yScaledShiftAmt in predictions are not random but
rather can be one of two valuesafter the initial release, k-id's provider for face scans, privately added a patch to this
script. however, the patch wasn't sufficient enough and we bypassed it. (so the script works again!)
the patch was the fact they started checking recordedOpennessStreak, recordedSpeeds, failedOpennessReadings, failedOpennessSpeeds and failedOpennessIntervals to be valid by checking the
values referencing eachother server-side.
with all of that done, we can officially verify our age as an adult. all of this
code is open source and available on github, so you can actually see how we do this exactly.