Bunu bir kabuk komut dosyasında yapmak istediğiniz için , Linux ile parola nasıl kontrol edilir? (on Unix.SE , AB tarafından önerilen ) ile alakalı olan:
Bir dizenin gerçekten bir kullanıcının şifresi olup olmadığını manuel olarak kontrol etmek için, kullanıcının gölge girdisindeki ile aynı karma algoritma ile, kullanıcının gölge girdisindeki ile aynı tuzla hash etmeniz gerekir . Sonra orada saklanan şifre karma ile karşılaştırılabilir.
Bunu nasıl yapacağınızı gösteren eksiksiz, çalışan bir senaryo yazdım.
- Adını
chkpassverirseniz, çalıştırabilirsiniz ve standart girişten bir satır okuyacak ve şifresinin olup olmadığını kontrol edecektir .chkpass useruser
- Bu komut dosyasının bağlı olduğu yardımcı programı edinmek için whois
paketini yükleyin mkpasswd.
- Bu komut dosyasının başarılı olması için kök olarak çalıştırılması gerekir.
- Gerçek iş yapmak için bu komut dosyasını veya herhangi bir bölümünü kullanmadan önce lütfen aşağıdaki Güvenlik Notlarına bakın.
#!/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
Güvenlik Notları
Doğru yaklaşım olmayabilir.
Böyle bir yaklaşımın güvenli ve uygun bir şekilde değerlendirilip değerlendirilmeyeceği, kullanım durumunuzla ilgili belirtmediğiniz ayrıntılara bağlıdır (bu yazıdan itibaren).
Denetlenmemiştir.
Bu senaryoyu yazarken dikkatli olmaya çalışmama rağmen, güvenlik açıkları için uygun şekilde denetlenmedi . Bu bir gösterim amaçlıdır ve bir projenin parçası olarak yayınlandığında "alfa" yazılımı olacaktır. Dahası ...
"İzleyen" başka bir kullanıcı, kullanıcının tuzunu bulabilir .
mkpasswdTuz verilerinin kabulü konusundaki sınırlamalar nedeniyle , bu komut dosyası , kullanım durumuna bağlı olarak kabul edebileceğiniz veya kabul edemeyeceğiniz bilinen bir güvenlik açığı içerir . Varsayılan olarak, Ubuntu ve diğer birçok GNU / Linux sistemindeki kullanıcılar, komut satırı argümanları da dahil olmak üzere diğer kullanıcılar (kök dahil) tarafından çalıştırılan işlemler hakkındaki bilgileri görüntüleyebilir. Kullanıcının girişi veya saklanan parola karması, herhangi bir harici yardımcı programa komut satırı bağımsız değişkeni olarak geçirilmez. Ancak tuz elde, shadowveri tabanı, bir bir komut satırı parametre olarak verilen mkpasswdbu yarar, girdi olarak bir tuz kabul tek yoludur, çünkü.
Eğer
- sistemdeki başka bir kullanıcı veya
- herhangi bir kullanıcı hesabı (örn.
www-data) kodunu çalıştırabilen herhangi biri veya
- çalışan işlemler hakkında bilgileri başka bir şekilde görüntüleyebilen herkes (içindeki girişleri manuel olarak incelemek dahil
/proc)
komut satırı bağımsız değişkenlerini mkpasswdbu komut dosyası tarafından çalıştırıldığı gibi denetleyebilir, ardından kullanıcının tuzunun bir kopyasını shadowveritabanından alabilir. Bu komutun ne zaman çalıştırıldığını tahmin edebilmeleri gerekebilir , ancak bu bazen elde edilebilir.
Tuzunuzla bir saldırgan, tuzunuz ve hashınızla bir saldırgan kadar kötü değil , ama ideal değil. Tuz, birisinin şifrenizi keşfetmesi için yeterli bilgi sağlamaz. Ancak birisinin , o sistemde o kullanıcıya özgü gökkuşağı tabloları veya önceden hesaplanmış sözlük karmaları oluşturmasına izin verir . Bu başlangıçta değersizdir, ancak güvenliğiniz daha sonraki bir tarihte tehlikeye girerse ve tam karma elde edilirse , değiştirme şansı elde etmeden önce kullanıcının şifresini almak daha hızlı bir şekilde kırılabilir .
Bu nedenle bu güvenlik açığı, tamamen sömürülebilir bir güvenlik açığından ziyade daha karmaşık bir saldırı senaryosunda ağırlaştırıcı bir faktördür. Ve yukarıdaki durumun çok zorlandığını düşünebilirsiniz. Ama genel, gerçek dünya kullanımı için herhangi bir yöntem tavsiye isteksiz sızıntı olduğunu herhangi olmayan halka açık veri /etc/shadowkök olmayan bir kullanıcıya.
Bu sorunu tamamen önleyerek şunları yapabilirsiniz:
- siz, C işlevleri çağırmak Perl veya sağlayan başka bir dilde komut bölümünü yazma Gilles yanıtında gösterilen üzere ilgili Unix.SE soruya , ya
- tüm betiğinizi / programınızı bash kullanmak yerine böyle bir dilde yazmak. (Soruyu etiketleme biçiminize göre, bash kullanmayı tercih ettiğiniz anlaşılıyor.)
Bu komut dosyasını nasıl çağırdığınıza dikkat edin.
Güvenilmeyen bir kullanıcının bu komut dosyasını kök olarak çalıştırmasına veya bu komut dosyasını çağıran herhangi bir işlemi kök olarak çalıştırmasına izin verirseniz, dikkatli olun . Ortamı değiştirerek, bu komut dosyasını veya kök olarak çalışan herhangi bir komut dosyasını herhangi bir şey yapabilirler . Bunun olmasını engelleyemediğiniz sürece, kullanıcıların kabuk komut dosyalarını çalıştırmak için yükseltilmiş ayrıcalıklara izin vermemelisiniz.
Bkz. 10.4. Bu konuda daha fazla bilgi için David A. Wheeler'ın Linux ve Unix NASIL için Güvenli Programlama'daki Kabuk Betik Dilleri (sh ve csh Türevleri) . Sunumu setuid komut dosyalarına odaklanırken, diğer mekanizmalar çevreyi doğru bir şekilde sterilize etmezlerse aynı sorunların bazılarına avlanabilir.
Diğer notlar
Sadece shadowveritabanından okuma karmaları destekler .
Bu komut dosyasının çalışması için parolalar gölgelenmelidir (yani, karmaları /etc/shadowyalnızca kökün okuyabileceği, içinde okuyabileceği ayrı bir dosyada olmalıdır /etc/passwd).
Bu her zaman Ubuntu'da geçerli olmalıdır. Gerekirse Her durumda, komut trivially gelen şifre sağlamalarının okumak için uzatılabilir passwdyanı sıra shadow.
Keep IFSBu komut dosyasını değiştirirken aklında.
IFS=$Başlangıçta ayarladım , çünkü bir gölge girdisinin karma alanındaki üç veri birbirinden ayrılıyor $.
- Onlar da bir lider var
$karma tip ve tuz neden olan "${ent[1]}"ve "${ent[2]}"yerine "${ent[0]}"ve "${ent[1]}"sırasıyla.
Bu komut dosyasında $IFSkabuğun sözcükleri nasıl böler veya birleştirdiğini belirleyen tek yerler
bu veriler bir diziye ayrıldığında, bu dizideki tırnaksız $( )komut ikamesinden başlatılarak :
set -f; ent=($(getent shadow "$1" | awk -F: '{print $2}')); set +f
dizi, tam alanla karşılaştırılmak üzere bir dizeye yeniden oluşturulduğunda shadow, içindeki "${ent[*]}"ifade:
if [[ "${ent[*]}" = "$(mkpasswd -sm $hashtype -S "${ent[2]}" <<<"$pass")" ]]
Komut dosyasını değiştirir ve başka durumlarda sözcük bölme (veya sözcük birleştirme) gerçekleştirmesini istiyorsanız, IFSkomutun farklı komutları veya farklı bölümleri için farklı değerlere ayarlamanız gerekir .
Bunu aklınızda $IFStutmazsanız ve normal boşluk ( $' \t\n') olarak ayarlandığını varsayarsanız , komut dosyanızın oldukça garip görünen bazı şekillerde davranmasını sağlayabilirsiniz.