วิธีตรวจสอบรหัสผ่านที่ป้อนเป็นรหัสผ่านที่ถูกต้องสำหรับผู้ใช้รายนี้?


15

สถานการณ์:

ในสคริปต์ทุบตีฉันต้องตรวจสอบว่ารหัสผ่านที่กำหนดโดยผู้ใช้เป็นรหัสผ่านของผู้ใช้ที่ถูกต้องหรือไม่

ฉันคิดว่าฉันมีผู้ใช้ A พร้อมรหัสผ่าน PA .. ในสคริปต์ฉันถามผู้ใช้ A ให้ป้อนรหัสผ่านดังนั้นวิธีการตรวจสอบว่าสตริงที่ป้อนเป็นรหัสผ่านของเขาจริง ๆ หรือไม่ ...


คุณหมายความว่าอย่างไรกับรหัสผ่านที่ถูกต้อง? ต้องการทดสอบว่าเป็นรหัสผ่านของผู้ใช้จริงหรือไม่
AB

@AB รหัสผ่านที่ถูกต้อง = รหัสผ่านเข้าสู่ระบบสิ่งที่คุณต้องการโทร ... ฉันหมายถึงรหัสผ่านสำหรับผู้ใช้นี้
Maythux

@AB ฉันรู้ว่ามันจะเป็นช่องโหว่ด้านความปลอดภัย แต่ที่นี่คุณรู้ชื่อผู้ใช้แล้วหรือยัง ... ในคำอื่น ๆ มันเป็นการทดสอบว่ารหัสผ่านสำหรับผู้ใช้รายนี้ ..
Maythux

3
นี่คือคำตอบของคุณ: unix.stackexchange.com/a/21728/107084
AB

วิธีการแก้ปัญหาบนพื้นฐานexpectที่stackoverflow.com/a/1503831/320594
Jaime Hablutzel

คำตอบ:


14

เนื่องจากคุณต้องการทำสิ่งนี้ในเชลล์สคริปต์มีส่วนร่วมสองสามอย่างในวิธีตรวจสอบรหัสผ่านด้วย Linux? (ในUnix.SE , แนะนำโดย AB ) มีความเกี่ยวข้องโดยเฉพาะ

  • คำตอบของrozcietrzewiaczเกี่ยวกับการสร้างแฮชรหัสผ่านที่ตรงกับรายการใน/etc/shadowให้ส่วนหนึ่งของการแก้ปัญหา
  • ความคิดเห็นของDaniel Alderอธิบายถึงไวยากรณ์ต่าง ๆ ของmkpasswdคำสั่งที่มีอยู่ใน Debian (และ Ubuntu)

ในการตรวจสอบด้วยตนเองว่าสตริงนั้นเป็นรหัสผ่านของผู้ใช้จริง ๆ หรือไม่คุณจะต้องแฮชมันด้วยอัลกอริธึมการแฮชแบบเดียวกับในรายการเงาของผู้ใช้ด้วยเกลือเดียวกันกับในรายการเงาของผู้ใช้ จากนั้นสามารถเปรียบเทียบกับแฮรหัสผ่านที่เก็บไว้ที่นั่น

ฉันได้เขียนสคริปต์การทำงานที่สมบูรณ์ซึ่งแสดงให้เห็นถึงวิธีการทำสิ่งนี้

  • หากคุณตั้งชื่อchkpassคุณสามารถเรียกใช้และจะอ่านบรรทัดจากอินพุตมาตรฐานและตรวจสอบว่าเป็นรหัสผ่านหรือไม่chkpass useruser
  • ติดตั้งแพ็คเกจwhois ติดตั้ง whoisเพื่อรับmkpasswdยูทิลิตี้ที่สคริปต์นี้ใช้
  • สคริปต์นี้ต้องถูกเรียกใช้ในฐานะรูท
  • ก่อนที่จะใช้สคริปต์นี้หรือส่วนใดส่วนหนึ่งของสคริปต์เพื่อใช้งานได้จริงโปรดดูSecurity Notesด้านล่าง
#!/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ยอมรับข้อมูลเกลือสคริปต์นี้มีข้อบกพร่องด้านความปลอดภัยที่รู้จักซึ่งคุณอาจหรืออาจจะไม่ได้รับการพิจารณาขึ้นอยู่กับกรณีการใช้งาน ตามค่าเริ่มต้นผู้ใช้บน Ubuntu และระบบ GNU / Linux อื่น ๆ ส่วนใหญ่สามารถดูข้อมูลเกี่ยวกับกระบวนการที่ดำเนินการโดยผู้ใช้รายอื่น (รวมถึงรูท) รวมถึงอาร์กิวเมนต์บรรทัดคำสั่ง ไม่มีการป้อนข้อมูลของผู้ใช้หรือรหัสผ่านแฮชที่เก็บไว้เป็นอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรมอรรถประโยชน์ภายนอก แต่เกลือที่ถูกแยกออกมาจากshadowฐานข้อมูลนั้นถูกกำหนดให้เป็นอาร์กิวเมนต์บรรทัดคำสั่งmkpasswdเนื่องจากนี่เป็นวิธีเดียวที่ยูทิลิตี้ยอมรับเกลือเป็นอินพุต

