Một kịch bản có thể được thực thi nhưng không thể đọc được?


65

Có thể thực thi một tập lệnh nếu không có quyền đọc nó? Trong chế độ root, tôi đã tạo một tập lệnh và tôi muốn người dùng khác thực thi tập lệnh này nhưng không đọc nó. Tôi đã chmodcấm đọc và viết nhưng cho phép thực thi, tuy nhiên trong chế độ người dùng, tôi thấy thông báo có nội dung: quyền bị từ chối.


Câu trả lời:


68

Vấn đề là kịch bản không phải là những gì đang chạy, nhưng người phiên dịch ( bash, perl, python, vv). Và người phiên dịch cần đọc kịch bản. Điều này khác với một chương trình "thông thường", giống như ls, trong đó chương trình được tải trực tiếp vào kernel, như trình thông dịch sẽ làm. Vì hạt nhân đang đọc tệp chương trình, nên không cần phải lo lắng về việc truy cập đọc. Trình thông dịch cần đọc tệp script, vì một tệp bình thường sẽ cần phải đọc.


2
Có nhưng trong trường hợp của anh ấy có một giải pháp?
Olivier Pons

13
Một khả năng sẽ có một chương trình C đơn giản nhúng tập lệnh và gọi trình thông dịch một cách rõ ràng. Chương trình AC không cần phải có quyền đọc để thực thi.
Arcege

1
Nói một cách chính xác, kernel không phân biệt đối xử trong trường hợp này và trên thực tế nó sẽ chạy shell (giống như cách tệp thực thi là tệp nhị phân). Tuy nhiên, shell sẽ ngay lập tức bị sập vì không thể đọc tệp đầu vào (nội dung tệp tập lệnh).
Jozef

34

Điều này chỉ có thể cho nhị phân.

$ chown foo:foo bar
$ chmod 701 bar

Là người dùng không có quyền:

$ ls -lha bar
-rwx-----x 1 foo foo 7.0K 2012-03-15 03:06 bar

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Bây giờ, Đây là cầu thủ bóng đá. Mặc dù tệp không thể đọc được bằng các cách thông thường, nhưng thực tế bạn không thể ngăn đọc tệp. Đây thực sự là một thử thách trên http://smashthestack.org/ (cấp 13). Có một tiện ích nổi tiếng được gọi là hktracecho phép bạn đọc tệp bằng cách sử dụng ptrace.


Rất thú vị (hktrace).
fthinker

1
Có thể chuyển đổi tập lệnh shell sang định dạng nhị phân?
ashim

4
Trên thực tế, bạn có thể ngăn chặn nó, tôi nghĩ. Các phiên bản kernel linux hiện tại đặt quy trình thành không thể kết xuất, nghĩa là không người dùng bình thường nào có thể ptrace nó nữa, nếu người dùng không được phép đọc nhị phân.
thejh

6

Điều này là không thể, ít nhất là trên Linux (các Unice khác có thể cho phép nó); Hãy nghĩ về nó, khi bạn chạy tập lệnh, trình bao cần đọc nó để biết phải làm gì.


3
Nó chắc chắn là có thể; OpenBSD cho phép mọi tập lệnh được thực thi mà không cần sự cho phép đọc. Trong phần mềm, nó thực hiện điều này bằng cách tạo một bộ mô tả tệp trùng lặp để trình thông dịch sử dụng.
eradman

@eradman Tôi đã đặt điều đó (cùng với một ví dụ, giải thích và một số nhận xét của tôi) vào một câu trả lời .
mosvy

3

Bạn có thể, tôi nghĩ rằng, làm điều này với setuid.

Ngoại trừ việc bạn không thể vì hầu hết các distro (dường như) đã setuidbị vô hiệu hóa vì đó là một lỗ hổng bảo mật lớn. Nó bị vô hiệu hóa đối với tôi, vì vậy tôi thực sự không biết rằng câu trả lời này sẽ hoạt động, dù sao tôi cũng đăng nó vì tôi nghĩ nó nên như vậy .

Dù sao, nếu tôi muốn làm những gì bạn muốn làm - và tôi đã có một bản phân phối setuidđược kích hoạt cho các tập lệnh - tôi sẽ làm một cái gì đó như:

$ chmod 700 myscript
$ cat > myscript-nonroot
#!/bin/sh
bash myscript
^D
$ sudo chown root:root myscript-nonroot
$ sudo chmod 4755 myscript-nonroot # make SURE this isn't world-writable!

Điều đó có nghĩa là tôi sẽ viết một tập lệnh khác với mục đích duy nhất là gọi tập lệnh chỉ đọc gốc, thay đổi tập lệnh đó để được sở hữu bởi root và cho phép tập lệnh setuid. (Cùng với tình trạng không thể ghi của người phục vụ bởi những người khác.)

