3

I am trying to generate a hashed password as in /etc/shadow file, using bash script. The user is prompted for the password which is saved in a variable PSWD. I have extracted the Hash and the salt value from the /etc/shadow file and saved them in a variables HVAL and SVAL respectively.

Now in order to generate a hashed password using Password and the Salt value, I need to use command given below (Reference):

$ perl -e 'print crypt("password","\$6\$salt\$") . "\n"'

In the above command, I must replace "password" with the $PSWD variable, "6" with $HVAL and "salt" with $SVAL variable.

I've tried exporting above variables and replacing them in the perl command, as shown below, but it was totally messed up.

perl -e 'print crypt("$ENV{"PSWD"}","\$$ENV{"HVAL"}\$$ENV{"SVAL"}\$") . "\n"'

What will be the corrections?

3
  • @StéphaneChazelas- I've used the backticks while assigning the output to a variable, still it is not working. Commented Aug 2, 2015 at 6:46
  • Yes, there's also the problem of the quotes, you'd need "$ENV{\"VAR\"}" though "$ENV{VAR}" would be enough, see my answer. Commented Aug 2, 2015 at 6:51
  • If the password is being changed: The hash should be re-generated. If only testing the password then ok.
    – user79743
    Commented Aug 3, 2015 at 13:10

2 Answers 2

6

The problem is with your double quotes. Here you don't need to quote those hash keys as they are simple identifiers. From perldoc perldata:

In fact, a simple identifier within such curlies is forced to be a string, and likewise within a hash subscript. Neither need quoting. Our earlier example, $days{'Feb'} can be written as $days{Feb} and the quotes will be assumed automatically. But anything more complicated in the subscript will be interpreted as an expression. This means for example that $version{2.0}++ is equivalent to $version{2}++, not to $version{'2.0'}++.

So:

perl -le 'print crypt($ENV{PSWD},"\$$ENV{HVAL}\$$ENV{SVAL}\$")'

If you're using it inside backticks, you'd need to double your backslashes as in:

var=`perl -le 'print crypt($ENV{PSWD},"\\$$ENV{HVAL}\\$$ENV{SVAL}\$")'`

Best is to use the $(...) form of command substitution instead:

var=$(perl -le 'print crypt($ENV{PSWD},"\$$ENV{HVAL}\$$ENV{SVAL}\$")')
1
  • A comment that the vars are passed in the environment to avoid being seen in ps -ef will help understand the command concept.
    – user79743
    Commented Aug 3, 2015 at 13:14
0

The sequence to get to the correct quote starts with the original command:

perl -e 'print crypt("password","\$6\$salt\$") . "\n"'

Let's add some space:

perl -e 'print crypt("  password  ","\$  6  \$  salt  \$") . "\n"'

Let's change the vars to their equivalents:

perl -e 'print crypt("  $ENV{PSWD}  ","\$  $ENV{HVAL}  \$  $ENV{SVAL}  \$") . "\n"'

The equivalents should not be quoted, as in quotes they fail:

perl -e 'print "$ENV{PSWD}" . "\n"'      # correct.
perl -e 'print "$ENV{"PSWD"}" . "\n"'    # fail.

And finally, lets remove the spaces inserted above:

perl -e 'print crypt("$ENV{PSWD}","\$$ENV{HVAL}\$$ENV{SVAL}\$") . "\n"'

then, the command may be assigned to a variable.

var="$(  perl -e 'print crypt("$ENV{PSWD}","\$$ENV{HVAL}\$$ENV{SVAL}\$") . "\n"'  )"

With exported values: PSWD=password, HVAL=6, SVAL=saltsalt I get:

$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .