Last active
January 29, 2024 15:30
-
-
Save djsmith42/aa407f91a82a9b86cb4e5550c0b90e3b to your computer and use it in GitHub Desktop.
ObservePoint Pre-audit action for TOTP tokens for MFA/2FA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const TOTP_KEY = 'Pate your TOTP key here. Example: 5ep5abbzomzpen2fpti6hhyu5i' | |
const CSS_SELECTOR = 'Paste your CSS selector here for the TOTP token input. Example: #totp_token' | |
// ---------------------------------------------------------------------------- | |
// Do not change code below this line | |
// ---------------------------------------------------------------------------- | |
totp(TOTP_KEY).then(token => { | |
const element = document.querySelector(CSS_SELECTOR) | |
if (element) { | |
console.log('Entering TOTP token', token, 'into element') | |
element.value = token | |
} else { | |
throw new Error('Could not find element with CSS selector: ' + CSS_SELECTOR) | |
} | |
}) | |
async function totp(key, secs = 30, digits = 6){ | |
return hotp(unbase32(key), pack64bu(Date.now() / 1000 / secs), digits); | |
} | |
async function hotp(key, counter, digits){ | |
if(!window.crypto) throw Error('The web crypto API is not available'); | |
let y = window.crypto.subtle; | |
if(!y) throw Error('The wep crypto API crypto.subtle object is not available'); | |
let k = await y.importKey('raw', key, {name: 'HMAC', hash: 'SHA-1'}, false, ['sign']); | |
return hotp_truncate(await y.sign('HMAC', k, counter), digits); | |
} | |
function hotp_truncate(buf, digits){ | |
let a = new Uint8Array(buf), i = a[19] & 0xf; | |
return fmt(10, digits, ((a[i]&0x7f)<<24 | a[i+1]<<16 | a[i+2]<<8 | a[i+3]) % 10**digits); | |
} | |
function fmt(base, width, num){ | |
return num.toString(base).padStart(width, '0') | |
} | |
function unbase32(s){ | |
let t = (s.toLowerCase().match(/\S/g)||[]).map(c => { | |
let i = 'abcdefghijklmnopqrstuvwxyz234567'.indexOf(c); | |
if(i < 0) throw Error(`bad char '${c}' in key`); | |
return fmt(2, 5, i); | |
}).join(''); | |
if(t.length < 8) throw Error('key too short'); | |
return new Uint8Array(t.match(/.{8}/g).map(d => parseInt(d, 2))); | |
} | |
function pack64bu(v){ | |
let b = new ArrayBuffer(8), d = new DataView(b); | |
d.setUint32(0, v / 2**32); | |
d.setUint32(4, v); | |
return b; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment