Go Ahead and Write Down Your Passwords

Tuesday, August 07, 2012

Boris Sverdlik

7c5c876d1933023ac375eead04302e1a

Another day, another password hack and yet another reason not to reuse passwords... 

Here is a simple bash script to generate strong passwords.

1) Install TrueCrypt http://www.truecrypt.org/

2) Create a hidden volume. Pick a strong passphrase you will not write down and use a keyfile

3) Mount the volume

4) Run the Script

I'll port it to Python this weekend, or maybe even something more platform independent. Also, don't forget to set Auto Dismount to 15 minutes, so you don't leave it up and running.

[code]

#!/bin/bash
#
#
# For Resiliency I keep the volume in multiple places, but for ease of use
# of use, I suggest keeping it on Dropbox. Set TrueCrypt to unmount after
# 30 minutes of idle.

echo "Hello, "$USER". This will generate your password. Please make sure you have mounted your TrueCrypt volume with your password file"

echo -n "Please enter the path to your encrypted vault file [ENTER]: "
read vaultfile

echo -n "Please enter the patch to your encrypted mount, this will be used for temp files [ENTER]: "
read encmounts

echo -n "Enter the website or application that this password is for and press [ENTER]: "
read site

grep -i $site $vaultfile

if [ $? == 0 ]; then

echo -n "Do you want to create a new password for this existing account? (yes or no): "
read update

if [ "$update" == "yes" ]; then

echo -n "Enter the user ID you will be using and press [ENTER]: "
read name

echo -n "Enter maximum password length characters can the password be [ENTER]: "
read counts
sed "/$site/d" $vaultfile > $encmounts/tmp ; mv $encmounts/tmp $vaultfile

curl -s http://www.bing.com/news?q=$color > $encmounts/temp

newpass=`md5 $encmounts/temp | awk '{print $4}' | openssl sha | cut -c 1-$counts|sed -e 's/[a-z]/A/' -e 's/[0-9]/#/'`
echo $name $newpass $site >> $vaultfile
# rm $encmounts/tmp
exit 1
elif [ "$update" == "no" ]; then

echo "Goodbye"
fi
fi

echo -n "Enter the user ID you will be using and press [ENTER]: "
read name

echo -n "Enter maximum password length characters can the password be [ENTER]: "
read counts

curl -s http://www.bing.com/news?q=$color > $encmounts/tmp

newpass=`md5 $encmounts/tmp | awk '{print $4}' | openssl sha | cut -c 1-$counts |sed -e 's/[a-z]/A/' -e 's/[0-9]/#/'`
echo $name $newpass $site >> $vaultfile

rm $encmounts/tmp

echo "Goodbye"

[/code]

Possibly Related Articles:
15254
Network Access Control
Information Security
Passwords Authentication Access Control Script TrueCrypt Tutorial Passphrases
Post Rating I Like this!
Default-avatar
Jakob Lell I've taken a quick look at your code and I've found some serious flaws:

1. The command "echo something|openssl sha" gives the output "(stdin)= 528167eed45c3a5a66dfaa5702e059d18a969b02". The cut command will then take the first $count characters from it and so it will get something starting with "(stdin)= ", which is totally predictable. Depending on the choosen password length there may be insufficient randomness because the first 9 characters are totally predictable.

2. The next problem is that the only source of randomness is the bing search (with the uninitialized variable $color as search term). The javascript of the bing site does contain some random-looking constants, which differ between multiple queries. However, I wouldn't trust it to be a cryptographically secure source of randomness just because it isn't designed to be secure. And even if this constants are actually generated in an unpredictable way at the moment, Microsoft may still remove this in the next site redesign or employ a cache for frequent searches.

3. The bing search which provides the randomness is queried via an unencrypted http connection so an attacker may be able to sniff the source of randomness used for the password generation and thus calculate the generated passwords.

4. The generated passwords only contain 4 bits of entropy per digit because they are generated from a hexadecimal hash. Replacing the first letter with an "A" and the first digit with a "#" may help to fulfil some password policies but it even further reduces the entropy and doesn't improve the security of the generated passwords in any way.
1344418952
B437b37fb61c142466b5c3533a14f692
Andrew Newey Sounds like a lot of effot mate, but each to their own.
1344481143
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik @jakob while I agree that the replacement is weak, I actually have a for loop (which I didn't include) that randomizes the caps and special characters...

How do you figure the first 9 characters are predictable? You grab the search then run 2 hash functions against it. Totally unique...

You could go SSL, but then the attacker would still need to know what hash functions you are using, so again invalid point. You can replace the bing search with whatever.. The Twitter API is a good option, but I didn't want to include my OATH token in the code. :)
1344559014
Default-avatar
Jakob Lell The problem with the first 9 characters is that the command "openssl sha" outputs the filename before the actual hash. When hashing standard input, the output starts with "(stdin)= " and your code doesn't remove this static information. Just try out the following command in a shell:

counts=10;echo abc |openssl sha | cut -c 1-$counts|sed -e 's/[a-z]/A/' -e 's/[0-9]/#/'

This will generate the password "(Atdin)= #". The "s" from "stdin" has ben replaced by an "A" and the first digit of the actual hash has been replaced by "#".


I'd also strongly recommend to use a local source of randomness such as /dev/urandom. This is typically quiet secure and it can't be sniffed on the network. You can of course combine multiple sources of randomness by hashing them together.

The security also shouldn't depend on the attacker not knowing the code. You've published the code and so it's not hard to guess which hash algorithms you are using. Normal users aren't able to program their own password manager so they have to use an existing one, which can be analyzed by an attacker as well.
1344583691
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik Sorry... I'm lost as to what you are trying to say..

First your password file is encrypted, second the whole point of this stupid script is so users can use different passwords for different sites and not worry about remembering them.


Now, I'm still lost as to what you are trying to say about (stdin) considering no where in the code is it used to calculate the password outside of $color variable.

Yes echo filename would be the same, but i'm not echoing the filename..

look closer at what it does

1) pulls the contents out to a tmp file
2) runs an MD5 against that tmp file then
3) runs SHA against the output of the MD5 resultant set

bob$ curl -s http://www.bing.com/news?q=green > tp1
bob$ md5 tp1 | awk '{print $4}' | openssl sha | cut -c 1-15
69ad1061e16bc8f

bob$ curl -s http://www.bing.com/news?q=purple > tp1
bob$ md5 tp1 | awk '{print $4}' | openssl sha | cut -c 1-15
2069470d4509311
1344585441
Default-avatar
Jakob Lell That's actually quiet strange. My version of openssl behaves differently and outputs the string "(stdin)= " before the actual hash. I'm using openssl version 1.0.1-4ubuntu5.3 as shipped with Ubuntu 12.04 amd64.

$ echo abc|openssl sha
(stdin)= 4cf315510f27558eb84011bb47333b4a5ae10a48
$ echo abc| openssl sha | cut -c 1-15
(stdin)= 4cf315
1344586546
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik No it's not strange... You're missing the first piece of the code... I'm not echoing out the file name..

I'm running an md5 against it, then the 2nd (awk) command rips out "MD5 (tp1) =" from the results, then it's run through the sha function

