Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Tue, 7 Dec 2010 09:18:19 +0300
From: Solar Designer <>
Subject: pwgen in JavaScript


A Google search for pwgen finds not only the Unix and the Windows
program, but also a few others, including this "JavaScript port of
pwgen" (of Ted's pwgen for Unix):

The generated passwords are of the "pronounceable" type - similar to
Ted's pwgen, but not exactly the same.  For the randomness, the
JavaScript code uses Math.random().  This has three problems (beyond the
problem with the original pwgen's pronounceable passwords): the source
of entropy for Math.random() is likely just the system time or the like
(too small and predictable), the internal state of a PRNG like this is
generally too small for this purpose, and the PRNG is not
cryptographically secure in that one "random" number may leak info about
another one.

I just ran a quick and easy (but not the most optimal) attack on this
implementation.  I saved the web page along with its JavaScript files,
then edited pwgen-app.js to generate more passwords at once and to show
them one per line:

    for (var i = 0; i < 10000; i++) {
        results += (pwgen.generate() + '<br>');

In the resulting list of 10000 passwords (generated in my web browser),
there were 9062 8-character and 938 9-character ones.  I did not check
the code, but the latter appear to be generated when the first 8 chars
lack any digit; the 9th char is then always a digit.

For my quick and easy attack, I generated a .chr file from the 9062
8-character passwords.

I also generated 1000 passwords in a similar fashion (changing 10000 to
1000 in the code above).  Of those, 909 were 8-character.  I computed
NTLM hashes for them with a Perl script, and started a John attack using
the .chr file above.  Here's what I got:

$ ./john -i=pwgen-js -se=pwgen-js -fo=nt 1k-8-nt
Loaded 909 password hashes with no different salts (NT MD4 [128/128 X2 SSE2-16])
Warning: only 60 characters available

guesses: 22  time: 0:00:00:05  c/s: 9086M  trying: Ouq9s1f1 - Ouq9s1ie
guesses: 45  time: 0:00:00:12  c/s: 11528M  trying: Iu4a9p3i - Iu4a9p2i
guesses: 102  time: 0:00:01:00  c/s: 12779M  trying: iLi4jebi - iLi4j0lu
guesses: 148  time: 0:00:03:00  c/s: 11026M  trying: Ugc7yo3e - Ugc7yoj9
guesses: 193  time: 0:00:05:58  c/s: 11133M  trying: Py2ige1n - Py2igen6
guesses: 220  time: 0:00:08:34  c/s: 11324M  trying: Pgsu9h2h - Pgsu9h8f
guesses: 320  time: 0:00:40:37  c/s: 9891M  trying: aTt5xp8x - aTt5xtty

2.2% (2.4% of 909) cracked in 5 seconds
10% (11%) cracked in 1 minute
22% (24%) cracked in 8.5 minutes
32% (35%) cracked in 40 minutes

This is mostly _without_ exploiting the problems with Math.random()
yet.  It'd take custom code to exploit those, but then I'd expect all
passwords to fall within seconds.  "[List.External:Strip]" in the
default john.conf implements this sort of attack for another naive
password generator.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.