ถ้า

  • ผู้ใช้รายอื่นในระบบหรือ
  • ทุกคนที่มีความสามารถในการสร้างบัญชีผู้ใช้ (เช่นwww-data) เรียกใช้รหัสของพวกเขาหรือ
  • ทุกคนที่สามารถดูข้อมูลเกี่ยวกับกระบวนการทำงาน (รวมถึงโดยการตรวจสอบรายการด้วยตนเอง/proc)

สามารถตรวจสอบอาร์กิวเมนต์บรรทัดคำสั่งได้mkpasswdเนื่องจากสคริปต์นี้รันจากนั้นพวกเขาสามารถรับสำเนาเกลือของผู้ใช้จากshadowฐานข้อมูล พวกเขาอาจต้องเดาได้เมื่อคำสั่งนั้นรัน แต่บางครั้งก็สามารถทำได้

ผู้โจมตีด้วยเกลือของคุณไม่ได้เลวร้ายเท่ากับผู้โจมตีด้วยเกลือและกัญชาของคุณแต่ก็ไม่เหมาะ เกลือไม่ได้ให้ข้อมูลที่เพียงพอสำหรับบางคนในการค้นหารหัสผ่านของคุณ แต่จะอนุญาตให้บางคนสร้างตารางเรนโบว์หรือพจนานุกรมที่คำนวณล่วงหน้าสำหรับผู้ใช้นั้นในระบบนั้น นี้เป็นครั้งแรกที่ไร้ค่า แต่ถ้าความปลอดภัยของคุณถูกบุกรุกในภายหลังและกัญชาเต็มรูปแบบจะได้รับแล้วมันอาจจะแตกได้รวดเร็วยิ่งขึ้นที่จะได้รับรหัสผ่านของผู้ใช้ก่อนที่พวกเขาจะได้รับโอกาสที่จะเปลี่ยนมัน

ดังนั้นข้อบกพร่องด้านความปลอดภัยนี้จึงเป็นปัจจัยที่ทวีความรุนแรงยิ่งขึ้นในสถานการณ์การโจมตีที่มีความซับซ้อนมากกว่าที่จะเป็นช่องโหว่ที่มีช่องโหว่ และคุณอาจพิจารณาสถานการณ์ข้างต้นอย่างลึกซึ้ง แต่ฉันลังเลที่จะแนะนำวิธีการใด ๆ สำหรับการใช้งานทั่วไปและในโลกแห่งความเป็นจริงที่รั่วไหลข้อมูลที่ไม่ใช่ข้อมูลสาธารณะใด ๆ/etc/shadowสู่ผู้ใช้ที่ไม่ใช่รูท

คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดย:

  • เป็นส่วนหนึ่งของการเขียนสคริปต์ของคุณใน Perl หรือภาษาอื่น ๆ ที่ช่วยให้คุณสามารถเรียกใช้ฟังก์ชัน C เป็นแสดงให้เห็นในคำตอบของ Gillesเพื่อคำถาม Unix.SE ที่เกี่ยวข้อง , หรือ
  • เขียนสคริปต์ / โปรแกรมทั้งหมดของคุณในภาษาดังกล่าวแทนที่จะใช้ทุบตี (ขึ้นอยู่กับวิธีที่คุณติดแท็กคำถามดูเหมือนว่าคุณต้องการใช้ bash)

ระวังวิธีที่คุณเรียกสคริปต์นี้

ถ้าคุณอนุญาตให้ผู้ใช้ที่ไม่น่าเชื่อถือในการเรียกใช้สคริปต์นี้เป็นรากหรือเรียกใช้กระบวนการใด ๆ ที่เป็นรากที่เรียกสคริปต์นี้ต้องระวัง โดยการเปลี่ยนสภาพแวดล้อมที่พวกเขาสามารถทำสคริปต์นี้ - หรือใด ๆสคริปต์ที่วิ่งเป็นราก - ทำอะไร นอกจากว่าคุณจะสามารถป้องกันไม่ให้สิ่งนี้เกิดขึ้นคุณต้องไม่อนุญาตให้ผู้ใช้ยกระดับสิทธิ์สำหรับการเรียกใช้เชลล์สคริปต์

