Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Command-line implementation of Symantec's "VIP Access" token application on OSX. This will read from the same secret key and produce the same time-based one-time-passwords as the GUI application, but with output that can be captured and used in scripts. This can be useful for things like automating two-factor AnyConnect VPN logins through openco…
#!/usr/bin/expect -f
#
# VIPAccess.exp
#
# Command-line emulation of Symantec's VIP Access software token.
# Usage:
# ./VIPAccess.exp [v]
# If the "v" argument (or any argument) is specified, verbose output
# will be produced on stderr. The OTP value will be output on stdout.
#
set timeout 10
log_user 0
set aes_key D0D0D0E0D0D0DFDFDF2C34323937D7AE
set keychain /Users/$env(USER)/Library/Keychains/VIPAccess.keychain
proc vlog { s } { if $::argc { puts stderr $s } }
vlog "Finding machine serial number (used by VIPAccess to secure the keychain.):"
spawn /bin/sh -c "ioreg -rac IOPlatformExpertDevice | xpath 'plist/array/dict/key\[.=\"IOPlatformSerialNumber\"\]/following-sibling::*\[position()=1\]/text()' 2>/dev/null"
expect eof
set serial $expect_out(buffer)
vlog " $serial"
vlog "Reading encrypted Credential ID and OTP secret key from $keychain:"
spawn security unlock-keychain $keychain
expect "password to unlock $keychain: "
send "${serial}SymantecVIPAccess$env(USER)\n"
expect eof
spawn security find-generic-password -gl CredentialStore $keychain
expect -re \"acct\"<blob>=\"\(\[a-zA-Z0-9/+\]+=\)\"
set id_crypt $expect_out(1,string)
vlog " $id_crypt"
expect -re password:\ \"\(\[a-zA-Z0-9/+\]+=\)\"
set key_crypt $expect_out(1,string)
vlog " $key_crypt"
vlog "Decrypting Credential ID and OTP key:"
spawn /bin/sh -c "openssl enc -aes-128-cbc -d -K $aes_key -iv 0 -a <<< '$id_crypt'"
expect -re \(.*\)Symantec
set id_plain $expect_out(1,string)
vlog " $id_plain"
spawn /bin/sh -c "openssl enc -aes-128-cbc -d -K $aes_key -iv 0 -a <<< '$key_crypt' | xxd -p"
expect -re \[0-9a-f\]+
set key_plain $expect_out(0,string)
vlog " $key_plain"
vlog "Generating current OTP using secret key."
spawn oathtool --totp $key_plain
expect -re \\d+
set otp $expect_out(0,string)
puts $otp
Owner

p120ph37 commented Jan 2, 2014

Getting the serial number via ioreg is what occupies most of the execution time for this script. If you don't mind saving your OTP secret key directly into your automation scripts, you can run this once in verbose mode to obtain the secret key, and then just use "oathtool --totp YOUR_KEY_HERE" directly to output your one-time-passwords.

Hi,

my question may seem a little dumb, sorry for that. I just stumbled across github for the first time and am not very familiar with it.

Since VIP Access generates a new ID every time I re-install it I'd like to use a different OATH Generator I can backup and use on all my devices.

Could I use your code to extract the secret from my local VIP Access installation to use it in any other OATH compatible generator?

If so how do I do it? Could I just enter your code in terminal (in verbose mode) to get the secret or do I have to install git for mac?

Thanks!

Regards, Denis

bamos commented Jun 26, 2014

Hi, in Brew 0.9.5, oathtool is available from oath-toolkit.

Owner

p120ph37 commented Nov 17, 2014

bleistift2,
Yes, you can use this script to extract the secret from the VIP Access on Mac (so you can save and reuse the same secret with any oath-compatable tool). Just click the "Download Gist" link, then use chmod 755 VIPAccess.exp in a terminal to mark it as executable, and ./VIPAccess.exp v to run it. (the "v" puts it in verbose mode, so you can see all the intermediate steps including the secret, instead of just the final output code). The output should look something like this:

aarons-mbp:Downloads anm$ chmod 755 VIPAccess.exp
aarons-mbp:Downloads anm$ ./VIPAccess.exp v
Finding machine serial number (used by VIPAccess to secure the keychain.):
    C02LNGDLFD57
Reading encrypted Credential ID and OTP secret key from /Users/anm/Library/Keychains/VIPAccess.keychain:
    OagYZjwfC1pFQrcF+xmoqoYFEzLnB71bIgjgU+ZxqQY=
    279r5n5VSVxwCJHuC9CXD7+/o+P3bBHdo3zguGbXIRs=
Decrypting Credential ID and OTP key:
    VSST29219676
    c3066e7467cbd399dbdfade86981f6d212c5d0b2
Generating current OTP using secret key.
723872
aarons-mbp:Downloads anm$

In that example, the secret was c3066e7467cbd399dbdfade86981f6d212c5d0b2

Hi,
great work.
Id had to re-install my smart phone and therefore also my VIP Access App. Before I noted down my Credential ID (VSMT...).
Do You know what is the relation between the Credential ID and the OTP Key (secret) ?
So: how can I recover my secret from the CredID I noted down before ?

I am pretty sure there must be a connection because when registering the App to a Website I just had to put in the CredID

Owner

p120ph37 commented Nov 19, 2014

I just discovered that @cyrozap has taken this a step further with a python implementation of the token-provisioning protocol: https://github.com/cyrozap/python-vipaccess and a blog post about writing it here: http://www.cyrozap.com/2014/09/29/reversing-the-symantec-vip-access-provisioning-protocol/

Owner

p120ph37 commented Nov 19, 2014

Vingelar,
The website where you enter your OTP codes doesn't know the secret - they simply pass along the OTP to Symantec, along with the Credential ID they have on file for you, and Symantec gives a good/no-good response.
Unfortunately, only Symantec and your now-deleted phone app knew the relation between the Credential ID and the OTP Key. The short answer is that you cannot recover the OTP Key from the Credential ID, and although Symantec has this information on their side, they will not release it to you. You will have to create a new credential and register it with the website.

echiu64 commented Jun 12, 2015

The cyrozap implementation is good, but generates a QR code and you need to manually run oathtool to get your 6 digit code. This works better out of the box imo. Especially if you are looking to automate anything or just want to copy/paste the code

lucianf commented Oct 1, 2015

Hi @p120ph37. I'm trying to reverse engineer the VIP iOS app and replace it with Authy/1password. Can you comment on how you obtained the AES key? I'm trying to take a similar approach for the iOS app and even though I have the keychain data it (rightfully) seems encrypted with a different key. You key seems to be unique for all installations of the Mac app (since your code works on any computer) so I'd hope that the same applied to the iOS app, I'm just looking for an (easy) way of getting the key to be able to move from there.

Owner

p120ph37 commented Jan 23, 2016

@lucianf - I discovered the AES key by tracing the crypto library calls that the VIP application makes.

ykhemani commented Jan 7, 2017

This is fantastic - thanks so much!

I just wanted to share a version written in bash which runs a little faster than expect:
https://github.com/ykhemani/vipaccess

You'll note that the programmatically generated keychain password is passed to the security unlock-keychain command via the -p command line argument. I wasn't sure about this, but given that the password is based on the machine serial number, a string and the user's name, this should not be cause for consternation.

I hope you will find the bash script alternative helpful.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment