มีการแนะนำข้อผิดพลาด shellshock (CVE-2014-6271 / 7169) เมื่อใดและแพตช์ที่แก้ไขได้อย่างสมบูรณ์คืออะไร


122

บริบทบางอย่างเกี่ยวกับข้อผิดพลาด: CVE-2014-6271

Bash รองรับการส่งออกไม่เพียง แต่ตัวแปรของเชลล์เท่านั้น แต่ยังทำหน้าที่ของเชลล์ไปยังอินสแตนซ์ของ bash อื่น ๆ ผ่านสภาวะแวดล้อมกระบวนการไปยังกระบวนการลูก (โดยอ้อม) เวอร์ชัน bash ปัจจุบันใช้ตัวแปรสภาพแวดล้อมที่ตั้งชื่อตามชื่อฟังก์ชันและนิยามฟังก์ชันที่ขึ้นต้นด้วย“ () {”) ในค่าตัวแปรเพื่อเผยแพร่นิยามฟังก์ชันผ่านสภาพแวดล้อม ช่องโหว่เกิดขึ้นเนื่องจาก bash ไม่หยุดทำงานหลังจากประมวลผลคำจำกัดความฟังก์ชัน มันยังคงแยกวิเคราะห์และรันคำสั่งเชลล์ตามนิยามฟังก์ชัน ตัวอย่างเช่นการตั้งค่าตัวแปรสภาพแวดล้อมของ

  VAR=() { ignored; }; /bin/id

จะดำเนินการ / bin / id เมื่อสภาพแวดล้อมถูกนำเข้าสู่กระบวนการทุบตี

ที่มา: http://seclists.org/oss-sec/2014/q3/650

ข้อผิดพลาดถูกนำมาใช้เมื่อใดและตัวแก้ไขที่แก้ไขได้อย่างสมบูรณ์คืออะไร (ดูCVE-2014-7169 )

รุ่นที่มีช่องโหว่นอกเหนือจากที่ระบุไว้ใน CVE (ตอนแรก) (3. {0..2} และ 4 {0..3}) คืออะไร

มีการใช้ซอร์สโค้ด buggy ในโครงการอื่นหรือไม่?

ต้องการข้อมูลเพิ่มเติม


ที่เกี่ยวข้อง: env x = '() {:;}; ทุบตีคำสั่งทำและทำไมมันไม่ปลอดภัย?


อีกบทความที่ดีเขียนได้ที่: access.redhat.com/articles/1200223
Greg Bray

คำตอบ:


206

TL; DR

ช่องโหว่ shellshock ได้รับการแก้ไขแล้ว

  • ในสาขา bash-2.05b: 2.05b.10 และสูงกว่า (รวม 10 แพทช์)
  • ในสาขา bash-3.0: 3.0.19 ขึ้นไป (รวมอยู่ในแพทช์ 19)
  • ในสาขา bash-3.1: 3.1.20 และสูงกว่า (รวมชุดข้อมูลแก้ไข 20)
  • ในสาขา bash-3.2: 3.2.54 ขึ้นไป (รวมอยู่ในชุด patch 54)
  • ในสาขา bash-4.0: 4.0.41 ขึ้นไป (รวมอยู่ในแพตช์ 41)
  • ในสาขา bash-4.1: 4.1.14 ขึ้นไป (รวมอยู่ในแพทช์ 14)
  • ในสาขา bash-4.2: 4.2.50 ขึ้นไป (รวม 50 patch)
  • บนสาขา bash-4.3: 4.3.27 ขึ้นไป (รวม 27 แพทช์)

หาก bash ของคุณแสดงเวอร์ชั่นที่เก่ากว่าผู้จำหน่ายระบบปฏิบัติการของคุณอาจยังคงได้ทำการแก้ไขด้วยตัวเองดังนั้นสิ่งที่ดีที่สุดคือการตรวจสอบ

ถ้า:

env xx='() { echo vulnerable; }' bash -c xx

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

รายละเอียด

ข้อผิดพลาดอยู่ในการดำเนินการเริ่มต้นของฟังก์ชั่นการส่งออก / นำเข้าแนะนำให้รู้จักกับ 5 วันของเดือนสิงหาคมปี 1989 โดยไบรอันฟ็อกซ์และเปิดตัวครั้งแรกในทุบตี-1.03 ประมาณหนึ่งเดือนต่อมาในเวลาที่ทุบตีไม่ได้อยู่ในการใช้อย่างแพร่หลายเช่นก่อนที่การรักษาความปลอดภัย เป็นเรื่องที่น่ากังวลและ HTTP และเว็บหรือลีนุกซ์ก็ยังมีอยู่

