#!/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 |
This comment has been minimized.
This comment has been minimized.
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 |
This comment has been minimized.
This comment has been minimized.
Hi, in Brew 0.9.5, |
This comment has been minimized.
This comment has been minimized.
bleistift2,
In that example, the secret was |
This comment has been minimized.
This comment has been minimized.
Hi, 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 |
This comment has been minimized.
This comment has been minimized.
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/ |
This comment has been minimized.
This comment has been minimized.
Vingelar, |
This comment has been minimized.
This comment has been minimized.
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 |
This comment has been minimized.
This comment has been minimized.
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. |
This comment has been minimized.
This comment has been minimized.
@lucianf - I discovered the AES key by tracing the crypto library calls that the VIP application makes. |
This comment has been minimized.
This comment has been minimized.
This is fantastic - thanks so much! I just wanted to share a version written in bash which runs a little faster than expect: You'll note that the programmatically generated keychain password is passed to the I hope you will find the bash script alternative helpful. Cheers! |
This comment has been minimized.
This comment has been minimized.
It would we very help full. if it can work for windows as well. |
This comment has been minimized.
This comment has been minimized.
Okay, so if you are trying to get this to work with 1password you need to get the key_plain into Base32… basically, I ran oathtool -v --totp $key_plain and it spit out the Base32 secret which I was able to paste in to 1password's TOTP field and it generates proper codes that stay in step with the VIP Access apps codes. BTW, I also had to constantly enter the keychain password the first time I ran this otherwise the keychain password was not getting passed. |
This comment has been minimized.
This comment has been minimized.
Can anyone provide the Powershell version for the listed scripts above in order to test on Win VM? Thank you |
This comment has been minimized.
This comment has been minimized.
Hello everyone, I could use this very much for the purpose of automating the VPN autentication and I can't still figure out how should I use this script. |
This comment has been minimized.
This comment has been minimized.
I only just now got around to looking at this. Nice. The reason I used expect is because this is actually a small piece of a larger automation task I've written which needs expect for some other steps anyway. Absent that, yes, bash is going to be faster/simpler for others to use. |
This comment has been minimized.
This comment has been minimized.
@hgocent, in order to automate VPN authentication, you will need a bit more than just this script. Here are the pieces, and some suggestions for how to address them:
Here is another post of mine describing how to set up VIP-Access/AnyConnect VPN from a Mac: https://gist.github.com/p120ph37/10999344 |
This comment has been minimized.
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.