Picking the low hanging passwords by David Gilbertson

According to a not-at-all recent report by Keeper, there’s a 50/50 chance that any user account can be accessed with one of the 25 most common passwords.

And there’s a 17% chance that the password is 123456.

This strikes me as absolute rubbish, but it got me thinking, if I want to get unfettered access to some user accounts, and I don’t really care which accounts, rather than using ‘brute force’ by trying many passwords for one user account, it makes much more sense to flip that and try one password on many user accounts.

If Keeper are right (and not misinterpreting the data which I’m totally not accusing them of doing), then I could try the password “123456” on a random selection of accounts and for 1 in 5 attempts I’d be in like Flynn.

So I tried exactly this on Reddit, copy/pasting usernames into the sign in form, leaving the password as 123456 and clicking login. Over and over again.

Of the 30 user names I tried, this password worked for 0 of them. A strike rate of roughly 0%.

So, manually copy/pasting user names into the sign in form is a big fat waste of time.

I should give up.

Or scale up.

const signIn = async (username) => {
  let currentPasswordIndex = 0;

  const browser = await puppeteer.launch();

  const page = await browser.newPage();
  await page.goto('https://www.reddit.com/login');

  // Runs once for each username/password combo
  const tryPassword = async () => {
    const password = PASSWORDS[currentPasswordIndex];

    await page.type('#user_login', username);
    await page.type('#passwd_login', password);
    await page.click('#login-form button[type=submit]');
  };

  page.on('requestfinished', async request => {
    const thisPassword = PASSWORDS[currentPasswordIndex];

    if (request.url().includes('/api/login/')) {
      const response = await request.response();
      const responseData = await response.json();

      if (isWrongPassword(responseData)) {
        console.log(`✘  ${username}/${thisPassword}`);

        // try the next password
        currentPasswordIndex += 1;
        await tryPassword();
      } else if (isRateLimited(responseData)) {
        // wait a bit
        await page.waitFor(getRateLimit(responseData));

        // then try the same password again
        await tryPassword();
      }
    }
  });

  await tryPassword();

  await page.waitForNavigation({ timeout : 7000 })
    .then(() => {
      // If the page navigates, it means the sign in was a success
      console.log(`✓  ${username}/${PASSWORDS[currentPasswordIndex]}`);
    })
    .catch(() => {
      // If waitForNavigation times out (wrong password) it throws
      // But I don't care because I've already logged the wrong passwords
    });

  await browser.close();
};

My little NodeJS server of horrors

This function will open the Reddit sign in page (using Puppeteer) and try signing in with a variety of passwords.

I could just call this function with a bunch of usernames and look at the output to see the user name/password combos it tried and which it got right…

Fun fact: 14% of Reddit user names are dirty

…but that involves more faffing about than I’m willing to endure.

So, I wrote a Chrome extension (no you can’t have it) that picks up all the user names on a page and sends them to my server which runs the script above.

When the script finds a password for a user, it sends it back to the browser and the extension adds a little tag next to the user’s name like so:

You brought this upon yourself, PhaserArray

(I also email myself any successes, because sometimes I’ll need to queue up the guessing for later — when I hit a rate limit, Reddit is super helpful and tells me exactly how many seconds I need to wait until I can start guessing again.).


I must admit, the first time I saw a user’s password hovering just to the right of their name, it put a little evil smile just below my nose. I immediately logged in as the user and had a bit of a poke around in their profile page. I saw the reset password button, the checkbox to log them out everywhere else…

…but as fast as it had come, my excitement faded.

Like sharing a vegan platter for two, I had no beef with this person. They were an ordinary, harmless internet citizen, they didn’t deserve to be a target.

So I closed the tab, shut down my server and forgot about the whole endeavour.

No, wait, I’m a bad guy — I almost forgot!

So, I attempted to go one level deeper. I took note of the email that they had listed in their account page and tried logging into it with the same password.

And…

Dammit, they’d used a different password for their email account. Like a flat-earther who accepts that climate change is happening, they were dumb, but not that dumb.

Luckily there is no shortage of people ignoring all good password advice; in almost every comment thread there were one or two accounts proudly displaying their passwords right next to their user names. All courtesy of some code that took, like, four hours to write.

I soon extended beyond Reddit to other sites (where usernames are visible) with varying levels of success. (For some reason, forums about trains are virtually impenetrable, while people on bird-watching forums are totes clueless. Maybe they’re too busy thinking about blue footed boobies and crested throat warblers to be crafting hard-to-guess passwords.)


If it’s not obvious, I should point out that I’m not interested in the user accounts of ornithologists per se. I’m interested in finding an entry point into the online world of individuals who are bad with passwords.

It’s like the classic Nigerian email scams. There aren’t many people left who will fall for it, but when you find someone who will, they’re ripe for the picking. And finding them is cheap — it’s a good recipe.

Of all the accounts with simple passwords, a small but healthy share listed an email address in the profile page that could be accessed with the same password. And from there, it’s not hard to reset other passwords and eventually get into the target’s bank account, raising transfer limits (answering ‘proof of identity’ questions is easy when you’ve got every email a person’s ever sent) and shuffling their money off to somewhere it will be more useful to me.

You know, it’s true what they say: if you do what you love you’ll never work a day in your life.


My little operation has outgrown the browser extension now and scaled up to trawl sites for masses of user names to test against those most common of passwords. My single server has grown to a reverso-brute-forcing farm with constantly rotating IP addresses churning away day and night. (Yes, even in the dark!)

I’ve automated finding an email address on the account page of various sites and trying to log into that, so I only need to get involved when I’ve got the keys to the kingdom of someone that apparently thought no harm would come from having a password like 123456, on multiple accounts.

I almost feel bad for them.

Back to reality

I think there will always be end users who create the simplest password they’re allowed to. So the onus is on us (developers, security folk, etc.) to ensure that insecure passwords simply aren’t possible.

I guess this whole (fictional) story is a preamble to a plea to the few people who are still doing security wrong.

Every site (yes you, Reddit) should be enforcing password strength. And if you ask me, every site that has allowed crap passwords in the past should be working on forcing these to be updated.

And please stop spreading the misinformation that a password must contain uppercase/lowercase letters, numbers and punctuation to be secure.

If you’re telling a user that their 26-character passphrase isn’t secure enough (ahem, Microsoft), then you’re making it harder for that user to create an easy-to-remember/hard-to-crack password.

And if you allow truly terrible passwords like [email protected] because your strength checking logic is blunt, you’re doing your users a double-disservice (ahem, Microsoft).

I’d recommend testing the strength of a password with something clever, like zxcvbn — a “password strength estimator inspired by password crackers” by Dropbox. I first heard of zxcvbn 4 minutes ago and have been a big fan ever since. (Have a play here, it’s fascinating.)

If you really want to help your less savvy users pick a secure password, inform them of the correct horse battery stapler concept on your sign up page (5f7ty^GF$H`@2 is difficult to crack, but this is difficult to crack is thousands of times harder).

One of these days, we’re going to see a user in the Litigious States of America successfully sue an organisation for allowing them to have an easily-guessed password. The EU will make minimum password-strength requirements mandatory, and blog posts like this will become obsolete.


Hey, thanks for reading. I hope you have a great day today. Or if it’s late at night and today wasn’t so great, maybe try again tomorrow.

Bye!


Originally posted: https://hackernoon.com/picking-the-low-hanging-passwords-b64684fe2c7

February 11, 2019

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of
© HAKIN9 MEDIA SP. Z O.O. SP. K. 2013