- Given a linux username and a password how can I test if it is a valid account? [closed]
- 2 Answers 2
- check password linux user
- Как проверить, что введенный пароль является действительным паролем для этого пользователя?
- 5 ответов
- Примечания по безопасности
- Это может быть не правильный подход.
- Это не было проверено.
- Другой пользователь, который "смотрит", может обнаружить соль пользователя.
- Будьте осторожны, как вы называете этот сценарий.
- Другие заметки
- Он поддерживает чтение хэшей из shadow только база данных.
- Держать IFS в виду при изменении этого сценария.
Given a linux username and a password how can I test if it is a valid account? [closed]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
So my question is straight forward given a linux username and a password how can I test if it is a valid account?
Here is an example of C-language function how to check username and password stackoverflow.com/a/63173069/2304760
2 Answers 2
You can validate that a given password is correct for a given username using the shadow file.
On most modern distributions, the hashed passwords are stored in the shadow file /etc/shadow (which is only readable by root). As root, pull the line from the shadow file for the given user like so:
cat /etc/shadow | grep username
You will see something like this:
username:$1$TrOIigLp$PUHL00kS5UY3CMVaiC0/g0:15020:0:99999:7.
After the username there is $1. This indicates that it is an MD5 hash. After that there is another $, then (in this case) TrOIigLp followed by another $. TrOIigLp is the salt. After that is the hashed password, which was hashed using the salt — in this case PUHL00kS5UY3CMVaiC0/g0.
Now, you can use openssl to hash the given password using the same salt, like so:
openssl passwd -1 -salt TrOIigLp
Enter the given password when prompted, the openssl command should compute the MD5 hash using the salt provided, and it should be exactly the same as the above from the shadow file. The -1 in the above command is for MD5 hashing.
check password linux user
I am on debian 9. I have a problem to check the password of a linux user in my scripts. I realized that the different linux tools for creating and modifying a user password gave results of different pattern in /etc/shadow To create a user
pwLinux="abcdef1234" userLinux="toto02" pwCrypt=$(perl -e 'print crypt($ARGV[0], "zzz")' $pwLinux) useradd -m -G adm,dip,plugdev,www-data,sudo -p $pwCrypt $userLinux
toto02:zzDxrNjXuUs3U:17469:0:99999:7.
USERNAME="toto02" PASSWD="abcdef1234" ORIGPASS=`grep -w "$USERNAME" /etc/shadow | cut -d: -f2` ORIGPASS=`echo $ORIGPASS | cut -d"$" -f2` GENPASS=$(perl -e 'print crypt($ARGV[0], "zzz")' $PASSWD) if [ "$GENPASS" == "$ORIGPASS" ]; then echo "Valid Password" exit 0 else echo "Invalid Password" exit 1 fi
# username "toto02", newPwd "aabbcc" echo "$:$" | chpasswd
toto02:$6$rLklwx9K$Brv4lvNjR.S7f8i.Lmt8.iv8pgcbKhwDgINzhT1XwCBbD7XkB98lCtwUK3/4hdylkganoLuh/eIc38PtMArgZ/:17469:0:99999:7.
If i want to check this password i must use a different script.
First problem how to have the same pattern of password in both cases? i use:
#!/bin/bash USERNAME="toto02" PASSWD="aabbcc" ORIGPASS=`grep -w "$USERNAME" /etc/shadow | cut -d: -f2` export ALGO=`echo $ORIGPASS | cut -d"$" -f2` export SALT=`echo $ORIGPASS | cut -d"$" -f3` echo "algo: -$ALGO-" echo "salt: -$SALT-" echo "pwd entré: -$PASSWD-" echo "shadow: -$ORIGPASS-" GENPASS="$(perl -e 'print crypt("$ENV","\$$ENV\$$ENV\$")')" echo "pwd généré: -$GENPASS-" if [ "$GENPASS" == "$ORIGPASS" ]; then echo "Valid Password" exit 0 else echo "Invalid Password" exit 1 fi
algo: -6- salt: -rLklwx9K- pwd entré: -aabbcc- shadow: -$6$rLklwx9K$Brv4lvNjR.S7f8i.Lmt8.iv8pgcbKhwDgINzhT1XwCBbD7XkB98lCtwUK3/4hdylkganoLuh/eIc38PtMArgZ/- pwd généré: -$6$rLklwx9K$AIX1bUMAK9bwdd2g3ST5VtXTvHlHXHxnh4Xj.fLdxjaEkAAvHeeN5islid0wtmZN5u1zWQBup./IP8IH9i6W7/- Invalid Password
Как проверить, что введенный пароль является действительным паролем для этого пользователя?
В скрипте bash я должен проверить, является ли пароль, заданный пользователем, действительным паролем пользователя.
Т.е. предположим, что у меня есть пользователь A с паролем PA.. В сценарии я попросил пользователя A ввести свой пароль, так как проверить, действительно ли введенная строка является его паролем.
5 ответов
Поскольку вы хотите сделать это в сценарии оболочки, пара вкладов в Как проверить пароль в Linux? (на Unix.SE, предложенный AB) особенно актуальны:
- Ответ rozcietrzewiacz на создание хэша пароля, который соответствует записи в /etc/shadow дает часть решения.
- КомментарийДаниэля Алдера объясняет другой синтаксис mkpasswd команда присутствует в Debian (и Ubuntu).
Чтобы вручную проверить, является ли строка действительно паролем какого-либо пользователя, вы должны хешировать ее с помощью того же алгоритма хеширования, что и в теневой записи пользователя, с той же солью, что и в теневой записи пользователя. Затем его можно сравнить с хешем пароля, хранящимся там.
Я написал полный рабочий скрипт, демонстрирующий, как это сделать.
- Если вы назовете это chkpass , Вы можете запустить chkpass user и он будет читать строку из стандартного ввода и проверить, если это user пароль.
- Установите Whois пакет для получения mkpasswd утилита, от которой зависит этот скрипт.
- Этот сценарий должен быть запущен от имени пользователя root для успеха.
- Прежде чем использовать этот сценарий или любую его часть для реальной работы, ознакомьтесь с примечаниями по безопасности ниже.
#!/usr/bin/env bash xcorrect=0 xwrong=1 enouser=2 enodata=3 esyntax=4 ehash=5 IFS=$ die() < printf '%s: %s\n' "$0" "$2" >&2 exit $1 > report() < if (($1 == xcorrect)) then echo 'Correct password.' else echo 'Wrong password.' fi exit $1 >(($# == 1)) || die $esyntax "Usage: $(basename "$0") " case "$(getent passwd "$1" | awk -F: '')" in x) ;; '') die $enouser "error: user '$1' not found";; *) die $enodata "error: $1's password appears unshadowed!";; esac if [ -t 0 ]; then IFS= read -rsp "[$(basename "$0")] password for $1: " pass printf '\n' else IFS= read -r pass fi set -f; ent=($(getent shadow "$1" | awk -F: '')); set +f case "$" in 1) hashtype=md5;; 5) hashtype=sha-256;; 6) hashtype=sha-512;; '') case "$" in \*|!) report $xwrong;; '') die $enodata "error: no shadow entry (are you root?)";; *) die $enodata 'error: failure parsing shadow entry';; esac;; *) die $ehash "error: password hash type is unsupported";; esac if [[ "$" = "$(mkpasswd -sm $hashtype -S "$" <<<"$pass")" ]] then report $xcorrect else report $xwrong fi
Примечания по безопасности
Это может быть не правильный подход.
Вопрос о том, следует ли считать такой подход безопасным или иным образом подходящим, зависит от деталей вашего варианта использования, которые вы не предоставили (на момент написания статьи).
Это не было проверено.
Хотя я пытался соблюдать осторожность при написании этого сценария, он не был должным образом проверен на наличие уязвимостей в безопасности. Он предназначен для демонстрации и будет "альфа" программным обеспечением, если будет выпущен как часть проекта. Более того.
Другой пользователь, который "смотрит", может обнаружить соль пользователя.
Из-за ограничений в том, как mkpasswd принимает солидные данные, этот сценарий содержит известный недостаток безопасности, который вы можете или не можете считать приемлемым в зависимости от варианта использования. По умолчанию пользователи в Ubuntu и большинстве других систем GNU/Linux могут просматривать информацию о процессах, выполняемых другими пользователями (включая root), включая их аргументы командной строки. Ни пользовательский ввод, ни сохраненный хэш пароля не передаются в качестве аргумента командной строки какой-либо внешней утилите. Но соль, извлеченная из shadow базы данных, задается в качестве аргумента командной строки для mkpasswd , поскольку это единственный способ, которым утилита принимает соль в качестве входных данных.
- другой пользователь в системе, или
- любой, кто имеет возможность создать любую учетную запись пользователя (например, www-data ) запустить их код, или
- любой, кто в противном случае может просматривать информацию о запущенных процессах (в том числе вручную проверяя записи в /proc )
может проверить аргументы командной строки mkpasswd так как он запускается этим сценарием, они могут получить копию соли пользователя из shadow база данных. Возможно, им придется угадывать, когда выполняется эта команда, но это иногда достижимо.
Атакующий с вашей солью не так плох, как атакующий с вашей солью и хэшем, но это не идеально. Соль не дает достаточно информации, чтобы кто-то мог найти ваш пароль. Но это позволяет кому-то генерировать радужные таблицы или предварительно вычисленные хеши словаря, специфичные для этого пользователя в этой системе. Это изначально бесполезно, но если ваша безопасность будет скомпрометирована на более позднем этапе и будет получен полный хэш, его можно будет взломать быстрее, чтобы получить пароль пользователя, прежде чем он получит возможность изменить его.
Таким образом, этот недостаток безопасности является обостряющим фактором в более сложном сценарии атаки, а не полностью уязвимой уязвимостью. И вы могли бы рассмотреть вышеуказанную ситуацию надуманным. Но я не хочу рекомендовать любой метод для общего, реального использования, который пропускает любые непубличные данные из /etc/shadow для пользователя без полномочий root.
Вы можете полностью избежать этой проблемы:
- написание части вашего скрипта на Perl или другом языке, который позволяет вам вызывать функции C, как показано в ответе Жиляна связанный вопрос Unix.SE, или
- написание всего сценария / программы на таком языке, а не использование bash. (Судя по тому, как вы пометили вопрос, похоже, вы предпочитаете использовать bash.)
Будьте осторожны, как вы называете этот сценарий.
Если вы позволяете ненадежному пользователю запускать этот сценарий от имени пользователя root или запускать любой процесс от имени пользователя root, который вызывает этот сценарий, будьте осторожны. Изменяя среду, они могут заставить этот скрипт - или любой скрипт, который запускается от имени root - делать что угодно. Если вы не можете предотвратить это, вы не должны разрешать пользователям повышенные привилегии для запуска сценариев оболочки.
Смотрите 10.4. Языки сценариев оболочки (производные sh и csh) в книге Дэвида А. Уилера по безопасному программированию для Linux и Unix HOWTO для получения дополнительной информации об этом. Хотя его презентация сосредоточена на сценариях setuid, другие механизмы могут стать жертвами некоторых из тех же проблем, если они неправильно очищают среду.
Другие заметки
Он поддерживает чтение хэшей из shadow только база данных.
Для работы этого скрипта пароли должны быть затенены (т. Е. Их хеши должны находиться в отдельном /etc/shadow файл, который может прочитать только root, а не в /etc/passwd ).
Это всегда должно быть в Ubuntu. В любом случае, при необходимости, скрипт может быть тривиально расширен для чтения хэшей паролей. passwd так же как shadow ,
Держать IFS в виду при изменении этого сценария.
Я поставил IFS=$ в начале, так как три данных в хеш-поле теневой записи разделены $ ,
- У них также есть ведущий $ Вот почему тип хеша и соль "$" а также "$" скорее, чем "$" а также "$" соответственно.
Единственные места в этом скрипте, где $IFS определяет, как оболочка разделяет или объединяет слова
- когда эти данные разбиваются на массив, инициализируя его из не заключенных в кавычки $( ) подстановка команд в:
set -f; ent=($(getent shadow "$1" | awk -F: '')); set +f
if [[ "$" = "$(mkpasswd -sm $hashtype -S "$" <<<"$pass")" ]]
Если вы модифицируете скрипт и выполняете его деление слов (или объединение слов) в других ситуациях, вам необходимо установить IFS к различным значениям для разных команд или разных частей скрипта.
Если вы не помните об этом и не предполагаете $IFS устанавливается на обычные пробелы ( $' \t\n' ), вы могли бы в конечном итоге заставить свой скрипт вести себя довольно странно, на первый взгляд.