Để trấn an một vài người, tôi đã không tìm thấy lỗi bằng cách quan sát các khai thác, tôi không có lý do gì để tin rằng nó đã bị khai thác trước khi được tiết lộ (mặc dù dĩ nhiên tôi không thể loại trừ được). Tôi cũng không tìm thấy nó bằng cách xem bash
mã của nó.
Tôi không thể nói rằng tôi nhớ chính xác những suy nghĩ của tôi tại thời điểm đó.
Điều đó ít nhiều đến từ một số phản ánh về một số hành vi của một số phần mềm tôi thấy nguy hiểm (các hành vi, không phải phần mềm). Loại hành vi khiến bạn suy nghĩ: điều đó không có vẻ là một ý tưởng tốt .
Trong trường hợp này, tôi đã phản ánh về cấu hình chung của ssh cho phép truyền các biến môi trường không được xác nhận từ máy khách với điều kiện tên của chúng bắt đầu bằng LC_
. Ý tưởng là để mọi người có thể tiếp tục sử dụng ngôn ngữ của chính họ khi ssh
đi vào các máy khác. Một ý tưởng tốt cho đến khi bạn bắt đầu xem xét việc xử lý nội địa hóa phức tạp như thế nào, đặc biệt là khi UTF-8 được đưa vào phương trình (và xem nó được xử lý tệ như thế nào bởi nhiều ứng dụng).
Trở lại vào tháng 7 năm 2014, tôi đã báo cáo một lỗ hổng trong việc xử lý nội địa hóa glibc kết hợp với sshd
cấu hình đó và hai hành vi nguy hiểm khác của trình bash
bao
cho phép kẻ tấn công (xác thực) tấn công vào máy chủ git miễn là chúng có thể tải lên các tệp ở đó và bash
được sử dụng là vỏ đăng nhập của người dùng git unix (CVE-2014-0485).
Tôi đã nghĩ rằng có lẽ đó là một ý tưởng tồi khi sử dụng bash
làm vỏ đăng nhập của người dùng cung cấp dịch vụ qua ssh, vì nó khá phức tạp (khi tất cả những gì bạn cần chỉ là phân tích một dòng lệnh rất đơn giản) và đã thừa hưởng hầu hết các lỗi sai của ksh. Vì tôi đã xác định được một vài vấn đề bash
khi sử dụng trong bối cảnh đó (để giải thích ssh ForceCommand
s), tôi đã tự hỏi liệu có khả năng nào hơn ở đó không.
AcceptEnv LC_*
cho phép bất kỳ biến nào có tên bắt đầu LC_
và tôi có một hồi ức mơ hồ rằng các bash
hàm xuất (một tính năng nguy hiểm mặc dù có tính năng hữu ích tại thời điểm đó) đang sử dụng các biến môi trường có tên giống như vậy
myfunction()
và tự hỏi liệu có gì thú vị để xem ở đó không.
Tôi đã định loại bỏ nó rằng điều tồi tệ nhất mà người ta có thể làm là xác định lại một lệnh được gọi là LC_something
không thực sự là vấn đề vì chúng không phải là tên lệnh hiện có, nhưng sau đó tôi bắt đầu tự hỏi làm thế nào bash
nhập các biến môi trường đó.
Điều gì xảy ra nếu các biến được gọi là LC_foo;echo test; f()
ví dụ? Vì vậy, tôi quyết định có một cái nhìn gần hơn.
A:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
tiết lộ rằng hồi ức của tôi đã sai ở chỗ các biến không được gọi myfunction()
nhưng myfunction
(và đó là
giá trị bắt đầu bằng ()
).
Và một bài kiểm tra nhanh:
$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for `true;echo test; f'
xác nhận sự nghi ngờ của tôi rằng tên biến không được khử trùng và mã được đánh giá khi khởi động .
Tệ hơn, tệ hơn rất nhiều, giá trị cũng không được khử trùng:
$ env 'foo=() { :;}; echo test' bash -c :
test
Điều đó có nghĩa là bất kỳ biến môi trường nào cũng có thể là một vectơ.
Đó là khi tôi nhận ra mức độ của vấn đề, đã xác nhận rằng nó cũng có thể khai thác qua HTTP ( HTTP_xxx
/ QUERYSTRING
... env vars), những cái khác như dịch vụ xử lý thư, sau này là DHCP (và có thể là một danh sách dài) và báo cáo nó (một cách cẩn thận) .