Skip to content

2FA

2FA

Best Practices

HMAC-based One Time Password (HOTP)

  • Uses HMAC to get random data.
    • Uses the last element in the HMAC to set an offset to start reading X number of bytes from

Time-based One-time Password Algorithm (TOTP)

  • HTOP but with a timestamp that is rounded to some timestep (usually 30 seconds)

Example in Python:

#!/usr/bin/python3
import base64, hmac, sys, struct, time

def hotp(key, counter, digits=6, digest='sha1'):
	#Decode the key and add padding if too short
    key = base64.b32decode(key.upper() + '=' * ((8 - len(key)) % 8))
    print("Internal Key:", key)

    #Pack the integer in to a 64 bit integer
    counter = struct.pack('>Q', counter)
    print("Counter:", counter)

    #Use SHA1 HMAC to generate a new mac from the key and the counter
    mac = hmac.new(key, counter, digest).digest()
    print("MAC:", mac)

    #Use the last byte as a offset value
    #This offset value is used as a random starting value
    offset = mac[-1] & 0x0f

    #Get an 32bit integer value form the mac at the correct offset
    print("mac[{}]: {}".format(offset, mac[offset:offset+4]))
    
    #Get the positive part of the integer
    binary = struct.unpack('>L', mac[offset:offset+4])[0] & 0x7fffffff
    print("Binary data" , binary)

    #Take the lower n digits of the number and prepend zeros if needed
    return str(binary)[-digits:].rjust(digits, '0')

def totp(key, time_step=30, digits=6, digest='sha1'):
    return hotp(key, int(time.time() / time_step), digits, digest)

def main():
    #args = [int(x) if x.isdigit() else x for x in sys.argv[1:]]
    #for key in sys.stdin:
    print(totp("MZLXK2LULZ3H2MZYPJYWWS2LFBRXCKC3GBGHUMZDEVUUU4JQIFVQ"))

if __name__ == '__main__':
    main()

Exploits

  • Can you go directly to that page?
    • If you change the referrer Header does it work?
  • Can you reuse a token?
    • How long is the token accepted?
    • If there is a limit specified and not used is it removed after that time?
  • Can you use a token from another account?
  • Can that token be viewed from a response from the server?
  • Can a email verification link bypass the 2fa mandate
  • Can I login with a password reset without a 2fa code

Brute Force:
- Limit to number of accepted codes?
- Limit to how fast you can test codes?
- Generate many OTP codes and test
- If there is a backup token can you use it ore than once

:
- Can the 2FA be removed without a token
- Can you read the 2FA token from a XSS/CORS vuln
- Upon 2fa activation are previous sessions expired

  • Information disclosure of Cellphone