Làm thế nào để `env X = '() {(a) => \' sh -c Nhật ký ngày tháng` `hoạt động như thế nào?


7

Sau khi đọc về bashlỗ hổng mới nhất , tôi đã tự hỏi làm thế nào khai thác của Tavis Ormandy. Làm thế nào để (a)=>\làm việc?

Anh đăng:

Bản vá bash dường như chưa hoàn chỉnh đối với tôi, phân tích chức năng vẫn còn dễ vỡ. ví dụ

$ env X='() { (a)=>\' sh -c "echo date"; cat echo

Tôi đã đoán tại stackoverflow.com/a/26045918/1126841 . Tôi không chắc nó đúng, vì vậy tôi sẽ không sao chép nó ở đây.
chepner

Câu trả lời:


5

GNU Bash xuất các hàm shell trong các biến môi trường bao gồm các định nghĩa hàm:

$ function foo { echo bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { echo bar
}

Khi một cá thể Bash mới được sinh ra, nó sẽ tìm các biến môi trường khớp với một mẫu nhất định. Nội dung của các biến đó được tự động nhập dưới dạng hàm shell. Như Stéphane Chazelas giải thích , do tính năng này được giới thiệu trong Bash 1.03, việc nhập hàm được thực hiện đơn giản bằng cách thay thế =mục nhập tương ứng trong mảng biến môi trường và diễn giải kết quả dưới dạng định nghĩa hàm. Trước bản vá đã sửa CVE-2014-6271 , biến môi trường đã được diễn giải toàn bộ, bao gồm bất kỳ lệnh nào tuân theo thân hàm thực tế. Bản vá giới thiệu hai chế độ đặc biệt cho parse_and_execute()chức năng SEVAL_FUNCDEFSEVAL_ONECMD. Khi hàm được gọi với SEVAL_FUNCDEF, nó có nhiệm vụ ngăn chặn việc giải thích các lệnh khác với định nghĩa hàm. Các SEVAL_ONECMDlá cờ có nghĩa vụ phải ngăn chặn chức năng từ việc đánh giá hơn một lệnh duy nhất.

Biến môi trường được chế tạo đặc biệt của Tavis Ormandy làm một cái gì đó khác biệt tinh tế. Nó được thiết kế để gây nhầm lẫn cho trình phân tích cú pháp và làm hỏng bộ đệm được sử dụng để lưu trữ các lệnh được ước tính. Phần còn lại của biến môi trường trong bộ đệm thay đổi cách hiểu của lệnh tiếp theo . Vấn đề liên quan này đã nhận được mã định danh CVE CVE-2014-7169 .

Các thành phần của định nghĩa biến môi trường X='() { (a)=>\'là:

  • () { được trình phân tích cú pháp giải thích là khởi đầu của một định nghĩa hàm

  • (a)= được dự định để gây nhầm lẫn cho trình phân tích cú pháp và khiến nó để lại tàn dư của biến môi trường trong bộ đệm

  • >\ là tải trọng thực tế còn lại trong bộ đệm

Mục đích của tải trọng là thay đổi cách hiểu của lệnh được thực thi trong lớp con được gọi bởi sh -c "echo date";. Điều này tất nhiên giả định rằng đó /bin/shlà một liên kết tượng trưng đến bash. Khi chuỗi lệnh được chỉ định làm toán hạng -cđược đặt trong bộ đệm, nội dung của bộ đệm là:

>\[0xA]echo date

Đây [0xA]là một ký tự dòng mới ASCII, thường hoạt động như một dấu phân cách lệnh, nhưng hiện được thoát khỏi \tải trọng. Kết quả là, nội dung của bộ đệm được hiểu là

>echo date

Bash cho phép các toán tử chuyển hướng đi trước các lệnh , nên điều này tương đương với

date > echo 

Điều này chỉ đơn giản là làm cho datelệnh được thực thi với đầu ra tiêu chuẩn của nó được chuyển hướng đến một tệp được gọi echo. Phần còn lại cat echokhông phải là một phần của khai thác, nó chỉ chứng minh rằng bây giờ một tệp echocó tên là chứa đầu ra của datetồn tại.

Về lý do tại sao chuỗi (a)=nhầm lẫn trình phân tích cú pháp trong trường hợp này, dường như nó có liên quan đến nó xuất hiện dưới dạng một định nghĩa hàm lồng nhau (không đúng định dạng). Các biến thể đơn giản hóa của khai thác thể hiện rõ điều này hơn:

$ X='() { function a a>\' bash -c echo
$ ls echo
echo

3
Điều làm tôi ngạc nhiên về toàn bộ hoạt động khai thác này không phải là ý tưởng rằng đó là một công cụ khai thác, mà thực tế là nó không hoạt động kể từ BASH 1.13
Eyoung100

@ eyoung100 Không chắc ý của bạn là gì với "bản chất của cách Linux được tạo ra". echochỉ "được coi là một tệp" (tên) vì vị trí của nó trong lệnh (bash). Trong echo datengày cũng không được coi là một lệnh. Nhưng trong >echo dateecho là tên của tệp nơi đầu ra của datelệnh được chuyển hướng.
Leiaz

@Liaz thực tế là điều này hoạt động hoàn toàn là bản chất mà tôi đã nhận được. Cố gắng coi một lệnh như echo như một tệp trên Windows và Windows sẽ cho bạn biết echo là một lệnh. Bản chất ở đây là Linux không quan tâm vì mọi thứ trong Linux là một tệp / filestream, v.v ... Xem bài viết này
eyoung100

1
@ eyoung100 Cảm ơn bạn đã hiệu đính, mặc dù tôi xin khác biệt rằng điều này có liên quan đến điều đó "mọi thứ đều là một tập tin . Ví dụ, dir>echohoàn toàn hợp lệ trong Windows, sự khác biệt duy nhất ở đây là Bash cho phép các toán tử chuyển hướng đi trước một lệnh .
Thomas Nyman

1
@ eyoung100 Chắc chắn, và tôi đồng ý rằng lý do tại sao echokết thúc như một outfile là khá mơ hồ (và cách sử dụng ở đây làm cho nó thậm chí còn khó hiểu hơn, nhưng đó là những gì câu hỏi được chỉ định). Tôi chỉ đang cố gắng đưa ra quan điểm rằng tôi không nghĩ đó thực sự là vì " bản chất của cách Linux được tạo ra" , mà chỉ là một đặc thù về cách Bash cho phép các toán tử chuyển hướng được sử dụng. Dù sao, cảm ơn sự cải thiện của bạn. Bạn chỉ ra nơi tôi không rõ ràng và tôi đã cố gắng chỉnh sửa câu trả lời để chính xác hơn.
Thomas Nyman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.