จากChangeLog ใน 1.05 :

Fri Sep  1 18:52:08 1989  Brian Fox  (bfox at aurel)

       * readline.c: rl_insert ().  Optimized for large amounts
         of typeahead.  Insert all insertable characters at once.

       * I update this too irregularly.
         Released 1.03.
[...]
Sat Aug  5 08:32:05 1989  Brian Fox  (bfox at aurel)

       * variables.c: make_var_array (), initialize_shell_variables ()
         Added exporting of functions.

การสนทนาบางอย่างในgnu.bash.bugและcomp.unix.questions ในช่วงเวลานั้นยังกล่าวถึงคุณลักษณะ

มันง่ายที่จะเข้าใจว่ามันไปถึงที่นั่นได้อย่างไร

bash ส่งออกฟังก์ชันใน env vars like

foo=() {
  code
}

และในการนำเข้าสิ่งที่ต้องทำก็คือตีความว่า=แทนที่ด้วยช่องว่าง ... ยกเว้นว่าไม่ควรตีความมันแบบสุ่ม

นอกจากนี้ยังแตกในที่bash(ตรงกันข้ามกับเชลล์เป้าหมาย) ตัวแปรสเกลาร์และฟังก์ชั่นมีชื่อพื้นที่แตกต่างกัน จริง ๆ แล้วถ้าคุณมี

foo() { echo bar; }; export -f foo
export foo=bar

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

หนึ่งอาจโต้แย้งว่าทุบตีควรใช้BASH_คำนำหน้า namespace สำหรับที่เป็นที่ env vars เฉพาะที่เกี่ยวข้องจากทุบตีเพื่อทุบตี rcใช้fn_คำนำหน้าสำหรับคุณสมบัติที่คล้ายกัน

วิธีที่ดีกว่าในการใช้มันจะต้องใส่นิยามของตัวแปรที่ส่งออกทั้งหมดในตัวแปรเช่น:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

ยังคงต้องมีการฆ่าเชื้อ แต่อย่างน้อยก็ไม่สามารถเอาเปรียบได้มากกว่า$BASH_ENVหรือ$SHELLOPTS...

มีโปรแกรมแก้ไขที่ป้องกันไม่ให้bashแปลสิ่งอื่นนอกเหนือจากคำจำกัดความของฟังก์ชั่นในนั้น ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ) และนั่นเป็นโปรแกรมที่มี ถูกนำไปใช้ในการปรับปรุงความปลอดภัยทั้งหมดจากลีนุกซ์รุ่นต่างๆ

อย่างไรก็ตามทุบตียังคงตีความรหัสในนั้นและข้อผิดพลาดใด ๆ ในล่ามสามารถใช้ประโยชน์ได้ พบข้อผิดพลาดหนึ่งอย่างแล้ว (CVE-2014-7169) แม้ว่าผลกระทบของมันจะเล็กกว่ามาก ดังนั้นจะมีอีกปะในเร็ว ๆ นี้

จนกว่าจะแก้ไขการชุบแข็งที่ป้องกันการทุบตีตีความรหัสในตัวแปรใด ๆ (เช่นการใช้BASH_FUNCDEFSวิธีการข้างต้น) เราจะไม่ทราบแน่นอนว่าถ้าเราไม่เสี่ยงจากข้อผิดพลาดในตัวแยกวิเคราะห์ bash และฉันเชื่อว่าจะมีการแก้ไขที่ชุบแข็งออกมาไม่ช้าก็เร็ว

แก้ไข 2014-09-28

พบข้อบกพร่องเพิ่มเติมสองตัวใน parser (CVE-2014-718 {6,7}) (โปรดทราบว่ากระสุนส่วนใหญ่จะต้องมีข้อบกพร่องใน parser ของพวกเขาสำหรับกรณีมุม ไม่ได้รับข้อมูลที่ไม่น่าเชื่อถือ)

