लिनक्स के साथ पासवर्ड कैसे जांचें?


22

मैं लिनक्स कमांड लाइन से जांचना चाहता हूं, अगर किसी दिए गए क्लीयरटेक्स्ट पासवर्ड एक / आदि / छाया पर एक क्रिप्टेड पासवर्ड के समान है

(मुझे वेब उपयोगकर्ताओं को प्रमाणित करने के लिए इसकी आवश्यकता है। मैं एक एम्बेडेड लिनक्स चला रहा हूं।)

मेरे पास / etc / छाया फ़ाइल तक पहुंच है।


पासवर्ड के साथ उपयोगकर्ता के रूप में लॉग इन करें?
Kusalananda

परीक्षण स्वचालित रूप से किया जाना चाहिए, मैं मैन्युअल रूप से वेब सर्वर से पासवर्ड नहीं टाइप कर सकता हूं
michelemarcon

जवाबों:


17

आप आसानी से awk के साथ एन्क्रिप्टेड पासवर्ड निकाल सकते हैं। फिर आपको उपसर्ग निकालने की जरूरत है $algorithm$salt$(यह मानते हुए कि यह प्रणाली पारंपरिक डीईएस का उपयोग नहीं कर रही है, जो कि दृढ़ता से पदावनत है क्योंकि यह इन दिनों क्रूर-मजबूर हो सकता है)।

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

पासवर्ड जाँच के लिए, अंतर्निहित C फ़ंक्शन है crypt, लेकिन इसे एक्सेस करने के लिए कोई मानक शेल कमांड नहीं है।

कमांड लाइन पर, आप cryptपासवर्ड पर चालान करने के लिए एक पर्ल वन-लाइनर का उपयोग कर सकते हैं।

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

चूंकि यह शुद्ध शेल टूल में नहीं किया जा सकता है, यदि आपके पास पर्ल उपलब्ध है, तो आप पर्ल में भी यह सब कर सकते हैं। (या पायथन, रूबी, ... आपके पास जो कुछ भी उपलब्ध है वह cryptफ़ंक्शन को कॉल कर सकता है ।) चेतावनी, अनुपलब्ध कोड।

#!/usr/bin/env perl
use warnings;
use strict;
my @pwent = getpwnam($ARGV[0]);
if (!@pwent) {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);
}

पर्ल के बिना एक एम्बेडेड सिस्टम पर, मैं एक छोटा, समर्पित सी प्रोग्राम का उपयोग करूंगा। चेतावनी, सीधे ब्राउज़र में टाइप की गई, मैंने संकलन करने की कोशिश भी नहीं की। यह आवश्यक कदमों को स्पष्ट करने के लिए है, न कि एक मजबूत कार्यान्वयन के रूप में!

