French version available on the site.
let's roll out the breadcrumb...
passwd command
In Ubuntu Karmic 9.10, users change passwords with "passwd" command.Have a look to source code of file /src/passwd.c in shadow-* package [1]:
/*the pw_encrypt function is defined in file lib/encrypt.c
* Authenticate the user. The user will be prompted for their own
* password.
*/
(...)
cipher = pw_encrypt (clear, crypt_passwd);
(...)
char *pw_encrypt (const char *clear, const char *salt)At this stage, we know that passwd command calls the function crypt().
{
(...)
cp = crypt (clear, salt);
(...)
Crypt() takes as arguments the password in plain text given by the user, and a salt. We'll see later that the salt describes the encryption algortihm chosen.
Who is this salt built?
the default encryption method is sha512
By default, Ubuntu Karmic 9.10 uses sha512 to encrypt its passwords [2]. Indeed, here is an excerpt of the file /etc/logins.def:$ cat /etc/login.defsThis file contains the environment variable ENCRYPT_METHOD with value SHA512.
(…)
#
# If set to MD5 , MD5-based algorithm will be used for encrypting password
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
# Note: It is recommended to use a value consistent with
# the PAM modules configuration.
#
ENCRYPT_METHOD SHA512
the salt is built with a prefix defined by the environment variable ENCRYPT_METHOD
On one hand, the environment variable ENCRYPT_METHOD is checked in the function Main() from source passwd.c previously listed:
if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL) {The variable data "method" in structure « new_password » is initialised with « SHA512 » (still in passwd.c):
if (!getdef_bool ("MD5_CRYPT_ENAB")) {
pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
}
} else {
if ( (strcmp (method, "MD5") == 0)
#ifdef USE_SHA_CRYPT
|| (strcmp (method, "SHA256") == 0)
|| (strcmp (method, "SHA512") == 0)
#endif /* USE_SHA_CRYPT */
)
(...)
}
static int new_password (const struct passwd *pw)On the other hand, a new password is created in function Main() of passwd.c, with the help of functions pw_encrypt (previously seen) and crypt_make_salt:
{
(...)
char *method;
/*The function crypt_make_salt is defined in shadow-*/libmisc/salt.c. The authentication method is there checked:
* Encrypt the password, then wipe the cleartext password.
*/
cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
memzero (pass, sizeof pass);
const char *method;You can see that it the environment variable ENCRYPT_METHOD was not defined, MD5_CRYPT_ENAB would be then checked.
(…)
{
method = getdef_str ("ENCRYPT_METHOD");
if (NULL == method) {
method = getdef_bool ("MD5_CRYPT_ENAB") ? "MD5" : "DES";
}
Then, with SHA512, the function crypt_make_salt makes a salt with the concatenation of characters '$','6','$ ' and a pseudo random number. It then returns this string as result.
if (0 == strcmp (method, "SHA512")) {
MAGNUM(result, '6');
strcat(result, SHA_salt_rounds((int *)arg));
salt_len = SHA_salt_size();
crypt() from libc choses the hash algorithm according to the salt
Have a look to crypt().What is the version of glibc?
$ ls /lib/libc-*Download glibc library sources on website gnu.org [3]. The function crypt() is defined in file crypt/crypt-entry.c:
/lib/libc-2.11.1.so
char * crypt (key, salt)
const char *key;
const char *salt;
{
#ifdef _LIBC
/* Try to find out whether we have to use MD5 encryption replacement. */
if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
return __md5_crypt (key, salt);
/* Try to find out whether we have to use SHA256 encryption replacement. */
if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
return __sha256_crypt (key, salt);
/* Try to find out whether we have to use SHA512 encryption replacement. */
if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
return __sha512_crypt (key, salt);
#endif
return __crypt_r (key, salt, &_ufc_foobar);
}
Conclusion
We excaped now the forest. We found that Ubuntu Karmic uses sha512 by default, through the environment variable ENCRYPT_METHOD in file /etc/login.defs.The passwd command is defined in source src/passwd.c in library shadow-*. Passwd wreates a hash with plain text password entered by the user in shell. Passwd calls function pw_encrypt(plain,salt).
this salt is created by function crypt_make_salt() from source shadow-*/libmisc/salt.c. This function uses the environment variable ENCRYPT_METHOD.
The function pw_encrypt of passwd calls function crypt from libc library.
The function crypt choses the encryption method according to salt prefix.
John the Ripper does not support SHA512 yet.
references
1) details of package passwd Ubuntu - http://packages.ubuntu.com/karmic/passwd2) manual libc – function crypt() - http://www.gnu.org/s/libc/manual/html_node/crypt.html
3) sources libc - http://www.gnu.org/software/libc/
Aucun commentaire:
Enregistrer un commentaire