newpass=`md5 $encmounts/tmp | awk '{print $4}' | openssl sha |
1344589876
Default-avatar
Jakob Lell On my system the command "openssl sha" outputs "(stdin)= ..." regardless of the input it gets via stdin and this static string is not removed by your code. So it's not important whether you pass it a static string or an md5 hash. Which operating system and which version of openssl are you using? According to your example above your version of openssl only outputs plain hash without the string "(stdin)= " in the beginning.
1344591118
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik I'm guessing you failed to notice that md5 isn't a valid command on your system either... The original code was on OS X, but if you knew what you were doing you would of probably mentioned in your first post that


md5 isn't working for you

bob@dontclickshit:~$ uname -ori
2.6.35.4-rscloud x86_64 GNU/Linux

bob@dontclickshit:~$ md5
-bash: md5: command not found

and that the output of md5sum (the *nix) command formats differently than osx

bob@dontclickshit:~$ md5sum tp1
0d24e4a2296d18d7b9ad856245b9d1fe tp1

so Yes... on your box because you clearly don't understand what the code was doing it would show up as


bob@dontclickshit:~$ curl -s http://www.bing.com/news?q=green > tp1
bob@dontclickshitmd5sum tp1 | awk '{print $4}' | openssl sha | cut -c 1-15
96e31e44688cee1

bob@dontclickshit:~$ curl -s http://www.bing.com/news?q=purple > tp1
bob@dontclickshit:~$ md5sum tp1 | awk '{print $4}' | openssl sha | cut -c 1-15
96e31e44688cee1

but since I have what clearly seems to be more experience than you, let me show you how it works on your machine..

I replaced md5 with md5sum and wait for it, awk '{print $1}' because only the 1st column is the hash value of the md5 function.


bob@dontclickshit:~$ uname -ori
2.6.35.4-rscloud x86_64 GNU/Linux
bob@dontclickshit:~$ curl -s

http://www.bing.com/news?q=green > tp1
bob@dontclickshit:~$ md5sum tp1 | awk '{print $1}' | openssl sha
59a0e8f7d569969cb7948fbe94da2168537be55e

bob@dontclickshit:~$ curl -s http://www.bing.com/news?q=purple > tp1
bob@dontclickshit:~$ md5sum tp1 | awk '{print $1}' | openssl sha
6d5bf397770f970a405fd7e83c3b2925cea6c0b4
1344593613
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik Are those random enough for you? It's not openssl sha that's broken, it's the fact that A) it did not go through an MD5 function and B) it did not parse it correctly because of the version differences.
1344593763
Default-avatar
Jakob Lell I did notice that md5 isn't available on my system but this isn't relevant for my point because at least some versions of openssl output the string "(stdin)= " before the actual hash when running "openssl sha". If the openssl command does this then the first 9 digits of the generated password are constant and don't depend on whether the md5 command works or not. Even if your system is not affected, this may lead to predictable passwords on other systems. I've repeated your commands on my system (Ubuntu 12.04 amd64) and here are the results:

$ uname -ori
3.2.0-27-generic x86_64 GNU/Linux
$ curl -s http://www.bing.com/news?q=green > tp1
$ md5sum tp1 | awk '{print $1}' | openssl sha
(stdin)= 40eaf1ca40c875214a10f98317103b5792be2187
$ curl -s http://www.bing.com/news?q=purple > tp1
$ md5sum tp1 | awk '{print $1}' | openssl sha
(stdin)= b3e2a8581c31bf628613e245eaae68f5b8b8d802

And the same on an Ubuntu 10.04 vm with openssl 0.9.8k-7ubuntu8.13:
$ uname -ori
2.6.32-41-generic unknown GNU/Linux
$ curl -s http://www.bing.com/news?q=green > tp1
$ md5sum tp1 | awk '{print $1}' | openssl sha
51b4899500818e4131b4918515404c5896a9337f
$ curl -s http://www.bing.com/news?q=purple > tp1
$ md5sum tp1 | awk '{print $1}' | openssl sha
6041bb7460546b668bc33055728bd4877876593b

As you can see the output of "openssl sha" depends on the version of openssl and you'd better add support for both version so that your code doesn't break when upgrading openssl.

By the way the openssl command also provides an option to generate cryptographically secure random numbers:
$ openssl rand -hex 10
744986ef56eee3e56cf6

That's definitely better than using hash values of a dynamically generated website (which may become predictable due to a site redesign, caching or temporary network/server errors).
1344597487
7c5c876d1933023ac375eead04302e1a
Boris Sverdlik I give up.. you're obviously smarter than me... If you think i'd be happy with an 8 character password of "(stdin)=" for each account as in your version, and would publish a script to that effect, than you must be a rocket scientist.

You can clearly see that I did get rid of the garbage in the MD5 sum, why would I leave in the SHA?

echo "(stdin)=
40eaf1ca40c875214a10f98317103b5792be2187" | cut -c 1-8

You clearly however didn't notice that MD5 wasn't working, just pointing to your theory "Hey I'm so frigging smart"... Yes.. "My system" will give you the same hash value for two totally random values in your bizarre little world... Where I'm hashing the same damn error "-bash md:command not found"

Here watch... Still paying attention Mr Wizard?

bob@dontclickshit:~$ md5 stupid |openssl sha
-bash: md5: command not found
f96cea198ad1dd5617ac084a3d92c6107708c0ef

bob@dontclickshit:~$ md5 dumb |openssl sha
-bash: md5: command not found
f96cea198ad1dd5617ac084a3d92c6107708c0ef

and just because I think I'm smarter than the average bear (not really, just definitely brighter than you) I updated to the latest stable release http://www.openssl.org/source/


bob@dontclickshit:~$ openssl version
OpenSSL 0.9.8o 01 Jun 2010

bob@dontclickshit:~$ md5 dumb |openssl sha
-bash: md5: command not found
f96cea198ad1dd5617ac084a3d92c6107708c0ef

bob@dontclickshit:~$ md5sum dumb |openssl sha
6924e38e4ec845fd4c5e932a92dbddbb0ad5afee

Please tell me you're done at this point?
1344606330
Default-avatar
Jakob Lell You've told that you've downloaded the "latest version" but then you show version 0.9.8o. However the latest stable version of openssl is actually 1.0.1c. If you had tried this version, you would have seen that this version does output the string "(stdin)= " before the actual hash. Since older versions of openssl just output the hash, your code works fine on your system. However, you should acknowledge that the behavior of openssl has changed and the program will generate weak passwords when using a more recent version of openssl.

I didn't mention the missing md5 program in my previous posts because this doesn't influence the output format of openssl and it was obvious from the code that you would just pass the md5 hash to openssl. Actually using a chain of two different hash algorithms is quiet useless and doesn't improve the security (unless you chain a lot more hash functions and keep the ordering of the hash functions a secret).
1344629059
37ecc670c7807f408c368b7a39317fb2
Matthew Harvey I don't really understand the point of this debate. As I take it, the script presented was intended to illustrate a point, which is that it's not that hard to use simple tools available on the system to create highly randomized passwords and to store them in a highly secure, and yet easily accessible, manner. It's just proof-of-concept code, not a ready-for-release open source tool or something.
1344638015
The views expressed in this post are the opinions of the Infosec Island member that posted this content. Infosec Island is not responsible for the content or messaging of this post.

Unauthorized reproduction of this article (in part or in whole) is prohibited without the express written permission of Infosec Island and the Infosec Island member that posted this content--this includes using our RSS feed for any purpose other than personal use.