/* 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);
}

एक अलग दृष्टिकोण मौजूदा प्रोग्राम जैसे कि suया का उपयोग करना है login। वास्तव में, यदि आप कर सकते हैं, तो वेब एप्लिकेशन के लिए जो कुछ भी इसके माध्यम से आवश्यक है उसे करने के लिए व्यवस्थित करना आदर्श होगा su -c somecommand username। यहां कठिनाई पासवर्ड को खिलाने के लिए है su; इसके लिए एक टर्मिनल की आवश्यकता होती है। टर्मिनल का अनुकरण करने वाला सामान्य उपकरण उम्मीद है , लेकिन यह एक एम्बेडेड सिस्टम के लिए एक बड़ी निर्भरता है। साथ ही, suव्यस्त बॉक्स में होने के बावजूद, इसे अक्सर छोड़ दिया जाता है क्योंकि इसके कई उपयोगों के लिए सेट रूट के लिए व्यस्त बॉक्स की आवश्यकता होती है। फिर भी, यदि आप ऐसा कर सकते हैं, तो सुरक्षा के दृष्टिकोण से यह सबसे मजबूत दृष्टिकोण है।


1
मुझे suअप्रोच पसंद है ।
बेंजोना

6

पर एक नजर है man 5 shadowऔर man 3 crypt। उत्तरार्द्ध से, आप यह सीख सकते हैं कि पासवर्ड हैश में /etc/shadowनिम्न रूप में है:

 $id$salt$encrypted

जहां idएन्क्रिप्शन के प्रकार को परिभाषित करता है और, आगे पढ़ना, इनमें से एक हो सकता है

          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)

हैश के प्रकार के आधार पर, आपको "हाथ से" पासवर्ड बनाने और सत्यापित करने के लिए उपयुक्त फ़ंक्शन / उपकरण का उपयोग करने की आवश्यकता है। यदि सिस्टम में mkpasswdप्रोग्राम है, तो आप इसे यहाँ सुझाए अनुसार उपयोग कर सकते हैं । (आप छाया फ़ाइल से नमक लेते हैं , अगर यह स्पष्ट नहीं था।) उदाहरण के लिए, md5पासवर्ड के साथ :

 mkpasswd -5 <the_salt> <the_password>

वह स्ट्रिंग उत्पन्न करेगा जो /etc/shadowप्रविष्टि से मेल खाना चाहिए ।


1
अपने डेबियन व्हीज़िए पर मेरे पास कमांड के लिए एक पूरी तरह से अलग सिंटैक्स mkpasswdथा, जिसे मुझे उपयोग करके इंस्टॉल करना था apt-get install whois। छाया रेखा के लिए कमांड लाइन <user>:$6$<salt>$<pwd>:थीmkpasswd -msha-512 <password> <salt>
डैनियल एल्डर

1

स्टैक ओवरफ्लो पर एक समान प्रश्न पूछा गया था । cluelessCoder ने उम्मीद का उपयोग करते हुए एक स्क्रिप्ट प्रदान की , जो आपके एम्बेडेड सिस्टम पर हो सकती है या नहीं।

#!/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

0

यह ध्यान रखें कि, सिस्टम को ठीक से कॉन्फ़िगर किया गया है, प्रोग्राम को रूट के रूप में चलाने की आवश्यकता होगी।

छाया फ़ाइल को सीधे पढ़ने और क्रिप्ट के आसपास अपना कोड लिखने से बेहतर उपाय सिर्फ पैम बाइंडिंग का उपयोग करना होगा।

व्यंग्य तर्कों का उपयोग करने के लिए अनुकूल करने के लिए इतना आसान - - टारबॉल stdio का उपयोग कर पुष्टि करने उपयोगकर्ता नाम / पासवर्ड के लिए एक सरल CLI उपकरण के साथ आने के लिए प्रयोग किया जाता है, हालांकि संस्करण मैं काट दिया पहले शायद ही संरचित प्रोग्रामिंग के लिए एक पिन-अप पोस्टर था। एक त्वरित Google और ऐसा लगता है कि हाल के संस्करणों को काफी हद तक साफ किया गया है, लेकिन अभी भी कुछ 'गोटो' वहां मौजूद हैं।


0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


passwordHash () {
    password=${1}
    salt=${2}
    encryption=${3}

    hashes=$(echo ${password} | openssl passwd -${encryption} -salt ${salt} -stdin)
    echo $(substring ${hashes} "$" "3")
}


passwordIsValid () {
    user=${1}
    password=${2}

    encryption=$(secret "encryption" ${user})
    salt=$(secret "salt" ${user})
    salted=$(secret "salted" ${user})
    hash=$(passwordHash ${password} ${salt} ${encryption})

    [ ${salted} = ${hash} ] && echo "true" || echo "false"
}


secret () {
    secret=${1}
    user=${2}
    shadow=$(shadow ${user})

    if [ ${secret} = "encryption" ]; then
        position=1
    elif [ ${secret} = "salt" ]; then
        position=2
    elif [ ${secret} = "salted" ]; then
        position=3
    fi

    echo $(substring ${shadow} "$" ${position})
}


shadow () {
    user=${1}
    shadow=$(cat /etc/shadow | grep ${user})
    shadow=$(substring ${shadow} ":" "1")
    echo ${shadow}
}


substring () {
    string=${1}
    separator=${2}
    position=${3}

    substring=${string//"${separator}"/$'\2'}
    IFS=$'\2' read -a substring <<< "${substring}"
    echo ${substring[${position}]}
}


passwordIsValid ${@}

एक त्रुटि की पुष्टि करें line 61: :: syntax error: operand expected (error token is ":")
हंगामा करना

टर्मिनल एमुलेटर बैश 5 होना चाहिए, और आपको तर्क के रूप में उपयोगकर्ता नाम और पासवर्ड दोनों को इंगित करना होगा। मैंने इसका परीक्षण किया है।
अल्बर्टो साल्विया नॉवेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.