ดู10.4 ภาษาสคริปต์ Shell (sh และ csh Derivatives)ใน David A. Wheeler ของSecure Programming สำหรับ Linux และ Unix HOWTOสำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ ในขณะที่การนำเสนอของเขามุ่งเน้นไปที่สคริปต์ setuid กลไกอื่น ๆ อาจตกเป็นเหยื่อของปัญหาเดียวกันบางอย่างหากพวกเขาไม่ทำความสะอาดสภาพแวดล้อมอย่างถูกต้อง

หมายเหตุอื่น ๆ

สนับสนุนการอ่านแฮชจากshadowฐานข้อมูลเท่านั้น

รหัสผ่านจะต้องมีเงาเพื่อให้สคริปต์นี้ทำงาน (เช่นแฮชควรอยู่ใน/etc/shadowไฟล์แยกต่างหากที่มีเพียงรูทเท่านั้นที่สามารถอ่านไม่ใช่ใน/etc/passwd)

นี่ควรเป็นกรณีใน Ubuntu เสมอ ในกรณีใด ๆ หากจำเป็นสคริปต์ที่สามารถขยายได้นิด ๆ ในการอ่านรหัสผ่าน hashes จากเช่นเดียวกับpasswdshadow

โปรดทราบIFSเมื่อแก้ไขสคริปต์นี้

ผมตั้งที่จุดเริ่มต้นตั้งแต่สามข้อมูลในฟิลด์กัญชาของรายการเงาจะถูกคั่นด้วยIFS=$$

  • พวกเขายังมีชั้นนำ$ซึ่งเป็นสาเหตุที่ประเภทกัญชาและเกลือ"${ent[1]}"และ"${ent[2]}"มากกว่า"${ent[0]}"และ"${ent[1]}"ตามลำดับ

ที่เดียวในสคริปต์นี้ที่$IFSกำหนดว่าเชลล์แยกหรือรวมคำต่างๆอย่างไร

  • เมื่อข้อมูลเหล่านี้ถูกแบ่งออกเป็นอาร์เรย์โดยการเริ่มต้นจากการ$( )ทดแทนคำสั่งunquote ใน:

    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') คุณอาจท้ายทำให้สคริปต์ของคุณทำงานในรูปแบบที่ดูแปลก ๆ


8

คุณสามารถใช้sudoสิ่งนี้ในทางที่ผิด sudoมี-lตัวเลือกสำหรับทดสอบสิทธิ์ sudo ที่ผู้ใช้มีและ-Sสำหรับอ่านรหัสผ่านจาก stdin อย่างไรก็ตามไม่ว่าผู้ใช้จะมีสิทธิ์ระดับใดหากผ่านการตรวจสอบสิทธิ์สำเร็จแล้วsudoจะกลับมาที่สถานะออก 0 ดังนั้นคุณสามารถใช้สถานะการออกอื่น ๆ เพื่อระบุว่าการรับรองความถูกต้องใช้งานไม่ได้ (สมมติว่าsudoตัวเองไม่มีปัญหาใด ๆ เช่น ข้อผิดพลาดในการอนุญาตหรือsudoersการกำหนดค่าไม่ถูกต้อง)

สิ่งที่ต้องการ:

#! /bin/bash
IFS= read -rs PASSWD
sudo -k
if sudo -lS &> /dev/null << EOF
$PASSWD
EOF
then
    echo 'Correct password.'
else 
    echo 'Wrong password.'
fi

สคริปต์นี้ขึ้นอยู่กับการsudoersกำหนดค่าค่อนข้างน้อย ฉันถือว่าการตั้งค่าเริ่มต้น สิ่งที่สามารถทำให้เกิดความล้มเหลว:

  • targetpwหรือrunaspwมีการตั้งค่า
  • listpw คือ never
  • เป็นต้น

ปัญหาอื่น ๆ ได้แก่ (ขอบคุณ Eliah):

  • ความพยายามที่ไม่ถูกต้องจะเข้าสู่ระบบ /var/log/auth.log
  • sudoจะต้องเรียกใช้ในฐานะผู้ใช้ที่คุณกำลังตรวจสอบความถูกต้อง หากคุณไม่มีsudoสิทธิ์ใช้งานเพื่อให้สามารถใช้sudo -u foo sudo -lSงานได้หมายความว่าคุณจะต้องเรียกใช้สคริปต์ในฐานะผู้ใช้เป้าหมาย

