Các kịch bản có thể chạy ngay cả khi chúng không được đặt là thực thi không?


25

Tôi dường như có thể chạy các tập lệnh (.sh) có và không có chúng được đặt thành thực thi. Vì vậy, chính xác vấn đề này ở đâu?

Câu trả lời:


24

Giả sử bạn có tệp myscriptchứa các mục sau:

#!/bin/bash
echo "Hello, World!"

Nếu bạn làm cho tệp này có thể thực thi được và chạy nó với ./myscript, thì kernel sẽ thấy rằng hai byte đầu tiên là #!, có nghĩa đó là tệp script. Sau đó, hạt nhân sẽ sử dụng phần còn lại của dòng làm trình thông dịch và truyền tệp làm đối số đầu tiên. Vì vậy, nó chạy:

/bin/bash myscript

và bash đọc tệp và thực thi các lệnh mà nó chứa.

Do đó, để bash (hoặc bất kỳ trình thông dịch nào mà tập lệnh của bạn yêu cầu) "thực thi" tập lệnh, nó chỉ cần có khả năng đọc tệp.

Vì vậy, đối với các tập lệnh, bit thực thi chỉ làm cho nó thuận tiện hơn một chút để thực thi nó. Miễn là bash có thể thực thi được, bạn luôn có thể chạy bash với tệp script làm đối số hoặc chạy bash tương tác và sao chép dán dòng script theo dòng vào thiết bị đầu cuối của bạn để thực thi các lệnh.


Cảm ơn đã giải thích chi tiết. :) Nếu tôi hiểu đúng, bất kỳ người dùng nào truy cập vào bash chỉ cần truy cập đọc vào tập lệnh để chạy nó vì bash sẽ lấy tập lệnh làm đầu vào và sẽ chỉ cần đọc nó. Tôi có thể dừng hành vi này bằng cách đọc quyền đọc tập lệnh cho người dùng đó. Đúng? Vậy khi nào thì quyền thực thi này được sử dụng & chính xác là vấn đề?
Ashfame

Có, nếu bạn sử dụng "bash myscript" thì người dùng chỉ cần truy cập đọc cho "myscript" (và tất nhiên có thể thực thi được cho / bin / bash nếu có bash trong đường dẫn). Tuy nhiên, nếu bạn thực hiện kịch bản của mình, mọi thứ sẽ khác một chút. Đúng là theo quan điểm của kernel, nó sẽ lại là "/ bin / bash myscript" nếu dòng đầu tiên là #! / Bin / bash, nhưng để đạt đến điểm đó, trước tiên, bạn cần phải trình bày tập lệnh dưới dạng thực thi cho người dùng hoặc nhóm. Tuy nhiên, điều đó đúng nếu với một số người dùng, tập lệnh không thể thực thi được nhưng có thể đọc được, anh ta vẫn có thể "chạy" tập lệnh bằng "bash myscript" ....
LGB

@LGB Vì vậy, điều đó khá vô dụng. Điều tốt là cắt quyền đọc khỏi người dùng cho tập lệnh đó. Đúng?
Ashfame

@Ashfame: Tôi sẽ nói hữu ích hơn là vô dụng. Bit thực thi trên các tệp thông thường không (và không bao giờ được dự định) được sử dụng để giới hạn quyền truy cập. Có vẻ như bạn đang mong đợi điều đó từ nó. Nếu bạn có một tệp thực thi nhị phân, bạn phải có quyền thực thi trên nó để chạy nó. Tuy nhiên, nếu bạn đã đọc quyền truy cập vào nó, bạn luôn có thể sao chép tệp vào thư mục chính của mình, trong trường hợp đó, bản sao sẽ thuộc quyền sở hữu của bạn, vì vậy bạn có thể thêm quyền thực thi cho nó ... và chạy nó. Đối với các thư mục mặc dù, nó có một mục đích khác nhau. Xem mywiki.wooledge.org/Permissions
geirha

1
Tôi nên sử dụng gì thay vì / bin / bash nếu tôi không biết trình thông dịch chính xác? Có một lệnh chạy tập lệnh theo dòng shebang?
Aivar

16

Hãy chắc chắn rằng bạn không nhầm lẫn "thực thi tập lệnh shell" với "chạy tập lệnh shell bằng sh".

Điều này sẽ không bị ảnh hưởng bởi quyền truy cập tệp trên file.sh:

sh file.sh

Bạn đang thực thi sh(phân giải chương trình /bin/sh), nó đọc file.shvà thực thi mã của nó.

