การเผยแพร่ระบบปฏิบัติการแบบโอเพ่นซอร์ส OpenBSD เป็นที่รู้จักกันดีในหมู่ผู้ดูแลระบบ โดยเฉพาะผู้ที่จัดการเซิร์ฟเวอร์ เนื่องจากเน้นไปที่การรักษาความปลอดภัยมากกว่าความเร็ว ฟีเจอร์ และฟรอนต์เอนด์ที่สวยงาม
บางทีโลโก้ของมันคือปลาปักเป้าพองตัว มีเดือยแหลมที่พร้อมจะขับไล่แฮ็กเกอร์เจ้าเล่ห์ที่อาจเข้ามา
แต่ทีม OpenBSD อาจเป็นที่รู้จักกันดีที่สุด ไม่ใช่สำหรับ distro ทั้งหมด แต่สำหรับชุดเครื่องมือการเข้าถึงระยะไกล OpenSSH ที่เขียนขึ้นในช่วงปลายทศวรรษที่ 1990 เพื่อรวมไว้ในระบบปฏิบัติการเอง
SSH ย่อมาจาก เปลือกที่ปลอดภัยเดิมทีสร้างโดยนักวิทยาศาสตร์คอมพิวเตอร์ชาวฟินแลนด์ ทาทู อีโลเนน ในช่วงกลางทศวรรษที่ 1990 ด้วยความหวังที่จะเลิกดูแลระบบจากพฤติกรรมเสี่ยงของการใช้โปรโตคอล Telnet
ปัญหาเกี่ยวกับ Telnet
Telnet นั้นเรียบง่ายและมีประสิทธิภาพอย่างน่าทึ่ง: แทนที่จะเชื่อมต่อสายจริง (หรือใช้โมเด็มผ่านสายโทรศัพท์) เพื่อสร้างการเชื่อมต่อ teletype กับเซิร์ฟเวอร์ระยะไกล คุณใช้การเชื่อมต่อ TELetype NETwork แทน
โดยทั่วไป ข้อมูลที่มักจะไหลไปมาผ่านการเชื่อมต่อแบบอนุกรมหรือสายโทรศัพท์แบบ Dial-Up จะถูกส่งและรับผ่านอินเทอร์เน็ต โดยใช้การเชื่อมต่อเครือข่าย TCP แบบแพ็กเก็ตสลับแทนการเชื่อมโยงแบบจุดต่อจุดแบบสลับวงจร .
ระบบการเข้าสู่ระบบที่คุ้นเคย การเชื่อมต่อที่ถูกกว่า ไม่ต้องใช้สายข้อมูลเฉพาะ!
แน่นอนว่าข้อบกพร่องใหญ่หลวงใน Telnet ก็คือการไม่มีการเข้ารหัส ดังนั้นการดมกลิ่นเซสชันเทอร์มินัลของคุณจึงเป็นเรื่องเล็กน้อย ทำให้แคร็กเกอร์เห็นทุกคำสั่งที่คุณพิมพ์ (แม้แต่ข้อผิดพลาดที่คุณทำ และทุกครั้งที่คุณกด [Backspace]
) และทุกไบต์ของเอาต์พุตที่ผลิต...
…และแน่นอน ชื่อผู้ใช้และรหัสผ่านของคุณเมื่อเริ่มต้นเซสชัน
ใครก็ตามบนเส้นทางเครือข่ายของคุณไม่เพียงแต่สร้างเซสชันดูแลระบบของคุณใหม่ตามเวลาจริงได้อย่างง่ายดายบนหน้าจอของตัวเองเท่านั้น แต่ยังอาจยุ่งกับเซสชันของคุณด้วยการแก้ไขคำสั่งที่คุณส่งไปยังเซิร์ฟเวอร์ระยะไกลและปลอมแปลงการตอบกลับกลับมาโดยที่คุณไม่ทันสังเกต อุบาย
พวกเขาสามารถตั้งค่าเซิร์ฟเวอร์แอบอ้าง หลอกล่อคุณ และทำให้คุณสังเกตเห็นการหลอกลวงได้ยากอย่างน่าประหลาดใจ
FTW การเข้ารหัสที่แข็งแกร่ง
SSH ของ Ylönen มีเป้าหมายเพื่อเพิ่มชั้นของการเข้ารหัสและการพิสูจน์ตัวตนที่รัดกุมในแต่ละจุดสิ้นสุดของเซสชันที่คล้าย Telnet ซึ่งสร้าง เปลือกที่ปลอดภัย (นั่นคือชื่อย่อของชื่อ หากคุณเคยสงสัย แม้ว่าเกือบทุกคนจะเรียกมันว่า ess-ess-aitch วันนี้).
มันเป็นที่นิยมในทันที และโปรโตคอลก็ถูกนำมาใช้อย่างรวดเร็วโดย sysadmins ทุกหนทุกแห่ง
ในไม่ช้า OpenSSH ก็ตามมา ดังที่เราได้กล่าวไว้ข้างต้น โดยปรากฏตัวครั้งแรกในปลายปี 1999 โดยเป็นส่วนหนึ่งของ โอเพ่นบีเอสดี 2.6 ปล่อย
ทีมงาน OpenBSD ต้องการสร้างโปรโตคอลโอเพ่นซอร์สฟรี เชื่อถือได้ และใช้งานได้จริง คนอื่นสามารถใช้โดยไม่มีความยุ่งยากในการออกใบอนุญาตหรือเชิงพาณิชย์ใด ๆ ที่ขัดขวางการดำเนินการดั้งเดิมของ Ylönen ในช่วงหลายปีหลังจากเปิดตัว
แน่นอน หากคุณเรียกใช้เซิร์ฟเวอร์ Windows SSH และเชื่อมต่อจากคอมพิวเตอร์ Linux ในตอนนี้ คุณจะต้องพึ่งพาการใช้งาน OpenSSH ที่ปลายทั้งสองด้านอย่างแน่นอน
โปรโตคอล SSH ยังใช้ในบริการไคลเอ็นต์-เซิร์ฟเวอร์ยอดนิยมอื่นๆ เช่น SCP และ SFTP ซึ่งย่อมาจาก สำเนาที่ปลอดภัย และ FTP ที่ปลอดภัย ตามลำดับ SSH มีความหมายอย่างหลวมๆ ว่า “เชื่อมต่ออย่างปลอดภัยและเรียกใช้คำสั่ง SHell ที่ปลายอีกด้านหนึ่ง” โดยทั่วไปแล้วสำหรับการเข้าสู่ระบบแบบโต้ตอบ เนื่องจากโปรแกรม Unix สำหรับเชลล์คำสั่งมักจะ /bin/sh
. SCP นั้นคล้ายกัน แต่สำหรับไฟล์ CoPying เนื่องจากคำสั่ง Unix file-copy นั้นถูกเรียกโดยทั่วไป /bin/cp
และ SFTP ได้รับการตั้งชื่อในลักษณะเดียวกัน
OpenSSH ไม่ใช่ชุดเครื่องมือ SSH เดียวในเมือง
การใช้งานที่รู้จักกันดีอื่น ๆ ได้แก่ : libssh2สำหรับนักพัฒนาที่ต้องการสร้างการสนับสนุน SSH ในแอปพลิเคชันของตนเอง ดรอปแบร์เซิร์ฟเวอร์ SSH ที่ถอดแบบมาจากโปรแกรมเขียนโค้ดของออสเตรเลีย แมตต์ จอห์นสัน ซึ่งพบได้ทั่วไปบนอุปกรณ์ที่เรียกว่า IoT (Internet of Things) เช่น เราเตอร์ที่บ้านและเครื่องพิมพ์ และ ฉาบคอลเล็กชันเครื่องมือที่เกี่ยวข้องกับ SSH สำหรับ Windows ยอดนิยมฟรีจากนักพัฒนาโอเพ่นซอร์สอินดี้ ไซม่อน ทาทาม ในประเทศอังกฤษ.
แต่ถ้าคุณเป็นผู้ใช้ SSH เป็นประจำ คุณเกือบจะได้เชื่อมต่อกับเซิร์ฟเวอร์ OpenSSH อย่างน้อยหนึ่งเซิร์ฟเวอร์แล้วในปัจจุบัน ไม่น้อยเพราะลีนุกซ์รุ่นใหม่ส่วนใหญ่รวมเซิร์ฟเวอร์นี้เป็นเครื่องมือการเข้าถึงระยะไกลมาตรฐาน และ Microsoft ก็มีทั้งไคลเอนต์ OpenSSH และ OpenSSH เซิร์ฟเวอร์เป็นส่วนประกอบ Windows อย่างเป็นทางการในทุกวันนี้
แก้ไขข้อผิดพลาดฟรีสองเท่า
OpenSSH เวอร์ชัน 9.2 เพิ่งออกมาและ บันทึกประจำรุ่น รายงานดังนี้
รุ่นนี้มีการแก้ไขสำหรับ […] ปัญหาความปลอดภัยของหน่วยความจำ [ข้อบกพร่องนี้] ไม่เชื่อว่าจะนำไปใช้ประโยชน์ได้ แต่เรารายงานข้อผิดพลาดของหน่วยความจำที่เข้าถึงเครือข่ายได้ส่วนใหญ่เป็นข้อบกพร่องด้านความปลอดภัย
ข้อผิดพลาดส่งผลกระทบต่อ sshd
, เซิร์ฟเวอร์ OpenSSH (the -d
ต่อท้ายย่อมาจาก ภูต, ชื่อ Unix สำหรับประเภทของกระบวนการพื้นหลังที่ Windows เรียกว่า บริการ):
sshd(8): แก้ไขข้อบกพร่องของหน่วยความจำแบบ double-free ของการรับรองความถูกต้องล่วงหน้าที่แนะนำใน OpenSSH 9.1 สิ่งนี้ไม่เชื่อว่าจะนำไปใช้ประโยชน์ได้ และเกิดขึ้นในกระบวนการตรวจสอบสิทธิ์ล่วงหน้าที่ไม่ได้รับสิทธิพิเศษซึ่งอยู่ภายใต้ chroot(2) และมีการแซนด์บ็อกซ์เพิ่มเติมในแพลตฟอร์มหลักส่วนใหญ่
ข้อผิดพลาดที่ไม่มีสองเท่าหมายความว่าบล็อกหน่วยความจำที่คุณส่งคืนไปยังระบบปฏิบัติการแล้วเพื่อใช้ซ้ำในส่วนอื่น ๆ ของโปรแกรมของคุณ...
…ภายหลังจะถูกส่งคืนอีกครั้งโดยส่วนหนึ่งของโปรแกรมที่ไม่ได้ “เป็นเจ้าของ” หน่วยความจำนั้นอีกต่อไป แต่ไม่รู้ว่าไม่ใช่
(หรือส่งกลับโดยจงใจเมื่อมีการแจ้งโค้ดที่พยายามกระตุ้นข้อบกพร่องโดยเจตนาเพื่อเปลี่ยน ความอ่อนแอ เป็น เอาเปรียบ.)
ซึ่งอาจนำไปสู่จุดบกพร่องที่ละเอียดอ่อนและแก้ไขได้ยาก โดยเฉพาะอย่างยิ่งหากระบบทำเครื่องหมายว่าบล็อกว่างพร้อมใช้งานเมื่อบล็อกแรก free()
เกิดขึ้น, จัดสรรส่วนนั้นให้กับส่วนอื่นของรหัสของคุณในภายหลังเมื่อมันขอหน่วยความจำผ่าน malloc(
) จากนั้นทำเครื่องหมายบล็อกว่างอีกครั้งเมื่อเรียกฟุ่มเฟือยไปที่ free()
ปรากฏ
นั่นทำให้คุณตกอยู่ในสถานการณ์แบบที่คุณพบเมื่อคุณเช็คอินในโรงแรมที่พูดว่า “โอ้ ข่าวดี! เราคิดว่าเราอิ่มแล้ว แต่แขกอีกคนเพิ่งตัดสินใจเช็คเอาท์ก่อนเวลา ดังนั้นคุณจะได้ห้องของพวกเขา”
แม้ว่าห้องจะได้รับการทำความสะอาดอย่างเรียบร้อยและเตรียมพร้อมสำหรับผู้เข้าพักใหม่เมื่อคุณเข้าไป และดูเหมือนว่ามันถูกจัดสรรอย่างเหมาะสมสำหรับการใช้งานพิเศษของคุณ คุณยังคงต้องวางใจได้ว่าคีย์การ์ดของแขกคนก่อนจะถูกยกเลิกอย่างถูกต้อง และพวกเขา “ เช็คเอาต์ก่อนเวลา” ไม่ใช่เล่ห์เหลี่ยมที่จะแอบกลับในวันเดียวกันและขโมยแล็ปท็อปของคุณ
แก้ไขข้อผิดพลาดสำหรับการแก้ไขข้อผิดพลาด
กระแทกแดกดัน หากคุณดูประวัติรหัส OpenSSH ล่าสุด คุณจะเห็นว่า OpenSSH มีข้อผิดพลาดเล็กน้อยในฟังก์ชันที่เรียกว่า compat_kex_proposal()
ใช้เพื่อตรวจสอบว่าอัลกอริทึมการแลกเปลี่ยนคีย์ประเภทใดที่จะใช้เมื่อตั้งค่าการเชื่อมต่อ
แต่การแก้ไขข้อบกพร่องเล็กน้อยนั้นทำให้เกิดช่องโหว่ที่รุนแรงขึ้นแทน
อย่างไรก็ตาม การมีอยู่ของข้อบกพร่องในส่วนหนึ่งของซอฟต์แวร์ที่ใช้ระหว่างการตั้งค่าการเชื่อมต่อเป็นสิ่งที่ทำให้สิ่งนี้เรียกว่า การตรวจสอบสิทธิ์ล่วงหน้าที่เข้าถึงเครือข่ายได้ ช่องโหว่ (หรือ ข้อผิดพลาดก่อนการตรวจสอบสิทธิ์ สั้น ๆ).
ข้อผิดพลาดที่ไม่มีสองเท่าเกิดขึ้นในโค้ดที่ต้องเรียกใช้ หลังจาก ลูกค้าได้เริ่มต้นเซสชันระยะไกล แต่ ก่อน ข้อตกลงเกี่ยวกับคีย์หรือการพิสูจน์ตัวตนใดๆ เกิดขึ้น ดังนั้นในทางทฤษฎีแล้ว ช่องโหว่สามารถถูกกระตุ้นก่อนที่จะมีการแสดงรหัสผ่านหรือคีย์เข้ารหัสใดๆ เพื่อตรวจสอบความถูกต้อง
ใน OpenSSH 9.0 compat_kex_proposal
มีลักษณะดังนี้ (ทำให้ง่ายขึ้นมากที่นี่):
char* compat_kex_proposal(char* suggestion) { if (condition1) { return suggestion; } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { suggestion = allocatenewstring2(); } if (isblank(suggestion)) { error(); } return suggestion; }
แนวคิดคือผู้โทรผ่านบล็อกหน่วยความจำของตนเองซึ่งมีสตริงข้อความแนะนำการตั้งค่าการแลกเปลี่ยนคีย์ และได้รับการอนุมัติให้ใช้คำแนะนำที่พวกเขาส่งมา หรือสตริงข้อความที่จัดสรรใหม่พร้อมคำแนะนำที่อัปเดต .
จุดบกพร่องคือถ้าเงื่อนไข 1 เป็นเท็จ แต่เงื่อนไข 2 และ 3 เป็นจริงทั้งคู่ รหัสจะจัดสรร สอง สตริงข้อความใหม่ แต่จะส่งคืนเท่านั้น หนึ่ง.
บล็อกหน่วยความจำที่จัดสรรโดย allocatenewstring1()
ไม่เคยถูกทำให้ว่าง และเมื่อฟังก์ชันกลับมา ที่อยู่หน่วยความจำจะหายไปตลอดกาล ดังนั้นจึงไม่มีทางที่โค้ดใดๆ จะ free()
ในอนาคต
บล็อกนั้นถูกละทิ้งโดยพื้นฐานแล้วทำให้เกิดสิ่งที่เรียกว่า หน่วยความจำรั่ว.
เมื่อเวลาผ่านไป การดำเนินการนี้อาจทำให้เกิดปัญหา ซึ่งอาจถึงขั้นบังคับให้เซิร์ฟเวอร์ปิดตัวลงเพื่อกู้คืนจากหน่วยความจำที่โอเวอร์โหลด
ใน OpenSSH 9.1 รหัสได้รับการปรับปรุงโดยพยายามหลีกเลี่ยงการจัดสรรสองสตริง แต่ละทิ้งหนึ่งในนั้น:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion){ char* previousone = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { previousone = suggestion; suggestion = allocatenewstring2(); } free(previousone); } if (isblank(suggestion()) { error(); } return suggestion; }
สิ่งนี้มีข้อผิดพลาดแบบ double-free เนื่องจากหากเงื่อนไข 1 และเงื่อนไข 2 เป็นเท็จทั้งคู่ แต่เงื่อนไข 3 เป็นจริง รหัสจะจัดสรรสตริงใหม่เพื่อส่งกลับเป็นคำตอบ...
…แต่ปล่อยสตริงที่ผู้โทรส่งผ่านมาอย่างไม่ถูกต้อง เนื่องจากฟังก์ชัน allocatenewstring1()
ไม่เคยถูกเรียกให้อัพเดตตัวแปร suggestion
.
สตริงคำแนะนำที่ส่งผ่าน เป็นหน่วยความจำที่เป็นของผู้โทรและด้วยเหตุนี้ผู้โทรจะปลดปล่อยธีมอิสระในภายหลัง ซึ่งนำไปสู่อันตรายที่ปราศจากสองเท่า
ใน OpenSSH 9.2 โค้ดมีความระมัดระวังมากขึ้น โดยคอยติดตามบล็อกหน่วยความจำที่เป็นไปได้ทั้งสามบล็อกที่ใช้: ต้นฉบับ suggestion
(หน่วยความจำเป็นของคนอื่น) และสตริงใหม่ที่เป็นไปได้สองรายการที่อาจถูกจัดสรรระหว่างทาง:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion) { char* newone = NULL; char* newtwo = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { newone = allocatenewstring1(); } if (condition3) { newtwo = allocatenewstring2(); } free(newone); newone = newtwo; } if (isblank(newone)) { error(); } return newone; }
หากเงื่อนไข 1 เป็นจริง ระบบจะใช้สำเนาใหม่ของสตริงที่ส่งผ่าน เพื่อให้ผู้โทรสามารถดำเนินการได้ในภายหลัง free()
หน่วยความจำของสตริงที่ส่งผ่านเมื่อใดก็ตามที่พวกเขาต้องการ
ถ้าเราผ่านเงื่อนไข 1 ไปแล้ว และเงื่อนไข 2 เป็นจริง แต่เงื่อนไข 3 เป็นเท็จ คำแนะนำทางเลือกที่สร้างขึ้นโดย allocatenewstring1()
ได้รับคืนและผู้ผ่านเข้า-ออก suggestion
สตริงถูกทิ้งไว้ตามลำพัง
ถ้าเงื่อนไข 2 เป็นเท็จ และเงื่อนไข 3 เป็นจริง สตริงใหม่จะถูกสร้างขึ้นและส่งคืน และส่งผ่านเข้ามา suggestion
สตริงถูกทิ้งไว้ตามลำพัง
ถ้าทั้งเงื่อนไข 2 และเงื่อนไข 3 เป็นจริง สตริงใหม่สองสตริงจะถูกจัดสรรไปพร้อมกัน คนแรกได้รับการปลดปล่อยเพราะไม่จำเป็น อันที่สองจะถูกส่งกลับ และผู้ผ่านเข้ามา suggestion
สตริงถูกทิ้งไว้ตามลำพัง
คุณสามารถ RTxM เพื่อยืนยันว่าถ้าคุณโทร free(newone)
เมื่อ newone
is NULL
จากนั้น "ไม่มีการดำเนินการใดๆ" เนื่องจากปลอดภัยเสมอ free(NULL)
. อย่างไรก็ตาม โปรแกรมเมอร์จำนวนมากยังคงป้องกันอย่างแน่นหนาด้วยโค้ดเช่น if (ptr != NULL) { free(ptr); }
.
จะทำอย่างไร?
ตามที่ทีมงาน OpenSSH แนะนำ การใช้ประโยชน์จากข้อบกพร่องนี้จะเป็นเรื่องยากไม่น้อยเนื่องจากสิทธิ์จำกัดที่ sshd
โปรแกรมได้ในขณะที่กำลังตั้งค่าการเชื่อมต่อเพื่อใช้งาน
อย่างไรก็ตาม พวกเขารายงานว่ามันเป็นช่องโหว่ด้านความปลอดภัยเพราะนั่นคือสิ่งที่มันเป็น ดังนั้นตรวจสอบให้แน่ใจว่าคุณได้อัปเดตเป็น OpenSSH 9.2.
และถ้าคุณเขียนโค้ดด้วยภาษา C จำไว้ว่าไม่ว่าคุณจะมีประสบการณ์แค่ไหน การจัดการหน่วยความจำก็ผิดพลาดได้ง่าย...
…ดังนั้นดูแลที่นั่น
(ใช่ สนิมและเพื่อนสมัยใหม่จะ ช่วยให้คุณเขียนโค้ดที่ถูกต้องแต่บางครั้งคุณก็ยังต้องใช้ C และแม้แต่ Rust ก็ไม่สามารถรับประกันได้ หยุดคุณเขียนรหัสที่ไม่ถูกต้อง หากคุณตั้งโปรแกรมอย่างไม่รอบคอบ!)
- เนื้อหาที่ขับเคลื่อนด้วย SEO และการเผยแพร่ประชาสัมพันธ์ รับการขยายวันนี้
- เพลโตบล็อคเชน Web3 Metaverse ข่าวกรอง ขยายความรู้. เข้าถึงได้ที่นี่.
- ที่มา: https://nakedsecurity.sophos.com/2023/02/03/openssh-fixes-double-free-memory-bug-thats-pokable-over-the-network/