ช่องโหว่ใน OpenSMTPD ที่อนุญาตให้เรียกใช้โค้ดจากระยะไกลในฐานะรูท

ในเมลเซิร์ฟเวอร์ที่พัฒนาโดยโครงการ OpenBSD เปิดSMTPD ระบุ ช่องโหว่ที่สำคัญ (CVE-2020-7247) ที่อนุญาตให้คุณเรียกใช้คำสั่งเชลล์จากระยะไกลบนเซิร์ฟเวอร์ที่มีสิทธิ์ของผู้ใช้ระดับรูท ช่องโหว่ดังกล่าวถูกระบุระหว่างการตรวจสอบซ้ำที่ดำเนินการโดย Qualys Security (การตรวจสอบ OpenSMTPD ก่อนหน้านี้ ถูกจัดขึ้น ในปี 2015 และพบช่องโหว่ใหม่ตั้งแต่เดือนพฤษภาคม 2018) ปัญหา ถูกกำจัด ในการเปิดตัว OpenSMTPD 6.6.2 ผู้ใช้ทุกคนควรติดตั้งการอัปเดตอย่างเร่งด่วน (สำหรับ OpenBSD สามารถติดตั้งแพตช์ผ่าน syspatch)

มีการเสนอการโจมตีสองประเภท ตัวเลือกแรกทำงานในการกำหนดค่าเริ่มต้นของ OpenSMTPD (รับคำขอจาก localhost เท่านั้น) และอนุญาตให้คุณใช้ประโยชน์จากปัญหาในเครื่อง เมื่อผู้โจมตีสามารถเข้าถึงอินเทอร์เฟซเครือข่ายท้องถิ่น (วนกลับ) บนเซิร์ฟเวอร์ (เช่น บนระบบโฮสต์) . ตัวเลือกที่สองปรากฏขึ้นเมื่อมีการกำหนดค่า OpenSMTPD ให้ยอมรับคำขอเครือข่ายภายนอก (เซิร์ฟเวอร์อีเมลที่ยอมรับอีเมลของบุคคลที่สาม) นักวิจัยได้เตรียมช่องโหว่ต้นแบบที่ประสบความสำเร็จทั้งกับตัวแปร OpenSMTPD จาก OpenBSD 6.6 และเวอร์ชันพกพาสำหรับระบบปฏิบัติการอื่น (ดำเนินการในการทดสอบ Debian)

ปัญหาเกิดจากข้อผิดพลาดในฟังก์ชัน smtp_mailaddr() ซึ่งถูกเรียกใช้เพื่อตรวจสอบความถูกต้องของค่าในช่อง "MAIL FROM" และ "RCPT TO" ที่กำหนดผู้ส่ง / ผู้รับและถูกส่งระหว่างการเชื่อมต่อ ไปยังเมลเซิร์ฟเวอร์ ฟังก์ชัน smtp_mailaddr() ถูกเรียกใช้ใน smtp_mailaddr() เพื่อตรวจสอบส่วนของที่อยู่อีเมลที่อยู่ก่อนหน้าอักขระ "@"
valid_localpart() ซึ่งถือว่าอักขระ "!#$%&'*/?^`{|}~+-=_" ได้รับอนุญาต (MAILADDR_ALLOWED) ตามที่ RFC 5322 กำหนด

ในกรณีนี้ สตริงจะถูก Escape โดยตรงในฟังก์ชัน mda_expand_token() ซึ่งจะแทนที่เฉพาะอักขระ "!#$%&'*?`{|}~" (MAILADDR_ESCAPE) นอกจากนี้ สตริงที่เตรียมใน mda_expand_token() จะใช้เมื่อเรียกตัวแทนการจัดส่ง (MDA) โดยใช้คำสั่ง 'execle("/bin/sh", "/bin/sh", "-c", mda_command,…' ไปที่ mbox ผ่าน /bin/sh บรรทัด "/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}" จะทำงาน โดยที่ค่า "%{mbox.from}" รวมถึงข้อมูลที่หลีกหนีจากพารามิเตอร์ "MAIL FROM"

สาระสำคัญของช่องโหว่นี้คือ smtp_mailaddr() มีข้อผิดพลาดเชิงตรรกะ ซึ่งหากมีการส่งผ่านโดเมนว่างไปยังอีเมล ฟังก์ชันจะส่งคืนรหัสยืนยันที่สำเร็จ แม้ว่าส่วนของที่อยู่ก่อนหน้า “@” จะมีอักขระที่ไม่ถูกต้องก็ตาม นอกจากนี้ เมื่อเตรียมสตริงด้วยฟังก์ชัน mda_expand_token() อักขระพิเศษของเชลล์ที่เป็นไปได้ทั้งหมดอาจไม่สามารถหนีได้ แต่จะอนุญาตให้ใช้เฉพาะอักขระพิเศษในที่อยู่อีเมลเท่านั้น ดังนั้น ในการเรียกใช้คำสั่งของคุณ เพียงใช้สัญลักษณ์ ";" ในส่วนท้องถิ่นของอีเมลก็เพียงพอแล้ว และช่องว่างซึ่งไม่ได้อยู่ในชุด MAILADDR_ESCAPE และไม่ถูก Escape ตัวอย่างเช่น:

$nc 127.0.0.1 25

HELO ศาสตราจารย์ฟาลเคน
จดหมายจาก:<;sleep 66;>
RCPT ถึง:
DATA
.
เลิก

หลังจากเซสชันนี้ OpenSMTPD เมื่อส่งไปยัง mbox จะเรียกใช้คำสั่งผ่านเชลล์

/usr/libexec/mail.local -f ;sleep 66; ราก

ในเวลาเดียวกัน ความเป็นไปได้ในการโจมตีถูกจำกัดด้วยข้อเท็จจริงที่ว่าส่วนท้องถิ่นของที่อยู่ต้องไม่เกิน 64 อักขระ และอักขระพิเศษ '$' และ '|' จะถูกแทนที่ด้วย ":" เมื่อทำการ Escape เพื่อหลีกเลี่ยงข้อจำกัดนี้ ข้อเท็จจริงที่ว่าเนื้อความของข้อความจะถูกส่งหลังจากรัน /usr/libexec/mail.local ผ่านอินพุตสตรีม เช่น คุณสามารถเรียกใช้ตัวแปลคำสั่ง sh และใช้เนื้อหาของจดหมายเป็นชุดคำสั่งได้โดยการจัดการกับที่อยู่ เนื่องจากมีการระบุส่วนหัวของบริการ SMTP ที่จุดเริ่มต้นของจดหมาย จึงแนะนำให้ใช้การเรียกใช้คำสั่ง read ในลูปเพื่อข้ามไป การหาประโยชน์จากการทำงานมีลักษณะดังนี้:

$nc 192.168.56.143 25

HELO ศาสตราจารย์ฟาลเคน
MAIL FROM:<;for i ใน 0 1 2 3 4 5 6 7 8 9 abcd;do read r;done;sh;exit 0;>
RCPT ถึง:[ป้องกันอีเมล]>
DATA
#0
#1
...
#d
สำหรับฉันใน WOPR; ทำ
echo -n "($i)" && id || หยุดพัก
เสร็จแล้ว > /root/x."`id -u`"."$$"
.
เลิก

ที่มา: opennet.ru

เพิ่มความคิดเห็น