Solved

password encryption...

Posted on 1998-04-12
27
569 Views
Last Modified: 2012-06-27
Hello,
I am trying to create a sript that will change the users passwd.
At first I thought it would be as simple as calling the passwd prorgam using the user-login and new password as comand line arguments.
Realising that I could not include the passwd at comand line, my other option is to edit the /etc/shadow file directly BUT I need to use the same encryption method and/or salt formula that passwd uses to encrypt the password or else the user will not be able to login. (the clashing of the encryption methods will not allow for password matching).
wow.. talk about a run-on sentence...
The reason for this is that I need to create over 700 accounts and I would like to use a random password generator.
basically what this script does is create the account, asign the password and create a passwd.txt file in the root directory so that later I can inform the users of their initial password.

Thanks,
Marcelo Iturbe
0
Comment
Question by:sinner052397
  • 14
  • 8
  • 5
27 Comments
 
LVL 84

Expert Comment

by:ozo
Comment Utility
perl -i.txt -pe 'BEGIN{($u,$p)=splice@ARGV,0,2; srand($$+time) if $]<5.004; @s=("a".."z","A".."Z","0".."9",".","/"); $s=$s[rand(64)].$s[rand(64)]; $c=crypt($p,$s)} s/^\Q$u\E:[^:]*:/$u:$c:/' $user $password /etc/shadow


0
 

Author Comment

by:sinner052397
Comment Utility
Thanks for the code Ozo, but I am having probs trying to implement it.
I tried to place it on multiple lines so that I could implement it in my perl script (and try to understand it)  and came out with something like...
BEGIN{
    ($u,$p)=splice@ARGV,0,2;
    srand($$+time) if $]<5.004;
        @s=("a".."z","A".."Z","0".."9",".","/");
        $s=$s[rand(64)].$s[rand(64)];
        $c=crypt($p,$s)
}
s/^\Q$u\E:[^:]*:/$u:$c:/' $user $password /etc/shadow
but I could not get it to work... my guess is that it wouls have something to do with the IF construct?
Could you help me out?
Thanks
Marcelo
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
the
$user $password /etc/shadow
were not part of the script itself, they were the command line arguments to call it with.
the
-i.txt -p
are also important switches in the call.
the -i could be replaced by setting $^I
and the -p could be replaced by putting a loop around code:
while( <> ){
  /^\Q$u\E:[^:]*:/$u:$c:/
}continue{
  print;
}

0
 

Author Comment

