I was recently thinking about how much entropy a single-shot password would need to be reasonably secure. I concluded 4 bytes of data is enough, and will explain my reasoning.
I should provide some context and define what a single-shot password is. Consider we are exploiting a vulnerability in a service on an open port, and can inject shellcode to be ran. All outgoing traffic from this machine is being blocked, or perhaps there are other reasons we don't want to send a reverse, outgoing shell. We instead want to bind a shell to a new port on the machine so that we can gain a foothold onto the machine and into the network.
We don't want anyone else who sees the open port to have unauthenticated access to our backdoor. Anyone attempting to connect gets one attempt at the password, and if they fail the listening port will close. Forever. We need to keep our shellcode minimal, so using a long passphrase is not going to fly when we inject our exploit.
I consider 4 bytes of data for a single-shot password in this instance to be "reasonably" secure. Of course "reasonably" is subjective, and I am sure there will be detractors to this statement and I would be interested in hearing their discourse. However, I will explain my own reasoning and back it with some simple mathematics.
Let me first say that a 4 byte password, in most contexts, is incredibly insecure. No matter what hashing mechanism or other protections are applied to it, it can probably be cracked within minutes or seconds. However, in a single-shot context, this type of attack on our password is not possible.
Now let's consider the 4-byte passwords that most people use daily. They're used from everything like bank account PIN numbers to "the last 4 digits of your social security number". Typically these passwords are strictly numerical, which does not provide much entropy at all. The set of 0 to 9 for each byte, 10 possibilities, combined 4 times.
So in fact, the amount of permutations for 4 bytes of numerical data is only
10 * 10 * 10 * 10 = 10,000. An attacker only needs 10,000 tries to enumerate every single possible combination of 4 digits.
For some reason, society still considers these 4 digit numerical PINs as "reasonably" secure, even when they're not single shot. In some cases PINs in an application (such as a bank website) can be vulnerable to guessing attacks, which means they can eventually and easily be cracked.
Now let me cite an example of a one-shot password, used by Google's two-factor authentication. When you log onto your GMail account, you have the option to have it send a 6-digit pin number to your cell phone, helping to ensure it's actually you logging onto the account. Well, six digits is
10 * 10 * 10 * 10 * 10 * 10 = 1,000,000. That's a one in a million shot, which Google has deemed reasonably secure.
Back to our bind shell. Our password is not limited to only numerical characters.
Consider the password
Z~r0. This contains 26 possibilities of lower case, 26 possibilities of uppercase, 10 possibilities of digits, and at
least 10 possibilities for symbols using a standard keyboard. Seventy-two possibilities per byte. So now our entropy is
72 * 72 * 72 * 72 = 26,873,856.
Someone trying to get into our one-shot shell would need to be pretty lucky, with odds of one in nearly
twenty seven million. A considerable leap over the 10,000 we use for PINs and the 1,000,000 Google uses.
We can even go a step further. We don't need to contain our password set to human-readable ones, we can use ASCII bytes that do not have a visible character. Any combination of bytes, including null bytes would work if we do a direct comparison of 32 bits. So, we open ourselves up to
256 * 256 * 256 * 256 = 4,294,967,296 possibilities. That's four billion with a B.
It's said winning the Powerball lottery is about 1 in 175 million odds (175,223,510). Any attacker would likely be better off trying to figure out a way to crack that than our single-shot bind port.