चूंकि आप इसे शेल स्क्रिप्ट में करना चाहते हैं, लिनक्स के साथ पासवर्ड की जांच करने में योगदान की एक जोड़ी ? (पर Unix.SE , एबी ने सुझाव दिया ) विशेष रूप से प्रासंगिक हैं:
- rozcietrzewiacz के जवाब एक पासवर्ड हैश कि में एक प्रविष्टि से मेल खाता है पैदा करने पर
/etc/shadow
समाधान का हिस्सा देता है।
- डैनियल एल्डर की टिप्पणी
mkpasswd
डेबियन (और उबंटू) में मौजूद कमांड के विभिन्न सिंटैक्स की व्याख्या करती है ।
मैन्युअल रूप से जांचने के लिए कि क्या कोई स्ट्रिंग वास्तव में कुछ उपयोगकर्ता का पासवर्ड है, तो आपको इसे उसी हैश एल्गोरिथम के साथ उपयोगकर्ता की छाया प्रविष्टि में होना चाहिए, जिसमें उपयोगकर्ता की छाया प्रविष्टि में नमक समान हो । फिर इसकी तुलना वहां रखे पासवर्ड हैश से की जा सकती है।
मैंने एक पूर्ण, कार्यशील स्क्रिप्ट लिखी है जिसमें यह दिखाया गया है कि यह कैसे करना है।
- यदि आप इसे नाम देते हैं
chkpass
, तो आप चला सकते हैं और यह मानक इनपुट से एक पंक्ति पढ़ेगा और जांच करेगा कि क्या यह पासवर्ड है।chkpass user
user
- उपयोगिता प्राप्त करने के लिए whois पैकेज स्थापित करें जिस
mkpasswd
पर यह स्क्रिप्ट निर्भर करती है।
- सफल होने के लिए इस स्क्रिप्ट को रूट के रूप में चलाया जाना चाहिए।
- वास्तविक काम करने के लिए इस स्क्रिप्ट या इसके किसी भी भाग का उपयोग करने से पहले, कृपया नीचे सुरक्षा नोट्स देखें।
#!/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") <username>"
case "$(getent passwd "$1" | awk -F: '{print $2}')" 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: '{print $2}')); set +f
case "${ent[1]}" in
1) hashtype=md5;; 5) hashtype=sha-256;; 6) hashtype=sha-512;;
'') case "${ent[0]}" 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 [[ "${ent[*]}" = "$(mkpasswd -sm $hashtype -S "${ent[2]}" <<<"$pass")" ]]
then report $xcorrect
else report $xwrong
fi
सुरक्षा नोट
यह सही दृष्टिकोण नहीं हो सकता है।
इस तरह एक दृष्टिकोण को सुरक्षित माना जाना चाहिए या नहीं और अन्यथा उपयुक्त आपके उपयोग के मामले के विवरण पर निर्भर करता है जो आपने प्रदान नहीं किया है (इस लेखन के रूप में)।
इसका ऑडिट नहीं हुआ है।
हालांकि मैंने इस स्क्रिप्ट को लिखते समय देखभाल करने की कोशिश की है, लेकिन सुरक्षा कमजोरियों के लिए इसे ठीक से ऑडिट नहीं किया गया है । यह एक प्रदर्शन के रूप में अभिप्रेत है, और यदि प्रोजेक्ट के भाग के रूप में जारी किया जाता है तो यह "अल्फ़ा" सॉफ्टवेयर होगा। इसके अलावा ...
एक अन्य उपयोगकर्ता जो "देख रहा है" उपयोगकर्ता के नमक की खोज करने में सक्षम हो सकता है ।
mkpasswd
नमक डेटा को स्वीकार करने की सीमाओं के कारण , इस स्क्रिप्ट में एक ज्ञात सुरक्षा दोष है , जिसे आप उपयोग के मामले के आधार पर स्वीकार्य नहीं मान सकते हैं या नहीं। डिफ़ॉल्ट रूप से, उबंटू और अधिकांश अन्य जीएनयू / लिनक्स सिस्टम पर उपयोगकर्ता अपने कमांड-लाइन तर्कों सहित अन्य उपयोगकर्ताओं (रूट सहित) द्वारा संचालित प्रक्रियाओं के बारे में जानकारी देख सकते हैं। न तो उपयोगकर्ता के इनपुट और न ही संग्रहीत पासवर्ड हैश को किसी भी बाहरी उपयोगिता के लिए कमांड-लाइन तर्क के रूप में पारित किया जाता है। लेकिन डेटाबेस से निकाले गए नमक को कमांड-लाइन तर्क के रूप में दिया जाता है , क्योंकि यह एकमात्र तरीका है कि उपयोगिता नमक को इनपुट के रूप में स्वीकार करती है।shadow
mkpasswd
अगर
- सिस्टम पर एक अन्य उपयोगकर्ता, या
- जो कोई भी उपयोगकर्ता खाता बनाने की क्षमता रखता है (जैसे,
www-data
) अपना कोड चलाते हैं, या
- कोई भी जो अन्यथा चलने वाली प्रक्रियाओं के बारे में जानकारी देख सकता है (मैन्युअल प्रविष्टियों का निरीक्षण सहित
/proc
)
कमांड-लाइन तर्कों की जांच करने में सक्षम है mkpasswd
क्योंकि यह इस स्क्रिप्ट द्वारा चलाया जाता है, फिर वे shadow
डेटाबेस से उपयोगकर्ता के नमक की एक प्रति प्राप्त कर सकते हैं । वे हो सकता है अनुमान करने में सक्षम होना चाहिए जब कि आदेश चला जाता है, लेकिन है कि कभी कभी प्राप्त है।
आपके नमक के साथ एक हमलावर आपके नमक और हैश के साथ हमलावर के रूप में बुरा नहीं है , लेकिन यह आदर्श नहीं है। नमक आपके पासवर्ड की खोज के लिए किसी को पर्याप्त जानकारी प्रदान नहीं करता है। लेकिन यह किसी को इंद्रधनुष सारणी या पूर्व-संकलित शब्दकोश हैश को उस प्रणाली पर उस उपयोगकर्ता के लिए विशिष्ट बनाने की अनुमति देता है। यह शुरू में बेकार है, लेकिन अगर बाद की तारीख में आपकी सुरक्षा से समझौता किया जाता है और पूर्ण हैश प्राप्त किया जाता है, तो उपयोगकर्ता के पासवर्ड को प्राप्त करने से पहले उसे बदलने के लिए और अधिक तेज़ी से क्रैक किया जा सकता है।
इस प्रकार यह सुरक्षा दोष पूरी तरह से शोषक भेद्यता के बजाय अधिक जटिल हमले परिदृश्य में एक शानदार कारक है। और आप उपरोक्त स्थिति पर विचार कर सकते हैं। लेकिन मैं किसी भी गैर-सार्वजनिक /etc/shadow
उपयोगकर्ता से गैर-सार्वजनिक डेटा लीक करने वाले सामान्य, वास्तविक दुनिया के उपयोग के लिए किसी भी विधि की सिफारिश करने के लिए अनिच्छुक हूं ।
आप इस समस्या से पूरी तरह से बच सकते हैं:
- पर्ल या देता है कि कुछ अन्य भाषा में अपनी स्क्रिप्ट का हिस्सा लिखने के रूप में आप, सी कार्यों फोन गाइल्स के जवाब में दिखाया गया है करने के लिए संबंधित Unix.SE प्रश्न , या
- बैश का उपयोग करने के बजाय अपनी पूरी स्क्रिप्ट / प्रोग्राम को ऐसी भाषा में लिखें। (आपके द्वारा प्रश्न को टैग करने के तरीके के आधार पर, ऐसा प्रतीत होता है कि आप बैश का उपयोग करना पसंद करते हैं।)
सावधान रहें कि आप इस स्क्रिप्ट को कैसे कहते हैं।
यदि आप एक अविश्वसनीय उपयोगकर्ता को इस स्क्रिप्ट को रूट के रूप में चलाने या किसी भी प्रक्रिया को रूट के रूप में चलाने की अनुमति देते हैं जो इस स्क्रिप्ट को कॉल करता है, तो सावधान रहें । पर्यावरण को बदलकर, वे इस लिपि को बना सकते हैं - या कोई भी लिपि जो जड़ के रूप में चलती है - कुछ भी करें । जब तक आप इसे होने से रोक सकते हैं, आपको उपयोगकर्ताओं को शेल स्क्रिप्ट चलाने के लिए उन्नत विशेषाधिकार की अनुमति नहीं देनी चाहिए।
10.4 देखें । इस पर अधिक जानकारी के लिए Linux और Unix HOWTO के लिए डेविड ए। व्हीलर के सिक्योर प्रोग्रामिंग में शेल स्क्रिप्टिंग लैंग्वेज (sh और csh डेरिवेटिव्स) । जबकि उनकी प्रस्तुति सेतुबंध लिपियों पर केंद्रित है, अन्य तंत्र कुछ ऐसी ही समस्याओं के शिकार हो सकते हैं यदि वे पर्यावरण को सही ढंग से साफ नहीं करते हैं।
अन्य नोट
यह shadow
केवल डेटाबेस से हैश पढ़ने का समर्थन करता है ।
इस स्क्रिप्ट को काम करने के लिए पासवर्ड को छायांकित किया जाना चाहिए (अर्थात, उनका हैश अलग /etc/shadow
फाइल में होना चाहिए जो केवल रूट पढ़ सकता है, अंदर नहीं /etc/passwd
)।
उबंटू में हमेशा ऐसा ही होना चाहिए। किसी भी स्थिति में, यदि आवश्यक हो तो स्क्रिप्ट को पासवर्ड हैश के passwd
साथ-साथ पढ़ने के लिए तुच्छ रूप से बढ़ाया जा सकता है shadow
।
IFS
इस स्क्रिप्ट को संशोधित करते समय ध्यान रखें ।
मैंने IFS=$
शुरुआत में सेट किया, क्योंकि एक छाया प्रविष्टि के हैश क्षेत्र में तीन डेटा द्वारा अलग किए गए हैं $
।
- उन्होंने यह भी एक प्रमुख है
$
, जिसके कारण हैश प्रकार और नमक कर रहे हैं, "${ent[1]}"
और "${ent[2]}"
के बजाय "${ent[0]}"
और "${ent[1]}"
, क्रमशः।
इस लिपि में एकमात्र स्थान जहां $IFS
यह निर्धारित करता है कि शैल कैसे विभाजित होती है या शब्दों को जोड़ती है
जब इन आंकड़ों को एक क्रम में विभाजित किया जाता है, तो इसे अनछुए $(
)
कमांड प्रतिस्थापन से आरंभ करके :
set -f; ent=($(getent shadow "$1" | awk -F: '{print $2}')); set +f
जब सरणी को पूर्ण फ़ील्ड से तुलना करने के लिए एक स्ट्रिंग में पुनर्गठित किया जाता है shadow
, तो इसमें "${ent[*]}"
अभिव्यक्ति:
if [[ "${ent[*]}" = "$(mkpasswd -sm $hashtype -S "${ent[2]}" <<<"$pass")" ]]
यदि आप स्क्रिप्ट को संशोधित करते हैं और अन्य स्थितियों में शब्द विभाजन (या शब्द जुड़ना) करते हैं, तो आपको IFS
अलग-अलग कमांड या स्क्रिप्ट के विभिन्न भागों के लिए अलग-अलग मान सेट करने होंगे ।
यदि आप इसे ध्यान में नहीं रखते हैं और मान लें $IFS
कि आप सामान्य व्हाट्सएप ( $' \t\n'
) पर सेट हैं , तो आप अपनी स्क्रिप्ट को कुछ अजीब-अजीब तरीकों से व्यवहार कर सकते हैं।