by:sinner052397
Comment Utility
Thanks!
I modified the code to place it in my script and it works perfect!
It ended up looking something like:
@ARGV = ("shadow");
$^I = ".bak";
srand($$+time) if $]<5.004;
@s=("a".."z","A".."Z","0".."9",".","/");
$s=$s[rand(64)].$s[rand(64)];
$c=crypt($p,$s);
while (<>) {
    if (s/^\Q$u\E:[^:]*:/$u:$c:/) {
           $found=1;
           print;
    } else {
           print;
}

The found was so that if the account was not found it needs to be created...
Anyways, thanks a bunch and if you would care to close the question with an answer I'll grade it!


0
 

Author Comment

by:sinner052397
Comment Utility
WAIT!!!
The above code has a bug in it... It changes the password, but I cannot use the set password to log in.
I tried taking out the if statement and just have
             srand($$+time);
             @s=("a".."z","A".."Z","0".."9",".","/");
             $s=$s[rand(64)].$s[rand(64)];
             $c=crypt($p,$s);
      while (<>) {
              if (s/^\Q$u\E:[^:]*:/$u:$c:/) {; ...
But that did not work either!
I'M SO CLOSE!!!!

Thanks again!
Marcelo


0
 

Author Comment

by:sinner052397
Comment Utility
WAIT!!!
The above code has a bug in it... It changes the password, but I cannot use the set password to log in.
I tried taking out the if statement and just have
             srand($$+time);
             @s=("a".."z","A".."Z","0".."9",".","/");
             $s=$s[rand(64)].$s[rand(64)];
             $c=crypt($p,$s);
      while (<>) {
              if (s/^\Q$u\E:[^:]*:/$u:$c:/) {; ...
But that did not work either!
I'M SO CLOSE!!!!

Thanks again!
Marcelo


PS. I also tried a few other srand codes I had 'lying' around but they did not work either...
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Hmm, without compromising your security, could you post an example of password and corresponding line in /etc/shadow that does work?
(it should be safe enough if you make it a dummy account which you disable before posting)
I just want to verify that the script can duplicate that working entry.
 
0
 

Author Comment

by:sinner052397
Comment Utility
G'day ozzo!
Not to worried about security since I am using dummy accounts on a computer that is not on a network (test puter).

The original passwd file contains (or parts thereof):
abc345:!:10329:0:99999:7:::0
abc111:!:10329:0:99999:7:::0
abc321:!:10329:0:99999:7:::0

Once I ran my script the file looks like

abc345:!:10329:0:99999:7:::0
abc111:qSYXnODQQpAJs:10329:0:99999:7:::0
abc321:!:10329:0:99999:7:::0

the password that was assigned to abc111 is k8830
In this example I used a 3 salt charecter, I have tried from using 1 salt character upto 5 and no luck.


0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Are you saying
abc111:qSYXnODQQpAJs:10329:0:99999:7:::0
is the entry that worked for password k8830 or the one that didn't work?
I was interested in an entry that worked, but this is also interesting.
I get crypt('k8830','qS') eq 'qSFY/2n/RbmNw', not 'qSYXnODQQpAJs'
Are you sure you had $p = 'k8830'?
I don't see where you're seting $p in your script
0
 

Author Comment

by:sinner052397
Comment Utility
I placed a print statement to print out the password and salt key before it encrypts the password.
The scrypt is now:
        @ARGV = ("/etc/shadow");
        $^I = ".bak";
        srand($$+time) if $]<5.004;
        @s=("a".."z","A".."Z","0".."9",".","/");
        $s=$s[rand(64)].$s[rand(64)];
print "Password is $p and salt key is $s\n";
        $c=crypt($p,$s);
        while (<>) {
            s/^\Q$u\E:[^:]*:/$u:$c:/)
            print;
        }

The result of the script and entry en /etc/shadow are:
Password is o3529 and salt key is Sb
abc111:SbmfITEqtovQI:10329:0:99999:7:::0

I then set the password to o3529 using the system passwd program and gave me the following:
abc111:w5nRObeGk1nhI:10329:0:99999:7:::0

I guess the secret is trying to get the right srand call??

0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
perl -e 'print crypt("o3529","w5")'
gives me w5nRObeGk1nhI
which matches your system passwd program, but
perl -e 'print crypt("o3529","Sb")'
gives me SbYebgDiovthY
which doesn't match your perl program
Could your perl have a buggy implementation of crypt?
What do the above two perl commands give you?
And what does
perl -v
report?
How about
perl -V


(I don't think the salt selection should matter much,
I just coded it to pick one randomly, but you could also pass the salt to the script too if you prefer.)



0
 

Author Comment

by:sinner052397
Comment Utility
Ok, I think I know where the problem lies, it is in the password
generator: Here is why,
When I hard code the password and salt key such as

    print "Password is c7564 and salt key is w5\n";
        $c=crypt("c7564","w5");
    print "Encrypted password is $c \n";

it gives me the same result from the command line:
perl -e 'print crypt("c7564","w5")'

which is: w53IaQOaNz/NM

But when the script sets the variable for the password
(in this case to e5908)
    print "Password is -$p- and salt key is w5\n";
        $c=crypt("$p","w5");
    print "Encrypted password is -$c- \n";
I get the following
    Password is -e5908- and salt key is w5
    Encrypted password is -w5zM737FQVHnk-

I encapsulated the password and crypted passwd with the -- to make sure that there were no "invisible" characters.

I then ran the comand line
    perl -e 'print crypt("e5908","w5"), "\n"'
and got:
    w5YObbHVuzrEM

Different encryptions! So the problem has to be with the vatiable and the variable is set in the follwing function:

sub setPass {
        srand(time|$$);
        $num = int(rand(9999)+1000); # picks a number from 1000 to 10000
        $num2 = int(rand(26)+97);    # ascii code for a character
        $pack = pack ("c4", $num2);  # turns the ascii number to it's character
        $p = "$pack". $num;          # appends the number to the character and gives me my passwd
}

I needed a simple password generator since the passwords are internal and they
last no longer than 5 days.

Any thoughts?

The reason why I ruled the version of perl our (5.004_4) is because the line
perl -e 'print crypt("o3529","Sb")'
also gave me SbYebgDiovthY


0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Aha! the pack("c4", $num2);
is giving you
$pack = "e\c@\c@\c@"
not
$pack = "e"
try
 pack ("c1", $num2);


(I also think your random password generator may be too predictable, but we can deal with that later)

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:sinner052397
Comment Utility
Wow... I actually have it all working!
I changed the password sub to:
sub setPass {
        srand($$+time);
        @s=("a".."z","0".."9");
$pass=$s[rand(35)].$s[rand(35)].$s[rand(35)].$s[rand(35)].$s[rand(35)].$s[rand(35)];
}

It's a bit better and it works fine. I did not place any special characters like ! because they were giving me problems. I'm sure the solution was as simple as escaping them \! but I'm just glad it's working!

THANK YOU!!!
You have been a great help and very patient!

Marcelo
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
srand($$+time) is a big improvement over srand($$|time)
but I sitll have some concerns.
One thing I should mention is that 5.004_4 will seed the srand for you and that it's usually better to let it
and you certainly don't want to seed twice, for $pass and for $salt.
But even with only one seeding, there's a danger that someone with just a rough idea when the random number generator was seeded will know that there's only a limited number of passwords that could have been generated during that time period.
And it's even worse if you use the same random number generator for the salt, since knowing what salt was generated could eliminate even more possibilities for the password.
To aleviate the last problem, since the randomness and secrecy of the salt is not critical, I'd suggest taking it from something completely different.
(Perhaps the previous modification time of /etc/passwd)
The limited number of possible password seeds us a more difficult problem, which I'm not sure how to address.
Perhaps you could take some random user input to mix in with the generated random number to keep it from being too predictable?


And one other minor hint, if instead of
 $s[rand(35)]
you say
 $s[rand(@s)]
then you don't need to change that part of the code if you ever change the set of characters you want to use.
(and you don't get the little bug that you never generate a '9' :-)

0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
#BTW, here's a little trick:
$pass=join'',@s[map rand($_),(0+@s)x6];

0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Do you have a /dev/random on your machine?
0
 
LVL 1

Accepted Solution

by:
dreamPeace earned 100 total points
Comment Utility

  Ever considered mapping the original password's utility input to a stream, and then simply writing to it to give it the nessesary info?
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Most password utilitys take their input from /dev/tty rather than from stdin,
so mapping the input to a stream may require opening a pty.
Which can be done in Perl, and there are modules like Comm.pl to help you to do it.
But that doesn't address the problem of randomly generating a password.
Or of making sure that it is random enough that someone can't guess the password from a limited number of strings you could have generated based on other clues you may have left, like the time you generated the password, or the salt you generated, or from knowing one of the other 700 passwords generated in the same session...    
0
 
LVL 1

Expert Comment

by:dreamPeace
Comment Utility
 That's not a reason. It'l be VERY hard to guess the password with the simplest
 genereation mechanism (add random numbers) and try to know when is was really
 changed. Also, let the generator source not to be seen by anyone, so they can't even  know the mechanism.  Come on, even FBI could use this as a way. And, if u let the  hacker know the other passwords and other info, that means you're already hacked.
   And no coding will help u then. You can also, to enhance it, use encryption and other
 mathematic functions to create a part of the password, and  these are really hard to break especially if noone sees the source of the generator. And besides does this site
lunches nuclear atacks? That's a LOT of work to pass such security, it's much easier
to adress other unix bugs or even to hack another site. There aren't many sites with that
good of a protection. Trust me, even though I have a lot of ideas of how to protect the site
from potential intruders, for password generation, almost eveything with a 'Random' fits,
as I don't think it's easy nither to get the other 700 passwords nor getting the real Random
table and the CORRECT (and non-covered up) time stamps.  

   Anyway, instead of understing all this, It's MUCH harder to get this generated password
 than to ALL other hacking techniques.  After all, it's better to go for the root not 701 if
 u know 700 already or not.

  Yeah I know, too much of a talk, but the idea should be clear. It's VERY VERY safe.

 Here's a sample:
-----  
 Randomize
 Get random number  1 (rnd1)
 Get random number  2 (rnd2)
 wait rnd1 milliseconds
 Randomize
 Get random number 3 (rnd3)
 Combine rnd1 and rnd3 and make it power 2  //   (a*a) is a power 2
 Take the square root of the outcome to xnum1.
 Get random numbe  4 (rnd4)
 if Rnd4 divides with no remainedr on two, then cut any floating point in xnum1 otherwise                                comlete xnum's floating point to one
 Make any adjustments to the number u want (make this as a predifined string selector)
 Use this as a password.


 
0
 
LVL 1

Expert Comment

by:dreamPeace
Comment Utility
Got a bug there in the generator mechanism - instead of recieving square root out xnum1
 get, for example, the tri-root.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
dreamPeace, I think it may be easier to determine the other generated passwords given that you know one than you seem to  suggest.
(and sinner said the users would be informed of their initial password)

Also, where do you get the seed for your Randomize?
The number of different possible seeds limits the number of
possible random sequences you can generate.
The use of  
sub setPass { srand(time|$$); ...
reseeding each invocation with time|$$
was particularly bad, and would make passwords rather easy to guess
0
 
LVL 1

Expert Comment

by:dreamPeace
Comment Utility

 Sorry, I'm was suggesting a general idea, not knowing if it's possible to do.
 I'm not relaying on seed or salt or pepper or anything like this. The simplest random
 mechanism uses the cumputer random table. If the time of the generation of the random
 number is unknown, you have NO way of determining this number.  What's true,
 is that it is possible to reverse the process and retrieve the numbers, but that's cause I'm
 not a cruptography expert. To be sure use the standard RC5 or what's the name by  SOMEHOW  entering the generated numbers and getting a password it'l take, by what
 they say years to decrypt. I know it's already been cracked, so just use another popular
 method. The thing is that hese aren't easy to reverse, and even the army uses them.
 ( Of course, they also have better one's.... :)
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Yes, a one way hash like MD5, or using a stream cypher like RC4 to generate a one way hash,
or even using the password crypt hash can make it impractical to directly recover the seed from the hash,
But a days worth of second ticks is only 86400 seeds to test.
With so few possibilitys it could easily be cracked quickly.
Perl 5.004 will try to use a faster clock for the seed if your system has one,
and if you don't sabotage it by reseeding it with a worse one,
but it's still a lot less than the 36^6 possible passwords you may think you're getting.
If you can introduce an additional source of unpredictability,
(and if you're careful how you introduce it so you really get the benefit of both sources, and not just the max, or worse, the min,
of the unpredictability from each source)
then you may be able to improve things.
0
 
LVL 1

Expert Comment

by:dreamPeace
Comment Utility
 OK, I give up guys. I have no expirience with cryptography, and everything I've said
 is good only when the hacker DOESN'T know the agorithm (after all, u CAN hide it,
 and it seems that if anyone get's to the source after u hide it... well u won't need to
 be worried about the passwords he might get. ).  
   
   I just want to say that every secret police in the world would love to have u. I believe
 that if u can hack custom alogrithms, why not go directly to the root password? I  suppose that compiling a database of all possible passwords and their crypted form
 isn't very hard with a large disk and a very very good PC (and a lot of time). And besides,
 most users trust on the unix password crypting to keep 'em secure, so what's wrong
 with sending a random number with a small modification (+second random)
 DIRECTLY to the cryptoalgorithm and let it take care of it? Comeon, I ask, what will u do
 get the rest of the users and try to guess it? Or maybe u'l login root and get the source?
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Well, if you want to depend on keeping the source secret, you might as well just include the list of passwords to return explicitly in yor program.
That way, you can insure they were all produced by a completly random unguessable process.
Otherwise, for someone with little experience in cryptography, and that includes you, me, and 99% of the population, keeping your algorithm a secret only insures that noone will be able to warn you about the exploitable weaknesses that you've probably included in your custom algorithm.

I would hope that the root password on a system would be chosen by a better method than with the generator algorithms presented here,
but in fact, because of the one way hash, even if root can know the contents of the password file,
that doesn't necessarily imply that root can know what the passwords themselves are,
only that root can verify a guess as to what a password is.

A database of all possible passwords, even without their salt, would require an impossibly large disk,
such a database would be useful only if you can restrict the possible passwords in some way,
perhaps to a set of common types of poorly chosen passwords, or to the set of passwords generated by a weak algorithm.

A random number generator is only as unpredictable as its seed,
and another random number from the same source will be completely determined by the earlier ones.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
sinner, you still haven't said how you invoke the script
or what sources of randomness you have access to.

If you have someone typing at it, you can extract some randomness from the timing of the keystrokes.

There's also a module to extract randomness from interrupt timing discrepancies .
(but depending on your machine it may be biassed or correlated)

You might also try to do something with disk seek timings...
(although this may be observable by others)


0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Setting up Secure Ubuntu server on VMware 1.      Insert the Ubuntu Server distribution CD or attach the ISO of the CD which is in the “Datastore”. Note that it is important to install the x64 edition on servers, not the X86 editions. 2.      Power on th…
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Learn how to get help with Linux/Unix bash shell commands. Use help to read help documents for built in bash shell commands.: Use man to interface with the online reference manuals for shell commands.: Use man to search man pages for unknown command…
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now