ในขณะที่ทั้ง 3 ข้อบกพร่อง 7169, 7186 และ 7187 ได้รับการแก้ไขในแพทช์ต่อไปนี้ Red Hat ผลักสำหรับการแก้ไขการชุบแข็ง ในแพทช์ของพวกเขาพวกเขาเปลี่ยนพฤติกรรมเพื่อให้ฟังก์ชั่นถูกส่งออกในตัวแปรที่เรียกว่าBASH_FUNC_myfunc()การตัดสินใจออกแบบของเชษฐ์มากหรือน้อย

ต่อมาเชษฐ์ตีพิมพ์แก้ไขว่าเป็นแพทช์ upstreams ทุบตีอย่างเป็นทางการ

ขณะนี้แพตช์แข็งหรือรุ่นต่างๆนั้นมีให้บริการสำหรับการแจกจ่าย Linux ที่สำคัญที่สุดและในที่สุดก็นำไปใช้กับ Apple OS / X

CVA-2014-627 {7,8}) ซึ่งถูกเปิดเผยในภายหลังโดยMichał Zalewski (CVE-2014-6278 เกือบ ไม่ดีเท่า CVE-2014-6271) ขอบคุณหลังจากคนส่วนใหญ่มีเวลาในการติดตั้งแพทช์ชุบแข็ง

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

โปรดทราบว่าในขณะที่ช่องโหว่ความปลอดภัยได้รับการแก้ไขอาจเป็นไปได้ว่าเราจะเห็นการเปลี่ยนแปลงบางอย่างในพื้นที่นั้น การแก้ไขเบื้องต้นสำหรับ CVE-2014-6271 ได้ทำลายความเข้ากันได้แบบย้อนหลังซึ่งจะหยุดการนำเข้าฟังก์ชั่นด้วย.หรือ:หรือ/ในชื่อ สิ่งเหล่านั้นยังสามารถถูกประกาศได้ด้วยการทุบตีซึ่งทำให้พฤติกรรมที่ไม่สอดคล้องกัน เนื่องจากฟังก์ชั่นที่มี.และ:ชื่อใช้กันทั่วไปจึงมีโอกาสที่โปรแกรมแก้ไขจะเรียกคืนการยอมรับอย่างน้อยฟังก์ชันจากสภาพแวดล้อม

ทำไมไม่พบก่อนหน้านี้

นั่นเป็นสิ่งที่ฉันสงสัยด้วย ฉันสามารถอธิบายได้สองสามข้อ

ก่อนอื่นฉันคิดว่าถ้านักวิจัยด้านความปลอดภัย (และฉันไม่ใช่นักวิจัยด้านความปลอดภัยระดับมืออาชีพ) ได้ค้นหาช่องโหว่ในการทุบตีโดยเฉพาะพวกเขาน่าจะพบว่าเป็นไปได้

ตัวอย่างเช่นหากฉันเป็นนักวิจัยด้านความปลอดภัยแนวทางของฉันอาจเป็น:

  1. ดูว่าbashรับข้อมูลจากที่ไหนและทำอะไรกับมัน และสภาพแวดล้อมเป็นสิ่งที่ชัดเจน
  2. ดูว่าสถานที่ใดที่bashล่ามถูกเรียกใช้และข้อมูลใด อีกครั้งมันจะโดดเด่น
  3. การนำเข้าฟังก์ชั่นที่ส่งออกเป็นหนึ่งในคุณสมบัติที่ถูกปิดการใช้งานเมื่อbashมีการ setuid / setgid ซึ่งทำให้มันเป็นสถานที่ที่มองเห็นได้ชัดเจนยิ่งขึ้น

ตอนนี้ฉันสงสัยว่าไม่มีใครคิดที่จะพิจารณาbash(ล่าม) เป็นภัยคุกคามหรือภัยคุกคามที่อาจเกิดขึ้นได้

bashล่ามไม่ได้หมายถึงการประมวลผลการป้อนข้อมูลที่ไม่น่าเชื่อถือ

เชลล์สคริปต์ (ไม่ใช่ตัวแปลภาษา) มักถูกมองอย่างใกล้ชิดจากมุมมองความปลอดภัย ไวยากรณ์ของเชลล์นั้นน่าอึดอัดใจและมีจำนวน caveats จำนวนมากที่มีการเขียนสคริปต์ที่เชื่อถือได้ (เคยเห็นฉันหรือคนอื่น ๆ ที่พูดถึงตัวแยก + glob หรือทำไมคุณควรอ้างอิงตัวแปรเช่น?) ว่ามันค่อนข้างธรรมดาในการค้นหาช่องโหว่ด้านความปลอดภัย ข้อมูลที่ไม่น่าเชื่อถือ

