The Internet of Broken Protocols: Showcase #4

(complete list of showcases:

Administrative note: I just posted the solution to showcase #1. Some readers are way smarter than me, and they've taught me a lot with their answers.

Now some of you would found this new showcase really lame, but it's pretty much what I found in the wild (with some minor changes to simplify the protocol). So beautiful, that's my first thought. I guess some people love collecting stamps and I love collecting terrible protocols ;=)

Updated: solution posted, sorry for the delay!


This is an one time password (OTP) protocol. It gives users an OTP that they can use to authenticate against a server. Your task again is to identify any weaknesses. You can leave your findings in a comment or email me at I'll update the post with my solution in a few days (I have reason for the delay).

Let Alice denote the user and Bob the server. Bob has Alice's email address. All direct communications between Alice and Bob are done over an insecure channel.

The protocol consists of two parts: provisioning and OTP generation.

# Provisioning

1/ Alice sends her email address

2/ Bob checks that is an existing user, generates a short code N, associates it with Alice's account, and sends it to Alice's email address. Let's assume that this email channel uses TLS and is safe against active attackers.

3/ Bob then generates a random 128-bit string K, associates it with Alice's account, and sends R = E(key=SHA-256(N), data=K), where E is AES/CBC/PKCS5Padding. This reply and all further communications come over the insecure channel.

4/ Alice checks her email for N, decrypts R to obtain K, then sends || E(key=K, data=N).

5/ Bob looks up K and N in Alice's account, uses K to decrypt Alice's response, and checks whether two N values match. If so, Bob generates a random 128-bit random secret S, associates it with Alice's account, and sends E(key=K, data=S).

6/ Alice uses K to decrypt S.

At this point the provisioning is considered successful, S is the shared secret from which all OTPs would be generated.

# OTP generation

This part just uses the TOTP protocol (


Andrew L. somehow missed this challenge, but I got nice emails from Thắng N., Carl M and Alex B. quangntenemy (I read the nickname as Kẻ Thù Nguyễn Tử Quảng, nice!) pointed out in the comment below that it doesn't make sense to use email as the second factor, but I think that's fine. Using email is not very different from using an installed app like Google Authenticator.

Carl. wrote,

"Assumption: 'short code' means a 6 digit number as typically found in OTP/2FA protocols.

In the provisioning protocol, since R (encrypted key K) is sent in the clear all one needs to do is brute-force the short code N for all values of N and perform decryptions using the hash of each guessed value of N as the key to find a set of candidate keys K{}. The candidate keys are checked for accuracy by finding a valid 128-bit key with proper pkcs5 padding and not a 256-bit random value.

Once K is found S may be gained by decrypting the value sent from Bob and OTP tokens then generated at will"

This is basically one of the problems I found in a OTP protocol developed by the one of the bigger banks in Vietnam. In their protocol they use SMS instead of email and ZeroBytePadding instead of PKCS5Padding, so I couldn't determine if the bug was actually exploitable.

Nobody pointed out that the protocol doesn't provide forward secrecy, but Thắng N. discovered an issue that I wasn't aware of when I wrote up this challenge. He wrote,

"if in step 5 Bob extract Alice's mail from message of step 4(not obtain it from sender
field in the email) to look up K and N values, attacker can mount such an attack:
        1. In step 4, he replaces the original message with attacker@gmail || E(key=K_a,
Values of K_a and N_a can obtain from normal procedure between him and Bob.
        2. In step 5, Bob send back to Alice message: E(key=K_a, data=S), attacker replaces
it with E(key=K, data=N), it exactly is tail part of message Alice try to send in step 4.
Attacker decrypts message to get S value.
Alice decrypts normally to get N value and assume it is shared value S. Now, attacker has a
control of private value  of each party and everything goes on later."

Neat reflection attack, isn't it?


quangntenemy said…
This is totally wrong. OTP is supposed to be the 2nd factor (what-you-have) in authentication, it cannot be built on top of email (what-you-know factor).