dlenski / python-vipaccess

A free software implementation of Symantec's VIP Access application and protocol
Apache License 2.0
827 stars 83 forks source link

Feature request - Provision with Activation Codes #63

Open uwuforever opened 1 year ago

uwuforever commented 1 year ago

The VIP Access desktop app provisions using an activation code, fetched from here:

https://vip.symantec.com/toolbar/activate.v

This returns a HTML page, where one of the lines is <input type="hidden" name="vip_access_toolbar_ac" id="vip_access_toolbar_ac" value="{base64 string here}" />.

The base64 string is decoded to a 16 character (A-Z0-9 all uppercase) 'activation code'. There's also no need to spoof an old device.

Example of a base64 string: l64L8lesoGPbLgYYnBYxMpBVO393evv1NpaRIOypiCA= and the activation code it decodes to: LEXIP16UAP3E7WUY.

When you use an activation code, the provision request looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<GetSharedSecret xmlns="http://www.verisign.com/2006/08/vipservice" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.verisign.com/2006/08/vipserviceuaservice.xsd" Id="**{MM/DD/YY HH:MM:SS COMPUTER_NAME}**" Version="2.0">
  <TokenModel>VSST</TokenModel>
  <ActivationCode>**LEXIP16UAP3E7WUY**</ActivationCode>
  <OtpAlgorithm type="HMAC-SHA1-TRUNC-6DIGITS"/>
  <ClockDrift>0</ClockDrift>
  <SharedSecretDeliveryMethod>HTTPS</SharedSecretDeliveryMethod>
  <SupportedEncryptionAlgorithm>PBE-AES128-CBC</SupportedEncryptionAlgorithm>
</GetSharedSecret>

It would be nice to have the provisioning requests look closer to real, up to date ones :)

dlenski commented 1 year ago

Yeah, this does look simpler overall…

The base64 string is decoded to a 16 character (A-Z0-9 all uppercase) 'activation code'. There's also no need to spoof an old device.

Example of a base64 string: l64L8lesoGPbLgYYnBYxMpBVO393evv1NpaRIOypiCA= and the activation code it decodes to: LEXIP16UAP3E7WUY.

Hmmm. How do you get from that base64 string to that activation code? If I decode your example, I get a random binary string? :thinking:

$ echo l64L8lesoGPbLgYYnBYxMpBVO393evv1NpaRIOypiCA= | base64 -d | hd
00000000  97 ae 0b f2 57 ac a0 63  db 2e 06 18 9c 16 31 32  |....W..c......12|
00000010  90 55 3b 7f 77 7a fb f5  36 96 91 20 ec a9 88 20  |.U;.wz..6.. ... |
00000020

My initial guess would that there is some layer of obfuscation or encryption in there, just like with the existing provisioning request format.

uwuforever commented 1 year ago

It’s encrypted and there’d be some reverse engineering involved to figure out the new key/derivation. However it’s not obfuscated nor does it have any real protection, so it is reasonably simple as far as reverse engineering jobs go.

I got the examples by running a MITM proxy. You can find the decrypt function in a disassembler by searching for the string “activate.v” in the main .exe file and setting breakpoints around it.

dlenski commented 1 year ago

Is there some benefit to using this new provisioning process? Is there some token type where the current one doesn't work?

I actually discovered a few weeks ago that we don't need to spoof (most of) the information about client software name and version. See https://github.com/dlenski/python-vipaccess/commits/less_spoof.

Basically I don't see a benefit of doing the RE work here, unless we think the current/old provisioning process no longer works in some way.

uwuforever commented 1 year ago

The benefits are longevity and reliability.

The old provisioning process will eventually be deprecated, hardcoded keys will change, and the tokens not created via an official app can be easily identified.

A token created with the new provisioning process would be completely indistinguishable from one created by the official app. It seems to involve a key derivation function rather than a hardcoded key, so should we figure out how it works, we are also no longer reliant on a deprecated key still working purely by luck.