นั่นเป็นเหตุผลที่คุณมักได้ยินว่าคุณไม่ควรเขียนเชลล์สคริปต์ CGI มิฉะนั้นสคริปต์ setuid จะถูกปิดใช้งานใน Unices ส่วนใหญ่ หรือคุณควรระมัดระวังเป็นพิเศษเมื่อประมวลผลไฟล์ในไดเรกทอรีที่เขียนได้ทั่วโลก (ดูCVE-2011-0441เป็นต้น)

โฟกัสอยู่ตรงนั้นเชลล์สคริปไม่ใช่ล่าม

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

ดังนั้นเชลล์จึงถูกเรียกใช้ในบริบทที่เชื่อถือได้ มันได้รับสคริปต์คงที่ในการตีความและบ่อยครั้งกว่าที่จะไม่ (เพราะมันยากมากที่จะเขียนสคริปต์ที่เชื่อถือได้) ข้อมูลคงที่ในการประมวลผล

ตัวอย่างเช่นในบริบทเว็บเชลล์อาจถูกเรียกใช้ในบางสิ่งเช่น:

popen("sendmail -oi -t", "w");

สิ่งที่อาจผิดไปกับสิ่งนั้น? หากมีการมองเห็นสิ่งผิดปกตินั่นเป็นเรื่องเกี่ยวกับข้อมูลที่ส่งไปยัง sendmail นั้นไม่ใช่วิธีการแยกบรรทัดคำสั่งของเชลล์เองหรือข้อมูลพิเศษใดที่ถูกส่งไปยังเชลล์นั้น ไม่มีเหตุผลที่คุณต้องการพิจารณาตัวแปรสภาพแวดล้อมที่ส่งผ่านไปยังเชลล์นั้น และถ้าคุณทำคุณจะรู้ว่ามันคือ env vars ที่ชื่อขึ้นต้นด้วย "HTTP_" หรือที่รู้จักกันดี CGI env vars เหมือนSERVER_PROTOCOLหรือQUERYSTRINGไม่มีเชลล์หรือ sendmail ที่มีส่วนเกี่ยวข้องกับธุรกิจ

ในบริบทของการยกระดับสิทธิพิเศษเช่นเมื่อใช้ setuid / setgid หรือผ่าน sudo โดยทั่วไปสภาพแวดล้อมจะถูกพิจารณาและมีช่องโหว่มากมายในอดีตไม่ใช่กับตัวเชลล์เอง แต่เทียบกับสิ่งที่ยกระดับสิทธิ์เช่นsudo(ดูตัวอย่างCVE -2011-3628 )

ตัวอย่างเช่นbashไม่เชื่อถือสภาพแวดล้อมเมื่อ setuid หรือเรียกใช้โดยคำสั่ง setuid (คิดว่าmountอินสแตนซ์ที่เรียกใช้ตัวช่วย) โดยเฉพาะอย่างยิ่งมันไม่สนใจฟังก์ชั่นที่ส่งออก

sudoไม่ทำความสะอาดสิ่งแวดล้อม: โดยเริ่มต้นยกเว้นรายการสีขาวและถ้ามีการกำหนดค่าไม่ในรายการสีดำอย่างน้อยไม่กี่คนที่เป็นที่รู้จักกันจะมีผลต่อเปลือกหรืออื่น (เช่นPS4, BASH_ENV, SHELLOPTS... ) นอกจากนี้ยังขึ้นบัญชีดำตัวแปรสภาพแวดล้อมที่เนื้อหาขึ้นต้นด้วย()(ซึ่งเป็นสาเหตุที่ CVE-2014-6271 ไม่อนุญาตให้เพิ่มระดับสิทธิ์ผ่านsudo)

แต่สำหรับบริบทที่ไม่สามารถเชื่อถือได้: ตัวแปรใด ๆ ที่มีชื่อและค่าใด ๆ สามารถตั้งค่าได้โดยผู้ใช้ที่ประสงค์ร้ายในบริบทนั้น ไม่สามารถใช้ได้กับเว็บเซิร์ฟเวอร์ / ssh หรือเวกเตอร์ทั้งหมดที่ใช้ประโยชน์จาก CVE-2014-6271 ที่ควบคุมสภาพแวดล้อม (อย่างน้อยชื่อของตัวแปรสภาพแวดล้อมจะถูกควบคุม ... )