ตอนนี้เหตุผลที่ฉันใช้ที่นี่เอกสารคือการขัดขวางการดักฟัง ตัวแปรที่ใช้เป็นส่วนหนึ่งของบรรทัดคำสั่งจะถูกเปิดเผยได้ง่ายขึ้นโดยการใช้topหรือpsเครื่องมืออื่น ๆ เพื่อตรวจสอบกระบวนการ


2
วิธีนี้ดูดีมาก แม้ว่ามันจะไม่ทำงานบนระบบที่มีการตั้งค่าที่ผิดปกติsudo(ตามที่คุณพูด) และกลุ่มที่/var/log/auth.logมีการบันทึกของความพยายามแต่ละครั้ง แต่นี่เป็นวิธีที่รวดเร็วง่ายและใช้ยูทิลิตี้ที่มีอยู่แทนที่จะใช้ล้อเลื่อน (เพื่อพูด) ผมขอแนะนำการตั้งค่าIFS=สำหรับการreadเพื่อป้องกันไม่ให้ประสบความสำเร็จสำหรับการป้อนข้อมูลที่ผิดพลาดของผู้ใช้และไม่ใช่เบาะรหัสผ่านช่องว่างเบาะเช่นเดียวกับความล้มเหลวผิดพลาดสำหรับการป้อนข้อมูลของผู้ใช้ช่องว่างเบาะเบาะและรหัสผ่าน (โซลูชันของฉันมีข้อบกพร่องที่คล้ายกัน) คุณอาจต้องการอธิบายว่าต้องใช้งานอย่างไรเมื่อผู้ใช้ที่กำลังตรวจสอบรหัสผ่าน
Eliah Kagan

@EliahKagan ความพยายามที่ล้มเหลวแต่ละครั้งถูกบันทึกไว้ แต่ใช่คุณพูดถูกทุกอย่าง
muru

การรับรองความถูกต้องที่ประสบความสำเร็จจะถูกบันทึกด้วย sudo -lทำให้รายการถูกเขียนด้วย " COMMAND=list" Btw (ไม่เกี่ยวข้อง) ในขณะที่มันไม่เป็นการดีกว่าที่จะทำเช่นนั้นการใช้สตริงที่นี่แทนเอกสารที่นี่จะบรรลุเป้าหมายความปลอดภัยเดียวกันและมีขนาดกะทัดรัดกว่า เนื่องจากสคริปต์ใช้ bashisms อยู่แล้วread -sและการ&>ใช้if sudo -lS &>/dev/null <<<"$PASSWD"; thenจึงไม่สามารถพกพาได้ ฉันไม่แนะนำให้คุณเปลี่ยนสิ่งที่คุณมี (มันก็โอเค) ค่อนข้างฉันพูดถึงมันเพื่อให้ผู้อ่านรู้ว่าพวกเขามีตัวเลือกนี้เช่นกัน
Eliah Kagan

@EliahKagan อา ฉันคิดว่าsudo -lปิดใช้งานบางอย่าง - อาจเป็นการรายงานเมื่อผู้ใช้พยายามเรียกใช้คำสั่งที่ไม่ได้รับอนุญาต
muru

@EliahKagan แน่นอน ฉันได้ใช้herestrings ว่าวิธีการก่อน ฉันทำงานหนักภายใต้ความเข้าใจผิดที่นี่ซึ่งนำไปสู่ ​​heredocs แต่แล้วฉันก็ตัดสินใจที่จะเก็บไว้
muru

4

อีกวิธีหนึ่ง (น่าสนใจมากกว่าสำหรับเนื้อหาเชิงทฤษฎีมากกว่าการใช้งานจริง)

/etc/shadowรหัสผ่านของผู้ใช้จะถูกเก็บไว้ใน

รหัสผ่านที่เก็บไว้ที่นี่จะถูกเข้ารหัสในล่าสุดรุ่น Ubuntu SHA-512ใช้

SHA-512โดยเฉพาะเมื่อมีการสร้างรหัสผ่านรหัสผ่านในข้อความที่ชัดเจนจะเค็มและการเข้ารหัสผ่าน

วิธีแก้ปัญหาหนึ่งก็คือเกลือ / เข้ารหัสรหัสผ่านที่กำหนดและจับคู่กับรหัสผ่านของผู้ใช้ที่เข้ารหัสที่เก็บไว้ใน/etc/shadowรายการของผู้ใช้ที่ได้รับ

หากต้องการให้รายละเอียดการแบ่งรหัสผ่านอย่างรวดเร็วในแต่ละ/etc/shadowรายการผู้ใช้นี่เป็นตัวอย่าง/etc/shadowรายการสำหรับผู้ใช้ที่fooมีรหัสผ่านbar:

