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 ได้ทำลายความเข้ากันได้แบบย้อนหลังซึ่งจะหยุดการนำเข้าฟังก์ชั่นด้วย.
หรือ:
หรือ/
ในชื่อ สิ่งเหล่านั้นยังสามารถถูกประกาศได้ด้วยการทุบตีซึ่งทำให้พฤติกรรมที่ไม่สอดคล้องกัน เนื่องจากฟังก์ชั่นที่มี.
และ:
ชื่อใช้กันทั่วไปจึงมีโอกาสที่โปรแกรมแก้ไขจะเรียกคืนการยอมรับอย่างน้อยฟังก์ชันจากสภาพแวดล้อม
ทำไมไม่พบก่อนหน้านี้
นั่นเป็นสิ่งที่ฉันสงสัยด้วย ฉันสามารถอธิบายได้สองสามข้อ
ก่อนอื่นฉันคิดว่าถ้านักวิจัยด้านความปลอดภัย (และฉันไม่ใช่นักวิจัยด้านความปลอดภัยระดับมืออาชีพ) ได้ค้นหาช่องโหว่ในการทุบตีโดยเฉพาะพวกเขาน่าจะพบว่าเป็นไปได้
ตัวอย่างเช่นหากฉันเป็นนักวิจัยด้านความปลอดภัยแนวทางของฉันอาจเป็น:
- ดูว่า
bash
รับข้อมูลจากที่ไหนและทำอะไรกับมัน และสภาพแวดล้อมเป็นสิ่งที่ชัดเจน
- ดูว่าสถานที่ใดที่
bash
ล่ามถูกเรียกใช้และข้อมูลใด อีกครั้งมันจะโดดเด่น
- การนำเข้าฟังก์ชั่นที่ส่งออกเป็นหนึ่งในคุณสมบัติที่ถูกปิดการใช้งานเมื่อ
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) มักจะอยู่ในใจของพวกเขาและผู้พัฒนาเชลล์อาจขอแก้ตัวได้ว่าซอฟต์แวร์ของเขาไม่น่าจะถูกโจมตีจากเครือข่าย