Vì mọi người đều có thể đọc và thực hiện chức năng myscript-nonroot, và khi bạn nhận được hai dòng nơi bạn thực sự thực thi tập lệnh của mình ( bash myscript), nó sẽ được chạy dưới quyền root (hoặc bất cứ ai khác bạn muốn, người dùng chính xác không quan trọng, miễn là tệp trình bao bọc được sở hữu bởi cùng một người dùng.)


4755 có nghĩa là gì? Tôi chưa quen với điều này, vì vậy tôi muốn biết ý nghĩa của nó. Tôi hiểu phần 755. Cảm ơn
Kevdog777

2
các 4tập setuid bit. Xem phần Chế độ trong trang chmod man trên manpagez .
quodlibetor

Ok, tôi vẫn không hiểu lắm, nhưng tôi phải mất một lúc để hiểu được 755.
Kevdog777

vâng, thực sự chmod 755là giống với 0775 bát phân. có rất nhiều rắc rối xung quanh đó .. Trang này ( manpagez.com/man/1/chmod ) có một cuộn ngang awfull và unneded mà tôi không thể hiểu ...
erm3nda

2

Có một nửa sự thật cho các tuyên bố trước. Bạn có thể thiết lập một tập lệnh để người dùng không đọc được nhưng vẫn có thể thực thi được. Quá trình này được rút ra một chút, nhưng có thể thực hiện được bằng cách tạo một ngoại lệ trong / etc / sudoer để người dùng có thể chạy tập lệnh như chính bạn tạm thời mà không bị nhắc nhập mật khẩu. Phương pháp này: - lấy xung quanh bản vá setuid cho các bản phát hành khác. - cho phép bạn tạm thời cấp quyền nâng cao cho một tập lệnh cụ thể mà không cung cấp cho người dùng quyền sudo đối với mọi thứ.

Làm theo hướng dẫn trên bài đăng này: Chỉ cho phép tệp


1

Trong tình huống này, tôi đã sử dụng sudo với tùy chọn NOPASSWD để người dùng có thể chạy tập lệnh mà không thể đọc được.


0

Nó hoạt động trên OpenBSD

Như đã được đề cập trong một bình luận của @eradman, điều này là có thể trên OpenBSD.

Là gốc:

hzy# cat <<'EOT' >/tmp/foo; chmod 001 /tmp/foo
#! /bin/sh
: this is secret
echo done
EOT

Là người dùng thông thường:

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ /tmp/foo
done

Điều đó hoạt động bằng cách chuyển /dev/fd/3(hoặc bất cứ fd mở nào cho tập lệnh) cho trình thông dịch. Thủ thuật đó sẽ không hoạt động trên Linux, nơi /dev/fd/Nkhông phải là thiết bị ký tự đặc biệt trả về một dup(2)fd khi được mở, nhưng các liên kết tượng trưng "ma thuật" cho tệp / nha khoa gốc, mở tệp từ đầu [1]. Nó có thể được triển khai trong Free / NetBSD hoặc Solaris ...

Nhưng nó không phải là những gì nó bị phá vỡ để được

Về cơ bản, cho phép x(thực thi) có nghĩa là cũng cho phép r(đọc) trên bất kỳ tệp nào có shebang [2]:

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ ktrace -ti /tmp/foo
done
hzy$ kdump | tail -n8
 70154 sh       GIO   fd 10 read 38 bytes
       "#! /bin/sh
        : this is secret
        echo done
       "
 70154 sh       GIO   fd 1 wrote 5 bytes
       "done

ktracekhông phải là cách duy nhất; nếu trình thông dịch được liên kết động có thể thực thi như perlhoặc python, một LD_PRELOADhack ed ghi đè read(2)chức năng có thể được sử dụng thay thế.

Và không, làm cho nó được thiết lập sẽ không ngăn người dùng thông thường nhìn thấy nội dung của nó; cô ấy chỉ đơn giản có thể chạy nó bên dưới ptrace(2), điều này sẽ khiến các bit setuid bị bỏ qua:

Là gốc:

hzyS# cat <<'EOT' >/tmp/bar; chmod 4001 /tmp/bar
#! /bin/sh
: this is secret
id
EOT

Là người dùng thông thường:

hzyS$ ktrace -ti /tmp/bar
uid=1001(duns) euid=0(root) gid=1001(duns) groups=1001(duns)
hzyS$ kdump
    ... nothing, the kernel disabled the ktrace ...
hzyS$ cc -Wall -xc - -o pt <<'EOT'
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <signal.h>

