Đây là lệnh tôi đã sử dụng để kiểm tra shell bash của mình để tìm lỗi Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Bất cứ ai có thể xin vui lòng giải thích các lệnh chi tiết?
Đây là lệnh tôi đã sử dụng để kiểm tra shell bash của mình để tìm lỗi Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Bất cứ ai có thể xin vui lòng giải thích các lệnh chi tiết?
Câu trả lời:
Câu trả lời này là một dẫn xuất của một bài viết gốc trên Tạp chí Fedora của Matthew Miller, được cấp phép theo giấy phép Creative Commons Attribution-Share Alike 4.0 .
Hãy để tôi giải thích:
env x='() { :;}; echo OOPS' bash -c :
Điều này sẽ in ra OOPS 'trên một hệ thống dễ bị tấn công, nhưng thoát ra một cách im lặng nếu bash đã được vá.
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Điều này sẽ in ra OOPS 'trên một hệ thống dễ bị tấn công, nhưng in “this is a test”
nếu bash đã được vá.
Và có lẽ bạn đã nghe nói rằng nó có liên quan đến các biến môi trường. Nhưng, tại sao mã trong các biến môi trường được thực thi? Chà, đáng ra không phải vậy - nhưng, vì một tính năng mà tôi muốn gọi là quá thông minh vì lợi ích của chính nó, có một số chỗ cho một lỗ hổng. Bash là những gì bạn thấy như một dấu nhắc thiết bị đầu cuối, nhưng nó cũng là một ngôn ngữ kịch bản và có khả năng xác định các chức năng. Bạn làm như thế này:
$ Ubuntu() { echo "Ubuntu is awesome."; }
và sau đó bạn có một lệnh mới. Hãy nhớ rằng echo
ở đây chưa thực sự chạy; nó chỉ được lưu như những gì sẽ xảy ra khi chúng ta chạy lệnh mới. Điều này sẽ quan trọng trong một phút!
$ Ubuntu
Ubuntu is awesome.
Hữu ích! Nhưng, giả sử, vì một số lý do, chúng ta cần thực thi một phiên bản mới của bash, như là một quy trình con và muốn chạy lệnh mới tuyệt vời của tôi theo đó. Câu lệnh bash -c somecommand
thực hiện chính xác điều này: chạy lệnh đã cho trong shell mới:
$ bash -c Ubuntu
bash: Ubuntu: command not found
Ôi. Buồn. Đứa trẻ không kế thừa định nghĩa hàm. Nhưng, nó vốn là môi trường - một tập hợp các cặp khóa-giá trị đã được xuất từ trình bao. (Đây là một khái niệm hoàn toàn mới; nếu bạn chưa quen với điều này, hãy tin tôi ngay bây giờ.) Và, hóa ra, bash cũng có thể xuất các hàm. Vì thế:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
Đó là tất cả tốt và tốt - ngoại trừ cơ chế mà điều này được thực hiện là tinh ranh . Về cơ bản, vì không có phép thuật Linux / Unix để thực hiện các chức năng trong các biến môi trường, nên hàm xuất thực sự chỉ tạo ra một biến môi trường thông thường có chứa định nghĩa hàm. Sau đó, khi lớp vỏ thứ hai đọc môi trường vào đến của Edward và gặp một biến có nội dung trông giống như một hàm, nó sẽ đánh giá nó.
Về lý thuyết, điều này là hoàn toàn an toàn , bởi vì, hãy nhớ, xác định một chức năng không thực sự thực hiện nó . Ngoại trừ - và đây là lý do tại sao chúng tôi ở đây - có một lỗi trong mã nơi đánh giá không dừng lại khi kết thúc định nghĩa hàm. Nó chỉ kepts đi.
Điều đó sẽ không bao giờ xảy ra khi hàm được lưu trữ trong một biến môi trường được tạo ra một cách hợp pháp, với export -f
. Nhưng, tại sao lại hợp pháp? Kẻ tấn công có thể tạo ra bất kỳ biến môi trường cũ nào, và nếu nó trông giống như một hàm, các bash shell mới sẽ nghĩ như vậy!
Vì vậy, trong ví dụ đầu tiên của chúng tôi:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Các env
lệnh chạy một lệnh với một bộ biến nhất định. Trong trường hợp này, chúng tôi đang thiết lập x
một cái gì đó trông giống như một chức năng. Hàm này chỉ là một lệnh đơn :
, đây thực sự là một lệnh đơn giản được định nghĩa là không làm gì cả. Nhưng sau đó, sau khi semi-colon
báo hiệu kết thúc định nghĩa hàm, có một echo
lệnh. Điều đó không được phép ở đó, nhưng không có gì ngăn cản chúng tôi làm điều đó.
Sau đó, lệnh được đưa ra để chạy với môi trường mới này là một bash shell mới, một lần nữa với lệnh echo this is a test
điều chỉnh hoặc điều không làm gì :
, sau đó nó sẽ thoát ra, hoàn toàn vô hại.
Nhưng - ôi! Khi lớp vỏ mới đó khởi động và đọc môi trường, nó sẽ đến x
biến và vì nó trông giống như một hàm, nên nó đánh giá nó. Định nghĩa hàm được tải vô hại - và sau đó tải trọng độc hại của chúng tôi cũng được kích hoạt. Vì vậy, nếu bạn chạy phần trên trên một hệ thống dễ bị tấn công, bạn sẽ được “OOPS”
in lại cho bạn. Hoặc, một kẻ tấn công có thể làm điều tồi tệ hơn nhiều so với chỉ in những thứ.
env
không cần thiết. Bạn có thể nhận được kết quả tương tự (đạt / không phụ thuộc vào việc Bash đã được cập nhật hay chưa) bằng cách sử dụng lệnh mà không có nó : x='() { :;}; echo OOPS' bash -c "echo this is a test"
. Điều này là do trước một lệnh có gán biến sẽ chuyển biến đó và giá trị của nó vào bash -c "..."
môi trường của lệnh ( trong trường hợp này).
env
có cần thiết hay không được xác định bởi lớp vỏ mà người ta chạy thử, không phải lớp vỏ đang được thử. (Chúng có thể giống nhau. Ngay cả khi đó, chúng tôi đang kiểm tra cách bash xử lý môi trường của chính nó .) Các kiểu vỏ Bourne chấp nhận NAME=value command
cú pháp; Vỏ kiểu C (ví dụ csh
, tcsh
) không. Vì vậy, bài kiểm tra có tính di động cao hơn một chút env
(với chi phí đôi khi tạo ra sự nhầm lẫn về cách thức hoạt động).
Trong phiên bản chưa được vá củabash
nó lưu trữ các định nghĩa hàm xuất dưới dạng các biến môi trường.
Lưu trữ một chức năng x
như,
$ x() { bar; }
$ export -f x
Và kiểm tra định nghĩa của nó là,
$ env | grep -A1 x
x=() { bar
}
Vì vậy, người ta có thể khai thác điều này bằng cách xác định các biến môi trường của riêng mình và diễn giải chúng như các định nghĩa hàm. Ví dụ env x='() { :;}'
sẽ được coi là
x() { :;
}
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Từ man env
,
env
- chạy một chương trình trong một môi trường sửa đổi.
:
không làm gì ngoài lối thoát với trạng thái thoát 0
. xem thêm
Khi một phiên bản mới của bash chưa được khởi chạy là bash -c "echo this is a test"
, biến môi trường được tạo ra được coi là một hàm và được tải. Theo đó, người ta nhận được đầu ra
dễ bị tổn thương đây là một bài kiểm tra
Lưu ý: Tiếng vang bên ngoài định nghĩa chức năng đã được thực hiện bất ngờ trong quá trình khởi động bash. Định nghĩa hàm chỉ là một bước để đánh giá và khai thác xảy ra, chính định nghĩa hàm và biến môi trường được sử dụng là tùy ý. Shell nhìn vào các biến môi trường, thấy x, trông giống như nó đáp ứng các ràng buộc mà nó biết về định nghĩa hàm trông như thế nào và nó đánh giá dòng, vô tình cũng thực hiện echo (có thể là bất kỳ lệnh nào, độc hại hay không) . Cũng thấy điều này
env test='() { echo "anything"; }' bash -c "echo otherthing"
bạn sẽ thấy ở đầu ra otherthing
. Điều đó được sửa chữa trong bản vá. cảm thấy tự do nếu tôi vẫn không rõ ràng.
unpatched bash
bạn có thể gọi hàm như được định nghĩa, nhưng trong một bản vá bash
, định nghĩa không có ở đó.
echo vulnerable
) không được thực thi. Lưu ý rằng trong các bản vá mới nhất, hàm đã qua phải có tiền tố cụ thể ( env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test"
). Một số bản vá gần đây có thể sử dụng %%
thay vì đầu tiên ()
.