foo:$6$lWS1oJnmDlaXrx1F$h4vuzZVBwIE1Z6vT7N.spwbxYig9e/OHOIH.VDv9JPaC3.OtTusPFzma7g.R/oSZFW5QOI7IDdDY01G0zTGQE/:16566:0:99999:7:::
  • foo: ชื่อผู้ใช้
  • 6: ประเภทการเข้ารหัสของรหัสผ่าน
  • lWS1oJnmDlaXrx1F: เกลือเข้ารหัสของรหัสผ่าน
  • h4vuzZVBwIE1Z6vT7N.spwbxYig9e/OHOIH.VDv9JPaC3.OtTusPFzma7g.R/oSZFW5QOI7IDdDY01G0zTGQE/: SHA-512รหัสผ่านเค็ม / เข้ารหัส

เพื่อให้ตรงกับรหัสผ่านที่กำหนดbarสำหรับผู้ใช้ที่ได้รับfooสิ่งแรกที่ต้องทำคือรับเกลือ:

$ sudo getent shadow foo | cut -d$ -f3
lWS1oJnmDlaXrx1F

จากนั้นหนึ่งควรได้รับรหัสผ่านเค็ม / เข้ารหัสเต็มรูปแบบ:

$ sudo getent shadow foo | cut -d: -f2
$6$lWS1oJnmDlaXrx1F$h4vuzZVBwIE1Z6vT7N.spwbxYig9e/OHOIH.VDv9JPaC3.OtTusPFzma7g.R/oSZFW5QOI7IDdDY01G0zTGQE/

จากนั้นรหัสผ่านที่กำหนดสามารถถูกใส่เกลือ / เข้ารหัสและจับคู่กับรหัสผ่านของผู้ใช้ที่ใส่เกลือ / เข้ารหัสที่เก็บไว้ใน/etc/shadow:

$ python -c 'import crypt; print crypt.crypt("bar", "$6$lWS1oJnmDlaXrx1F")'
$6$lWS1oJnmDlaXrx1F$h4vuzZVBwIE1Z6vT7N.spwbxYig9e/OHOIH.VDv9JPaC3.OtTusPFzma7g.R/oSZFW5QOI7IDdDY01G0zTGQE/

พวกเขาตรงกัน! ทุกอย่างใส่ลงในbashสคริปต์:

#!/bin/bash

read -p "Username >" username
IFS= read -p "Password >" password
salt=$(sudo getent shadow $username | cut -d$ -f3)
epassword=$(sudo getent shadow $username | cut -d: -f2)
match=$(python -c 'import crypt; print crypt.crypt("'"${password}"'", "$6$'${salt}'")')
[ ${match} == ${epassword} ] && echo "Password matches" || echo "Password doesn't match"

เอาท์พุท:

$ ./script.sh 
Username >foo
Password >bar
Password matches
$ ./script.sh 
Username >foo
Password >bar1
Password doesn't match

1
sudo getent shadowsudo grep ...>> เป็นอย่างอื่นดี นี่คือสิ่งที่ฉันคิดในตอนแรกแล้วก็ขี้เกียจเกินไป
muru

@muru ขอบคุณ แน่นอนรู้สึกดีกว่าอัปเดตมาก แต่ก็ยังฉันไม่แน่ใจว่าในกรณีนี้getent+ grep+ cut> grep+cut
kos

1
จี๊ด getentสามารถทำการค้นหาให้คุณได้ ฉันใช้เสรีภาพในการแก้ไข
muru

@muru ใช่แล้วคุณควรจะมีจริงตอนนี้ฉันเห็นจุด!
kos

2
ฉันคิดว่านี่เป็นจริงมากแม้ว่าฉันอาจจะลำเอียง: เป็นวิธีเดียวกับที่ฉันใช้ การนำไปใช้และการนำเสนอของคุณแตกต่างกันมาก - นี่เป็นคำตอบที่มีค่าอย่างแน่นอน ในขณะที่ฉันเคยmkpasswdสร้างแฮชจากการป้อนข้อมูลของผู้ใช้และเกลือที่มีอยู่ (และรวมถึงคุณสมบัติเพิ่มเติมและการวินิจฉัย) คุณได้เขียนโปรแกรม Python อย่างง่ายที่ใช้การmkpasswdทำงานที่สำคัญที่สุดและใช้สิ่งนั้น ผมขอแนะนำให้คุณตั้งค่าIFS=เมื่ออ่านใส่รหัสผ่านและใบเสนอราคา${password}ด้วย"ดังนั้นความพยายามในการใช้รหัสผ่านที่มีช่องว่างไม่ทำลายสคริปต์
Eliah Kagan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.