GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo comprobar la contraseña con Linux?

Puede extraer fácilmente la contraseña cifrada con awk. A continuación, debe extraer el prefijo $algorithm$salt$ (asumiendo que este sistema no está usando el DES tradicional, que está fuertemente obsoleto porque puede ser de fuerza bruta en estos días).

correct=$(</etc/shadow awk -v user=bob -F : 'user == $1 {print $2}')
prefix=${correct%"${correct#\$*\$*\$}"}

Para verificar la contraseña, la función C subyacente es crypt , pero no hay un comando de shell estándar para acceder a él.

En la línea de comando, puede usar una sola línea de Perl para invocar crypt en la contraseña.

supplied=$(echo "$password" |
           perl -e '$_ = <STDIN>; chomp; print crypt($_, $ARGV[0])' "$prefix")
if [ "$supplied" = "$correct" ]; then …

Dado que esto no se puede hacer con herramientas de shell puras, si tiene Perl disponible, también puede hacerlo todo en Perl. (O Python, Ruby,... lo que sea que tengas disponible que pueda llamar al crypt función.) Advertencia, código no probado.

#!/usr/bin/env perl
use warnings;
use strict;
my @pwent = getpwnam($ARGV[0]);
if ([email protected]) {die "Invalid username: $ARGV[0]\n";}
my $supplied = <STDIN>;
chomp($supplied);
if (crypt($supplied, $pwent[1]) eq $pwent[1]) {
    exit(0);
} else {
    print STDERR "Invalid password for $ARGV[0]\n";
    exit(1);
}

En un sistema integrado sin Perl, usaría un programa C pequeño y dedicado. Advertencia, escrito directamente en el navegador, ni siquiera he intentado compilar. ¡Esto pretende ilustrar los pasos necesarios, no como una implementación robusta!

/* Usage: echo password | check_password username */
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
    char password[100];
    struct spwd shadow_entry;
    char *p, *correct, *supplied, *salt;
    if (argc < 2) return 2;
    /* Read the password from stdin */
    p = fgets(password, sizeof(password), stdin);
    if (p == NULL) return 2;
    *p = 0;
    /* Read the correct hash from the shadow entry */
    shadow_entry = getspnam(username);
    if (shadow_entry == NULL) return 1;
    correct = shadow_entry->sp_pwdp;
    /* Extract the salt. Remember to free the memory. */
    salt = strdup(correct);
    if (salt == NULL) return 2;
    p = strchr(salt + 1, '$');
    if (p == NULL) return 2;
    p = strchr(p + 1, '$');
    if (p == NULL) return 2;
    p[1] = 0;
    /*Encrypt the supplied password with the salt and compare the results*/
    supplied = crypt(password, salt);
    if (supplied == NULL) return 2;
    return !!strcmp(supplied, correct);
}

Un enfoque diferente es usar un programa existente como su o login . De hecho, si puede, sería ideal hacer arreglos para que la aplicación web realice lo que necesite a través de su -c somecommand username . La dificultad aquí es pasar la contraseña a su; esto requiere una terminal. Se espera la herramienta habitual para emular una terminal, pero es una gran dependencia para un sistema embebido. Además, mientras su está en BusyBox, a menudo se omite porque muchos de sus usos requieren que el binario BusyBox sea setuid root. Aún así, si puede hacerlo, este es el enfoque más sólido desde el punto de vista de la seguridad.


Echa un vistazo a man 5 shadow y man 3 crypt . De este último, puede aprender que la contraseña tiene un hash en /etc/shadow tener la siguiente forma:

 $id$salt$encrypted

donde id define el tipo de cifrado y, leyendo más, puede ser uno de

          ID  | Method
          ---------------------------------------------------------
          1   | MD5
          2a  | Blowfish (not in mainline glibc; added in some
              | Linux distributions)
          5   | SHA-256 (since glibc 2.7)
          6   | SHA-512 (since glibc 2.7)

Según el tipo de hash, debe utilizar la función/herramienta adecuada para generar y verificar la contraseña "a mano". Si el sistema contiene mkpasswd programa, puede usarlo como se sugiere aquí. (Tomas la sal del archivo shadow, si eso no fuera obvio). Por ejemplo, con md5 contraseñas:

 mkpasswd -5 <the_salt> <the_password>

generará la cadena que debe coincidir con /etc/shadow entrada.


Hubo una pregunta similar en Stack Overflow. cluelessCoder proporcionó un script usando expect, que puede o no tener en su sistema integrado.

#!/bin/bash
#
# login.sh $USERNAME $PASSWORD

#this script doesn't work if it is run as root, since then we don't have to specify a pw for 'su'
if [ $(id -u) -eq 0 ]; then
        echo "This script can't be run as root." 1>&2
        exit 1
fi

if [ ! $# -eq 2 ]; then
        echo "Wrong Number of Arguments (expected 2, got $#)" 1>&2
        exit 1
fi

USERNAME=$1
PASSWORD=$2

#since we use expect inside a bash-script, we have to escape tcl-$.
expect << EOF
spawn su $USERNAME -c "exit" 
expect "Password:"
send "$PASSWORD\r"
#expect eof

set wait_result  [wait]

# check if it is an OS error or a return code from our command
#   index 2 should be -1 for OS erro, 0 for command return code
if {[lindex \$wait_result 2] == 0} {
        exit [lindex \$wait_result 3]
} 
else {
        exit 1 
}
EOF

Linux
  1. Cómo verificar la versión de Redhat

  2. Cómo verificar la zona horaria en Linux

  3. Cómo administrar la contraseña de la cuenta en Linux

  4. Cómo verificar el historial de inicio de sesión de Linux

  5. Cómo permitir ssh con contraseñas vacías en Linux

Cómo asegurar servidores Linux con SE Linux

Cómo proteger con contraseña una carpeta en Linux

Cómo comprobar la versión del sistema operativo con la línea de comandos de Linux

Cómo verificar el espacio de intercambio en Linux

¿Cómo proteger GRUB con contraseña en Linux?

Cómo verificar los parámetros del servidor VPS con el comando Linux