สิ่งสำคัญคือการบล็อกตัวแปรที่ชอบecho="() { evil; }"แต่ไม่ใช่HTTP_FOO="() { evil; }"เพราะHTTP_FOOจะไม่ถูกเรียกว่าเป็นคำสั่งของเชลล์สคริปต์หรือบรรทัดคำสั่ง และ apache2 จะไม่ตั้งค่าechoหรือBASH_ENVตัวแปร

เห็นได้ชัดว่าตัวแปรสภาพแวดล้อมบางอย่างควรมีบัญชีดำในบริบทบางอย่างตามชื่อของพวกเขาแต่ไม่มีใครคิดว่าพวกเขาควรจะเป็นบัญชีดำตามเนื้อหาของพวกเขา(ยกเว้นsudo) หรือในคำอื่น ๆ ไม่มีใครคิดว่า vars env โดยพลการอาจเป็นเวกเตอร์สำหรับการฉีดโค้ด

สำหรับการทดสอบอย่างกว้างขวางว่ามีการเพิ่มฟีเจอร์หรือไม่นั้นฉันอาจกล่าวได้ว่าเป็นไปไม่ได้

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

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

ไม่ใช่สิ่งที่นักพัฒนาซอฟต์แวร์ (โดยเฉพาะในปี 1989) มักจะอยู่ในใจของพวกเขาและผู้พัฒนาเชลล์อาจขอแก้ตัวได้ว่าซอฟต์แวร์ของเขาไม่น่าจะถูกโจมตีจากเครือข่าย


128
PS: คำตอบนี้จากบุคคลที่เดิมค้นพบข้อผิดพลาด :)
ราเมษ

6
@Ben นั่นไม่ใช่คำตอบสำหรับคำถามตรงข้ามใช่ไหม
Doorknob

31
ฉันขอถาม…คุณสะดุดข้อผิดพลาดได้หรือไม่หรือคุณกำลังมองหาข้อบกพร่องใน Bash หรือไม่?
200_success

7
@gerrit เนื่องจากข้อผิดพลาดไม่ทำให้เกิดพฤติกรรมที่ไม่ดีภายใต้สภาวะปกติ เนื่องจากไม่มีอะไรผิดพลาดไม่มีใครดูรหัสอื่นนอกเหนือจากนักวิจัยด้านความปลอดภัยและหมวกดำ
Loren Pechtel

4
@JacekSzymanski จริง แต่ส่วนหัวอื่น ๆ ล่ะ? ส่วนหัวที่กำหนดเองโดยเฉพาะอย่างยิ่ง? (ผู้โจมตีสามารถเพิ่มส่วนหัว X-Exploit-Payload ที่ควรถูกตั้งค่าเป็น HTTP_X_EXPORT_PAYLOAD)
มิถุนายน

19

ตามฐานข้อมูล NVD ที่ NIST ( http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271 ) ทุกรุ่นของ bash จาก 1.14.0 เป็นต้นไปมีความเสี่ยง

RedHat มีลมของข้อผิดพลาดบน14 กันยายน

แพทช์ออกโดย Mr.Ramey (ทุบตีผู้ดูแล) บน ก.ย. 26-2014 การแก้ไขข้อผิดพลาด CVE-2014-7169

ใช้แพทช์เหล่านี้และก่อนหน้านี้ทั้งหมดกับแหล่งทุบตีที่สอดคล้องกัน:


ช่องโหว่เพิ่มเติมในการทุบตี


อีกเล็กน้อยเกี่ยวกับประวัติของข้อผิดพลาด (ความอนุเคราะห์จากmikeserv )

ที่มา: http://www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm

ในปี 1994 Chet Ramey อธิบายว่ามันเป็นตัวกำหนดคุณสมบัติ POSIX 2 เก่าที่ระบุฟังก์ชันส่งออกไว้ หรืออย่างน้อยเขาก็อธิบายกลไกทุบตีว่าทำเช่นนั้น - ไม่ว่าจะเป็นข้อบกพร่องหรือไม่ก็ตอนนี้ฉันไม่รู้ นอกจากนี้เขายังกล่าวถึงการส่งออกฟังก์ชั่นของ rc ในเธรดนั้นด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.