In my line of work, there is a lot of uses for a random sting of text. Things like:
You get the picture. Strings that you need to key once, or once per instance. In most cases, these are strings that after creation, you don't neccesarily need to know what they are, you just need to know how to change them. With this list of parameters, you'd think that folks would use random characters for these functions right - at least do the random keyboard walk for it? In my experience, this is almost NEVER the case. People try spell things - "l3tm31n", D0ntg0th3r3" and the like. They'll use their Company name, or the street address of their organization, or some other "meaningful" string. And after using "leet-speak" passwords, they then carefully record the password and save it to a text file, usually on the server that's using the password. As a pentester, this is a win for me, I don't even need to crack the password, you just gave it away! As a system administrator, this horrifies me! So, what to do? In the past, I've used an excel spreadsheet to generate a random string of "n" characters, selected from a set of characters that do not include the "confusing" ones (Oo01lIiL and so on). The "randomness" was defined by how long I felt like leaning on the F9 key that day. After creating the string, I would then try to get my client to NOT write down the string - this almost never works, but it's worth a try. For today's story, I decided to improve on this a bit, and re-coded it in python. This was a 5 minute script (as most of mine are), so if you see a way to improve or neaten this up in any way, please - don't be shy - use our comment form. ========================================= psk.py =========================================
from random import randint ========================================================================================== Running this as "python psk 15" will create a 15 character pseudo-random string:
C:\> python psk.py 15 You can change the values that are permitted to be in the string (to exclude lower case values, or to add special characters) by adding or removing characters in the "chars" string. Changing the length of the string is as simple as changing the value in the command line option:
C:> python psk.py 32 And please, in most cases there is NO reason to write down this password. Your "windows service password for whichever service" for instance should be changed periodically, but in most cases there is no reason that you should know what it is, you just need to be able to change it. Also, if you use this to create a random pre-shared-key for your ste-to-site VPN, emailing it in cleartext is what we call "a bad idea". Not only is it open for theft as it transits the internet (and both internal networks), it's also stored (likely forever) in your sent mail and in the recipients inbox, and likely in the Exchange Server message store - the whole cleartext data at rest / cleartext data in transit concept should ring a bell, especially if you've been audited for PCI lately. As always, in these days when brute-forcing is simple, quick and cheap, bigger is in fact better. For pre-shared keys or "write only" passwords, I generally start at 32 characters and go up from there. Since you never need to re-key the thing, after it's generated you can cut/paste it and forget it. I hope that you find this simple bit of code useful. If you've got a simpler way of getting to the same results, or if you can improve on my quick-and-dirty python, please post to the comment field below!
=============== |
Rob VandenBrink 579 Posts ISC Handler Sep 23rd 2013 |
Thread locked Subscribe |
Sep 23rd 2013 8 years ago |
how about this one liner?
gpg --gen-random 1 21 | gpg --enarmor | sed -n 5p |
Nerijus 7 Posts |
Quote |
Sep 23rd 2013 8 years ago |
For the powershell folks
Function Get-NewPassword([int]$lengthOfPassword=30,[int]$numberOfNonAlphanumericCharacters=7){ [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null [System.Web.Security.Membership]::GeneratePassword($lengthOfPassword,$numberOfNonAlphanumericCharacters) } |
Nerijus 2 Posts |
Quote |
Sep 23rd 2013 8 years ago |
Awesome one liners (or close to it)! And perfect if (as suggested), the phrase is a cut/paste/forget it forever process
However, if you've ever had to re-key one of these off of a printed copy, copy it off of the screen or even worse, include it in documentation (I know, a REALLY bad idea, but it happens), you'll want to avoid zero's, the letter "O", the number 1 and the letters "I" and "l". I find that a list of permitted characters does the trick for me |
Rob VandenBrink 579 Posts ISC Handler |
Quote |
Sep 23rd 2013 8 years ago |
There is a super handy little *nix utility called apg (Automated Password Generator) that makes generating nasty strings of gibberish easy and conformant with any password complexity policy. I use it for personal passwords and root accounts. There are options for entropy or seed input, ensuring passwords are not in a local password dictionary, crypt output, using inline in scripts, etc, etc. Here are a couple usage examples:
to generate a nasty 32 character root password: apg -a 1 -m 32 /?@q@a;K"_9z46tezcPAF}~Y)QZ0FeD@ 7>?UhMB{,bp4rdh%,bHh7l8`V6@+e4k9 bNc^1C?"v*`g6I504]hgU#aop%G|66%Z (FF^%PnD3h\.2HQ{uJb>k/&N,&&j&QnH i@Cw![19oX7t~4;;2g>>SgF(uG_il_dl _5IJ9`Mg2(uaWUux_YHDK{M\*[K]02Uu to generate a user pronounceable password that meets a typical password complexity policy: apg -m 8 -t -M SNCL Mit)Huoth3 (Mit-RIGHT_PARENTHESIS-Hu-oth-THREE) Gock?Oz1 (Gock-QUESTION_MARK-Oz-ONE) Hilt]owIc6 (Hilt-RIGHT_BRACKET-ow-Ic-SIX) Wowt/onk6 (Wowt-SLASH-onk-SIX) Qualk4On< (Qualk-FOUR-On-LESS_THAN) Nerd4twit; (Nerd-FOUR-twit-SEMICOLON) |
Rob VandenBrink 2 Posts |
Quote |
Sep 23rd 2013 8 years ago |
Great little 5 minute script! Only suggestion is to add a sys.exti() after verifying the syntax to avoid index error message(s).
|
Rob VandenBrink 1 Posts |
Quote |
Sep 23rd 2013 8 years ago |
>> chars = "abcedfghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789"
AY-BE-SEA-E-deeeeee-F ? I have heard of "I before E except after C", but "lower-E before lower-D" ? Is this an intentional part of your implementation of the algorithm? Anyway, if you are omitting '1/I/l' and '0/O', then you should omit '5/S' and 'B/8' and 'C/Q/O', so that your over-50-years-pointy-haired-boss with less-than-optimal eyesight and needing-to-be-updated prescription-lenses and a funky on-screen font won't call you at home in the middle of the night, after getting locked-out for mis-entering a password "too many" times. Or, maybe it's my fault, for trying to read too-many 25-character Microsoft product-keys when helping friends do a re-install of "best-practises-nuked-after-being-compromised" copy of Windows. Was the 17th-of-25 character a Q? an O? a C? a B? an 8? Arrgghh! |
Anonymous |
Quote |
Sep 23rd 2013 8 years ago |
Unless you're careful, you could end up with much less entropy in your 'random' string than bits in the key you're creating. I dread to think how how cryptographically strong the PRNG of Microsoft Excel might be. If it's seeded by something like seconds since the Epoch, and you know roughly when the password was generated, I bet it's breakable in fewer than 2^32 iterations of the algorithm by trying different seed values and iteration counts. For authenticating with a network service though, that's probably okay, as you may not get that many login attempts.
|
Steven C. 171 Posts |
Quote |
Sep 23rd 2013 8 years ago |
for write once passwords I tend to use: https://www.grc.com/passwords.htm it generates a different random password every time, and the entropy should be high enough for most needs.
|
Raystorm 1 Posts |
Quote |
Sep 23rd 2013 8 years ago |
Thanks for catching that, I pasted the next-to-last version of the script in, the one that was missing the exit() command.
Fixed now! |
Rob VandenBrink 579 Posts ISC Handler |
Quote |
Sep 24th 2013 8 years ago |
The GRC site looks interesting and has some neat utilities. The problem I have with using websites for keys and passwords is the same problem as using websites and cloud services to crack passwords - when you create the password (or crack a password), the website has your public ip address, likely your private ip address and the password you just generated or cracked. Best case, everything is above board and written correctly, and this is a transient condition. Worst case, the whole shot goes into the website log either by accident or intention.
Absolutely nothing against this site in particular - it's the concept that I have personal doubt trepidation with. |
Rob VandenBrink 579 Posts ISC Handler |
Quote |
Sep 24th 2013 8 years ago |
my personal favorite: head -c12 /dev/random | base64
base64 uses of course a somewhat limited character set, but it isn't bad and the passwords don't include any special characters that may cause problems depending on the context. |
Johannes 4511 Posts ISC Handler |
Quote |
Sep 24th 2013 8 years ago |
Quoting Johannes:my personal favorite: head -c12 /dev/random | base64 I do something very similar: openssl rand -base64 32 | cut -c1-32 Regarding Python, I have a similar script doing exactly the same thing: # Quick function to generate a random pwd of a given size def gen_rand_pwd(size=32, charset=string.ascii_letters + string.digits): return ''.join(random.choice(charset) for x in range(size)) If the server side supports whitespaces and punctuation (in my experience this is pretty rare...), change charset to string.printable. For punctuation only, use string.punctuation. You get the idea. I definitely share the pain here. I hate "cool" leet passwords. |
Johannes 1 Posts |
Quote |
Sep 24th 2013 8 years ago |
Why not a password database, along with password generator? I'm sure any popular password database will do. Keepass/KeepassX, LastPass, 1Password - all have good (1,2,3,x time) password generators as far as I know.
As stated by Stephen C, the problem with many of these do-it-yourself solutions is that they suffer from weak entropy. A good password generator will use system entropy if it's sufficient or collect entropy itself. For strong passwords (phrases) you need to remember, I wrote a python script base on diceware: https://github.com/chrishiestand/phrasenoia |
Chris 12 Posts |
Quote |
Sep 24th 2013 8 years ago |
How about this idea for increasing entropy in the original script. Take the string of permitted characters and jumble it up a bit to make that string more randomized. That way, even if the index for rndint is known, the character set is not predictable. You could even repeat the set a number of times in different orders too, such as follows:
TM6vf8iEWhkg3ICDxRqOpU1LGF5t2HarKoBJ7NPQZy4mejbcdAwzlnuX9VY and (CRLF added for ease of viewing) cEgnqQAp6LD35d9CjR4rH7abyKfeJBNWY2mukhTlZxwV18IvFPOiMXGzU toLrF7IaUnCXERPyufKgW3T2bDJmkqicOoz1N85hjvBwpY4ZHlt9VxQMde A6GTM6vf8iEWhkg3ICDxRqOpU1LGF5t2HarKoBJ7NPQZy4mejbcdAwzlnuX9VY |
Sean 4 Posts |
Quote |
Sep 24th 2013 8 years ago |
On Linux and MacOS; I wrote a C program to use /dev/random for this.
Leveraging PRNG and system timing as well; just in case of the off chance, that /dev/random isn't as random as it's supposed to be, for some reason. http://pastebin.com/nqnj0byn |
Mysid 146 Posts |
Quote |
Sep 24th 2013 8 years ago |
openssl rand -base64 32
on its own is even better. Personally, I have tools that I can set to relevant alphabets to generate keys from system entropy, including one that uses a case insensitive alphabet with o, L and a few others excluded. My current favorite is to use a local (not networked) password manager which can type the key for me without me or anyone else ever seeing it, then instantly deleting the new "password" from the database. |
Mysid 1 Posts |
Quote |
Oct 3rd 2013 8 years ago |
After reading http://xkcd.com/936/ - "we have trained everyone to use passwords that are hard for humans to remember yet easy for computers to guess" - I wrote a generator that uses English words - enough of them to get the entropy reasonable.
So for 49 bits of entropy, you can have "ones/aging/draw/alkali" instead of "cf R0Lt_zPq" Notthing like the 300-bit entropy of the GRC site, but rated "reasonable" instead of "overkill" - a huge step up from "12345" or "qazwsxewdc" http://andrew.triumf.ca/cgi-bin/mkpasswd2.pl (myself, I still write them down in an encrypted store rrather than try and remember them all, having taken the "no reuse" thing to heart) |
advaxtriumf.ca 7 Posts |
Quote |
Oct 8th 2013 8 years ago |
Sign Up for Free or Log In to start participating in the conversation!