int main(int ac, char **av){
        int s; pid_t pid;
        if((pid = fork()) == 0){
                ptrace(PT_TRACE_ME, 0, 0, 0);
                execvp(av[1], av + 1);
        }
        while(wait(&s) > 0 && WIFSTOPPED(s)){
                s = WSTOPSIG(s);
                ptrace(PT_CONTINUE, pid, (caddr_t)1, s == SIGTRAP ? 0 : s);
        }
}
EOT
hzyS$ ./pt ktrace -ti /tmp/bar
uid=1001(duns) gid=1001(duns) groups=1001(duns)
hzyS$ kdump | tail -5
 29543 sh       GIO   fd 10 read 31 bytes
       "#! /bin/sh
        : this is secret
        id
       "

(xin lỗi nếu đây không phải là cách thẳng thắn nhất để chứng minh điều đó)

[1] điều này có thể được mô phỏng trên Linux bằng cách sử dụng binfmt_misc, nhưng trình thông dịch sẽ phải được sửa đổi, hoặc một trình bao bọc sẽ phải được sử dụng; xem phần cuối của câu trả lời này để biết ví dụ cố tình làm cho không an toàn một cách lố bịch.

[2] hoặc nói chung, bất kỳ tệp nào sẽ không execve()trở lại ENOEXEC.


-2

Có, nếu bạn là người dùng root, bạn có thể thực thi tệp mà không cần sự cho phép đọc

# echo "echo hello" > test
# chmod 100 test
# ll test
---x------ 1 root root 10 Nov 29 12:13 test
# ./test
hello

Nhưng nếu bạn đăng nhập với bất kỳ người dùng nào khác, bạn không thể thực thi tệp này

$ ./test
-bash: ./test: Permission denied

3
Điều này không thực sự trả lời câu hỏi, vì root vẫn có thể đọc tệp ngay cả khi không được phép.
wjandrea

-5

Để làm cho tập lệnh của bạn không thể đọc được nhưng vẫn có thể thực thi được, bạn có 3 tùy chọn chính:

Lựa chọn đầu tiên

Sử dụng lệnh openssl để mã hóa thủ công. Và trong tương lai, khi bạn muốn chạy tập lệnh, bạn sẽ phải chạy openssl một cách thủ công và cung cấp mật khẩu để giải mã.

Mã hóa với openssl:

catcriptcript.sh | openssl aes-128-cbc -a -salt -k yourpassword> yourcript.enc

Giải mã với openssl:

catcriptcript.enc | openssl aes-128-cbc -a -d -salt -k yourpassword> yourcript.dec

minecript.dec sẽ giống như tập lệnh gốc của bạn

Sự lựa chọn thứ hai

Sử dụng một trang web như www.Enscoding.com để tự động mã hóa tập lệnh của bạn và làm cho phiên bản được mã hóa của tập lệnh có thể thực thi được. Trang web này sử dụng cả khả năng mã hóa của openssl và một số phương thức che giấu khác để gây khó khăn cho những kẻ xâm nhập vào kịch bản của bạn hoặc tiết lộ bí mật mà bạn muốn ẩn. Với trang web này, bạn có thể mã hóa tập lệnh shell và dòng lệnh perl, python, ruby ​​script. Tôi nghĩ rằng php là tốt.

Lựa chọn thứ ba

Sử dụng một công cụ như shc . Có vẻ như nó chưa được cập nhật từ năm 2012. nhưng tôi đã sử dụng nó trong quá khứ. Bạn phải biên dịch tập lệnh của mình cho từng HĐH mà bạn muốn sử dụng tập lệnh đó, nếu HĐH đó khác với tập lệnh bạn đã sử dụng để biên dịch tập lệnh đó.

Tóm lược:

Nếu việc ẩn mã của bạn có tầm quan trọng lớn đối với bạn, chỉ dựa vào quyền và quyền sở hữu sẽ giúp bạn, vì bất kỳ ai có quyền root đều có thể nhận được. Đó chỉ là sự thật. Những gì bạn có thể làm, nếu bạn thực sự muốn ngăn chặn việc xem mã trái phép của bất kỳ ai là viết một tập lệnh xung quanh lệnh openssl. Làm cho nó để trước khi tập lệnh chạy, nó sẽ nhắc nhập mật khẩu VÀ sau khi mật khẩu được cung cấp, nó sẽ chạy tập lệnh mà không ghi nó vào tập tin tạm thời. Nếu điều này nghe có vẻ quá nhiều công việc thì tùy chọn 2 và 3 sẽ đủ cho mục đích của bạn.


Liên kết "shc" cũng trỏ đến một trang từ trước đó. Bạn có bất kỳ cơ hội liên kết với trang / dịch vụ này?
phk

3
Nếu bạn mã hóa tập lệnh của mình, nó sẽ không thể chạy nếu không có khóa. Nếu bạn đã gửi khóa cho người dùng để chạy nó, sẽ có thể thấy nội dung của nó.
Anwers
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.