Quyền truy cập tệp sẽ có hiệu lực nếu bạn thực sự thực thi chính tập lệnh :

./file.sh

Lưu ý rằng các quyền của tệp không được hỗ trợ bởi các hệ thống tệp không phải của Linux, như FAT. Vì vậy, ngay cả khi bạn chạy chmod -x file.sh, tệp vẫn sẽ có quyền cũ.

Thực thi quyền được thực thi bởi hệ thống tập tin. Nhưng các chương trình cũng có thể "thực thi" mã bằng cách đọc nội dung tệp, bỏ qua các quyền của hệ thống tệp khi "thực thi".


Tôi hiểu quan điểm của bạn. Nhưng sau đó là cho nhóm hoặc thế giới hoặc cả hai?
Ashfame

@Ashfame Nếu bạn đặt quyền thực thi, tập lệnh có thể được chạy trực tiếp bởi người dùng có quyền đó - cho dù họ có quyền đó trên cơ sở nhóm, thế giới hay chủ sở hữu. Nhưng ngay cả những người không có quyền thực thi cũng có thể thực thi nó bằng cách gọi một chương trình khác (như bash) để thực hiện - để chặn rằng bạn cũng sẽ phải lấy đi sự readcho phép của họ .
jg-faustus

If you set the executable permission, the script can be run directly by users who have that permission - whether they have it on a group, world or owner basisNhưng làm thế nào quyền được cấp cho người dùng khác nhau bằng cách kiểm tra quyền thực thi? Và tôi đã nhận được điểm thứ hai của bạn. Bạn có nghĩa là lấy đi sự cho phép đọc kịch bản của họ để họ thậm chí không thể xử lý nó thông qua bash. Đúng?
Ashfame

@Ashfame Trên điểm cho phép đọc, có. Về cách, bạn sẽ gọi một cái gì đó như sudo chmod g+x myfile.shtrong thiết bị đầu cuối để thêm quyền thực thi cho nhóm của tệp. Xem hướng dẫn cấp quyền tệp . Để quản lý quyền cho nhiều người dùng đồng thời, bạn sẽ sử dụng các nhóm, xem ví dụ: Quản lý các nhóm .
jg-faustus

ý tôi là khi chúng ta thêm quyền thực thi trong GUI, thì nó dành cho ai? chủ sở hữu / nhóm / thế giới?
Ashfame

1

Đừng nghĩ về nó theo cách đó. Tôi có thể thực hiện tập tin này không? Hãy nghĩ về nó theo cách: Ai có thể thực hiện tệp này?

Nếu máy tính là của bạn và tập tin là của bạn, tôi chắc chắn bạn có thể thực thi nó. Bạn có thể muốn xem xét thêm về các lệnh như chmodchown , và quyền truy cập tệp.

Tôi hy vọng điều đó sẽ giúp.


Vâng, tôi biết về họ. Điều đó có nghĩa là, tôi (chủ sở hữu) luôn có thể thực hiện nó. Đúng? Sau đó, thiết lập một tập tin là thực thi là cho nhóm hoặc thế giới hoặc cả hai?
Ashfame

1

Tòa nhà execcủa nhân Linux không thành công EACCESnếu tệp không thể thực thi được

Mặc dù bạn có thể làm sh myprog.sh(chỉ đọc các tệp và thông dịch là), nhưng cố gắng chạy chương trình là ./myprog.shkhông thể, vì khi bạn làm điều đó:

Điều này có thể được xác minh với main.c:

#define _XOPEN_SOURCE 700
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = {"myprog", NULL};
    char *envp[] = {NULL};
    int ret;
    ret = execve("myprog.sh", argv, envp);
    perror("execve");
    printf("%d\n", errno);
    printf("%d\n", EACCES);
}

myprog.sh:

#!/bin/sh
echo worked

Nếu myprog.shkhông thể thực thi được, mainthất bại với:

execve: Permission denied
13
13

Đã thử nghiệm trong Ubuntu 17.10 , gcc -std=c99.

POSIX 7 đề cập rằng tại:

Các hàm exec, ngoại trừ fexecve (), sẽ thất bại nếu:

[EACCES] Quyền tìm kiếm bị từ chối đối với một thư mục được liệt kê trong tiền tố đường dẫn của tệp hình ảnh quy trình mới hoặc tệp hình ảnh quy trình mới từ chối quyền thực thi.

Cơ sở hợp lý khác có thể được tìm thấy tại: /security/66550/unix-execute- allow-can-be- easy-bypassed-is-it-superfupt-or-why-the

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.