TL; DR
Lỗ hổng shellshock được sửa hoàn toàn trong
- Trên nhánh bash-2.05b: 2.05b.10 trở lên (bao gồm bản vá 10)
- Trên nhánh bash-3.0: 3.0.19 trở lên (bao gồm bản vá 19)
- Trên nhánh bash-3.1: 3.1.20 trở lên (bao gồm bản vá 20)
- Trên nhánh bash-3.2: 3.2.54 trở lên (bao gồm bản vá 54)
- Trên nhánh bash-4.0: 4.0.41 trở lên (bao gồm bản vá 41)
- Trên nhánh bash-4.1: 4.1,14 trở lên (bao gồm bản vá 14)
- Trên nhánh bash-4.2: 4.2.50 trở lên (bao gồm bản vá 50)
- Trên nhánh bash-4.3: 4.3.27 trở lên (bao gồm bản vá 27)
Nếu bash của bạn hiển thị phiên bản cũ hơn, nhà cung cấp hệ điều hành của bạn vẫn có thể tự vá nó, vì vậy tốt nhất là kiểm tra.
Nếu như:
env xx='() { echo vulnerable; }' bash -c xx
cho thấy "dễ bị tổn thương", bạn vẫn dễ bị tổn thương. Đó là thử nghiệm duy nhất có liên quan (cho dù trình phân tích cú pháp bash vẫn tiếp xúc với mã trong bất kỳ biến môi trường nào ).
Chi tiết.
Lỗi là trong việc thực hiện ban đầu của hàm xuất khẩu / nhập khẩu được giới thiệu trên 5 ngày của tháng 8 năm 1989 bởi Brian Fox, và lần đầu tiên được phát hành vào bash-1,03 khoảng một tháng sau đó tại một thời điểm mà bash là không sử dụng rộng rãi như vậy, trước khi an ninh đó là rất nhiều mối quan tâm và HTTP và web hoặc Linux thậm chí còn tồn tại.
Từ ChangeLog trong 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.
Một số cuộc thảo luận trong gnu.bash.orms và comp.unix.questions vào khoảng thời gian đó cũng đề cập đến tính năng này.
Thật dễ hiểu làm thế nào nó đạt được điều đó.
bash xuất các hàm trong env vars như
foo=() {
code
}
Và khi nhập khẩu, tất cả những gì phải làm là giải thích rằng với sự =
thay thế bằng một khoảng trắng ... ngoại trừ việc nó không nên diễn giải một cách mù quáng.
Nó cũng bị hỏng trong đó bash
(trái với vỏ Bourne), các biến và hàm vô hướng có một không gian tên khác nhau. Thật ra nếu bạn có
foo() { echo bar; }; export -f foo
export foo=bar
bash
sẽ vui vẻ đặt cả hai vào môi trường (có các mục có cùng tên biến) nhưng nhiều công cụ (bao gồm nhiều shell) sẽ không truyền bá chúng.
Người ta cũng sẽ tranh luận rằng bash nên sử dụng BASH_
tiền tố không gian tên cho điều đó vì các vv env chỉ liên quan từ bash đến bash. rc
sử dụng fn_
tiền tố cho một tính năng tương tự.
Một cách tốt hơn để thực hiện nó là đặt định nghĩa của tất cả các biến được xuất trong một biến như:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Điều đó vẫn cần phải được vệ sinh nhưng ít nhất điều đó không thể khai thác nhiều hơn $BASH_ENV
hoặc $SHELLOPTS
...
Có một bản vá ngăn không cho bash
giải thích bất cứ điều gì khác ngoài định nghĩa hàm trong đó ( https://lists.gnu.org/archive/html/orms-bash/2014-09/msg00081.html ) và đó là bản vá có đã được áp dụng trong tất cả các bản cập nhật bảo mật từ các bản phân phối Linux khác nhau.
Tuy nhiên, bash vẫn diễn giải mã trong đó và bất kỳ lỗi nào trong trình thông dịch có thể bị khai thác. Một lỗi như vậy đã được tìm thấy (CVE-2014-7169) mặc dù tác động của nó nhỏ hơn rất nhiều. Vì vậy, sẽ có một bản vá khác đến sớm.
Cho đến khi một bản sửa lỗi cứng ngăn bash diễn giải mã theo bất kỳ biến nào (như sử dụng cách BASH_FUNCDEFS
tiếp cận ở trên), chúng tôi sẽ không biết chắc chắn nếu chúng tôi không dễ bị lỗi từ trình phân tích cú pháp bash. Và tôi tin rằng sẽ có một bản sửa lỗi cứng như vậy được phát hành sớm hay muộn.
Chỉnh sửa 2014-09-28
Hai lỗi bổ sung trong trình phân tích cú pháp đã được tìm thấy (CVE-2014-718 {6,7}) (lưu ý rằng hầu hết các shell bị ràng buộc có lỗi trong trình phân tích cú pháp của chúng cho các trường hợp góc, điều đó sẽ không gây lo ngại nếu trình phân tích cú pháp đó không xảy ra 'T đã được tiếp xúc với dữ liệu không đáng tin cậy).
Trong khi cả 3 lỗi 7169, 7186 và 7187 đã được sửa trong các bản vá sau, Red Hat đã cố gắng khắc phục sự cố. Trong bản vá của họ, họ đã thay đổi hành vi để các chức năng được xuất ra trong các biến được gọi là BASH_FUNC_myfunc()
quyết định thiết kế của Chet ít nhiều.
Chet sau đó đã xuất bản bản sửa lỗi đó như là một bản vá bash ngược dòng chính thức .
Bản vá cứng đó, hoặc các biến thể của nó hiện có sẵn cho hầu hết các bản phân phối Linux lớn và cuối cùng được chuyển sang Apple OS / X.
Điều đó hiện gây lo ngại cho bất kỳ env var tùy ý khai thác trình phân tích cú pháp thông qua vectơ đó bao gồm hai lỗ hổng khác trong trình phân tích cú pháp (CVE-2014-627 {7,8}) được tiết lộ sau đó bởi Michał Zalewski (CVE-2014-6278 tệ như CVE-2014-6271) rất may sau khi hầu hết mọi người đã có thời gian để cài đặt bản vá cứng
Lỗi trong trình phân tích cú pháp cũng sẽ được sửa, nhưng chúng không còn là vấn đề nữa khi trình phân tích cú pháp không còn dễ dàng tiếp xúc với đầu vào không tin cậy.
Lưu ý rằng mặc dù lỗ hổng bảo mật đã được khắc phục, có khả năng chúng ta sẽ thấy một số thay đổi trong khu vực đó. Bản sửa lỗi ban đầu cho CVE-2014-6271 đã phá vỡ tính tương thích ngược ở chỗ nó dừng nhập các hàm có .
hoặc :
hoặc /
trong tên của chúng. Những người vẫn có thể được tuyên bố bằng bash mặc dù điều đó tạo ra một hành vi không nhất quán. Vì các hàm có .
và :
trong tên của chúng thường được sử dụng, nên có khả năng một bản vá sẽ khôi phục chấp nhận ít nhất là các hàm từ môi trường.
Tại sao nó không được tìm thấy sớm hơn?
Đó cũng là điều tôi băn khoăn. Tôi có thể đưa ra một vài lời giải thích.
Đầu tiên, tôi nghĩ rằng nếu một nhà nghiên cứu bảo mật (và tôi không phải là nhà nghiên cứu bảo mật chuyên nghiệp) đã đặc biệt tìm kiếm các lỗ hổng trong bash, thì họ có thể đã tìm thấy nó.
Ví dụ, nếu tôi là một nhà nghiên cứu bảo mật, cách tiếp cận của tôi có thể là:
- Nhìn vào nơi
bash
nhận đầu vào và những gì nó làm với nó. Và môi trường là một điều hiển nhiên.
- Nhìn vào những nơi mà trình
bash
thông dịch được gọi và trên dữ liệu nào. Một lần nữa, nó sẽ nổi bật.
- Việc nhập các hàm được xuất là một trong những tính năng bị vô hiệu hóa khi
bash
được setuid / setgid, làm cho nó trở thành một nơi thậm chí rõ ràng hơn để xem xét.
Bây giờ, tôi nghi ngờ không ai nghĩ rằng bash
(người phiên dịch) là một mối đe dọa, hoặc mối đe dọa đó có thể xảy ra theo cách đó.
Trình bash
thông dịch không có nghĩa là xử lý đầu vào không tin cậy.
Các kịch bản Shell (không phải trình thông dịch) thường được xem xét kỹ từ quan điểm bảo mật. Cú pháp shell rất khó xử và có rất nhiều cảnh báo khi viết các tập lệnh đáng tin cậy (từng thấy tôi hoặc người khác đề cập đến toán tử split + global hoặc tại sao bạn nên trích dẫn các biến chẳng hạn?) Đến nỗi khá phổ biến để tìm lỗ hổng bảo mật trong các tập lệnh xử lý dữ liệu không đáng tin cậy.
Đó là lý do tại sao bạn thường nghe rằng bạn không nên viết tập lệnh shell CGI hoặc tập lệnh setuid bị vô hiệu hóa trên hầu hết các Thông báo. Hoặc bạn nên hết sức cẩn thận khi xử lý tệp trong các thư mục có thể ghi trên thế giới ( ví dụ: xem CVE-2011-0441 ).
Trọng tâm là ở chỗ, các kịch bản shell chứ không phải trình thông dịch.
Bạn có thể tiếp xúc với một thông dịch viên vỏ để dữ liệu không tin cậy (ăn dữ liệu nước ngoài như mã shell để giải thích) thông qua eval
hoặc .
hoặc gọi nó trên người sử dụng cung cấp tác phẩm, nhưng sau đó bạn không cần một lỗ hổng trong bash
khai thác nó. Một điều khá rõ ràng là nếu bạn chuyển dữ liệu không được xác nhận cho một trình bao để giải thích, nó sẽ diễn giải nó.
Vì vậy, vỏ được gọi trong bối cảnh đáng tin cậy. Nó được cung cấp các tập lệnh cố định để diễn giải và thường xuyên hơn không (vì rất khó để viết các tập lệnh đáng tin cậy) để xử lý dữ liệu.
Chẳng hạn, trong ngữ cảnh web, một shell có thể được gọi trong một cái gì đó như:
popen("sendmail -oi -t", "w");
Điều gì có thể xảy ra với điều đó? Nếu có gì đó sai được dự kiến, đó là về dữ liệu được cung cấp cho sendmail đó, chứ không phải cách dòng lệnh shell đó được phân tích cú pháp hoặc dữ liệu bổ sung nào được cung cấp cho shell đó. Không có lý do gì bạn muốn xem xét các biến môi trường được truyền vào shell đó. Và nếu bạn làm như vậy, bạn sẽ nhận ra tất cả các vars env có tên bắt đầu bằng "HTTP_" hoặc các vars CGI nổi tiếng như SERVER_PROTOCOL
hoặc QUERYSTRING
không có cái vỏ hay sendmail nào có liên quan.
Trong bối cảnh độ cao đặc quyền như khi chạy setuid / setgid hoặc thông qua sudo, môi trường thường được xem xét và có rất nhiều lỗ hổng trong quá khứ, một lần nữa không chống lại chính vỏ mà chống lại những thứ nâng cao các đặc quyền như sudo
(ví dụ CVE -2011-3628 ).
Chẳng hạn, bash
không tin tưởng vào môi trường khi setuid hoặc được gọi bởi lệnh setuid ( mount
ví dụ, hãy gọi người trợ giúp). Đặc biệt, nó bỏ qua các chức năng xuất khẩu.
sudo
làm sạch môi trường: tất cả theo mặc định trừ một danh sách trắng, và nếu cấu hình không, tại danh sách đen ít nhất một vài mà được biết là ảnh hưởng đến một vỏ này hay cách khác (như PS4
, BASH_ENV
, SHELLOPTS
...). Nó cũng đưa vào danh sách đen các biến môi trường có nội dung bắt đầu bằng ()
(đó là lý do tại sao CVE-2014-6271 không cho phép leo thang đặc quyền thông qua sudo
).
Nhưng một lần nữa, đó là bối cảnh nơi môi trường không thể tin cậy: bất kỳ biến nào với bất kỳ tên và giá trị nào đều có thể được đặt bởi người dùng độc hại trong bối cảnh đó. Điều đó không áp dụng cho máy chủ web / ssh hoặc tất cả các vectơ khai thác CVE-2014-6271 nơi môi trường được kiểm soát (ít nhất là tên của các biến môi trường được kiểm soát ...)
Điều quan trọng là chặn một biến như echo="() { evil; }"
, nhưng không HTTP_FOO="() { evil; }"
, bởi vì HTTP_FOO
sẽ không được gọi là lệnh bởi bất kỳ tập lệnh shell hoặc dòng lệnh nào. Và apache2 là không bao giờ để thiết lập một echo
hoặc BASH_ENV
biến.
Rõ ràng là một số biến môi trường nên được liệt kê đen trong một số ngữ cảnh dựa trên tên của chúng , nhưng không ai nghĩ rằng chúng nên được liệt kê đen dựa trên nội dung của chúng (ngoại trừ sudo
). Hay nói cách khác, không ai nghĩ rằng các env tùy ý có thể là một vectơ cho việc tiêm mã.
Về việc liệu thử nghiệm mở rộng khi tính năng được thêm vào có thể bắt được nó hay không, tôi muốn nói là không thể.
Khi bạn kiểm tra tính năng , bạn kiểm tra chức năng. Các chức năng hoạt động tốt. Nếu bạn xuất hàm trong một lệnh bash
gọi, nó sẽ được nhập vào một lệnh khác. Một thử nghiệm rất kỹ lưỡng có thể đã phát hiện ra các vấn đề khi cả một biến và hàm có cùng tên được xuất hoặc khi hàm được nhập ở một ngôn ngữ khác với ngôn ngữ được xuất.
Nhưng để có thể phát hiện ra lỗ hổng, đây không phải là một bài kiểm tra chức năng mà bạn phải làm. Khía cạnh bảo mật sẽ phải là trọng tâm chính và bạn sẽ không kiểm tra chức năng, nhưng cơ chế và cách nó có thể bị lạm dụng.
Đó không phải là điều mà các nhà phát triển (đặc biệt là vào năm 1989) thường có trong đầu và một nhà phát triển hệ vỏ có thể được miễn là nghĩ rằng phần mềm của anh ta khó có thể khai thác được mạng.