Bisakah skrip dapat dieksekusi tetapi tidak dapat dibaca?

65

Apakah mungkin untuk menjalankan skrip jika tidak ada izin untuk membacanya? Dalam mode root, saya membuat skrip dan saya ingin pengguna lain mengeksekusi skrip ini tetapi tidak membacanya. Saya melakukan chmoduntuk melarang membaca dan menulis tetapi mengizinkan eksekusi, namun dalam mode pengguna, saya melihat pesan yang mengatakan: izin ditolak.

ashim
sumber

Jawaban:

68

Masalahnya adalah bahwa script tidak apa yang sedang berjalan, tetapi juru ( bash, perl, python, dll). Dan penerjemah perlu membaca skrip. Ini berbeda dari program "biasa", seperti ls, dalam hal program dimuat langsung ke dalam kernel, seperti yang dilakukan oleh penerjemah. Karena kernel itu sendiri sedang membaca file program, tidak perlu khawatir tentang akses baca. Penerjemah perlu membaca file skrip, karena file normal perlu dibaca.

Arcege
sumber
2
Ya tetapi dalam kasusnya apakah ada solusi?
Olivier Pons
13
Satu kemungkinan adalah memiliki program C sederhana yang menyematkan skrip dan memanggil penerjemah secara eksplisit. Program AC tidak perlu memiliki izin baca untuk dieksekusi.
Arcege
1
Sebenarnya, kernel tidak membeda-bedakan dalam kasus ini dan sebenarnya akan menjalankan shell (cara yang sama seperti jika file yang dapat dieksekusi adalah biner). Namun, shell itu sendiri akan segera macet karena tidak dapat membaca file input (konten file skrip).
Jozef
34

Ini hanya mungkin untuk binari.

$ chown foo:foo bar
$ chmod 701 bar

Sebagai pengguna yang tidak memiliki hak:

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

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Sekarang, inilah kickernya. Meskipun file tidak dapat dibaca dengan cara konvensional, Anda sebenarnya tidak dapat mencegah membaca file. Ini sebenarnya sebuah tantangan di http://smashthestack.org/ (level 13). Ada utilitas terkenal yang disebut hktraceyang memungkinkan Anda membaca file menggunakan ptrace.

kwarrick
sumber
Sangat menarik (hktrace).
fthinker
1
apakah mungkin untuk mengubah skrip shell ke format biner?
ashim
4
Sebenarnya, Anda dapat mencegahnya, saya pikir. Versi kernel Linux saat ini mengatur prosesnya menjadi non-dumpable, artinya tidak ada pengguna normal yang dapat melakukan ptrace lagi, jika pengguna tidak diperbolehkan membaca biner.
thejh
6

Ini tidak mungkin, setidaknya di Linux (Unix lain mungkin mengizinkannya); Pikirkan tentang hal ini, ketika Anda menjalankan skrip, shell perlu membacanya untuk mengetahui apa yang harus dilakukan.

Renan
sumber
3
Itu tentu saja mungkin; OpenBSD memungkinkan semua skrip dijalankan tanpa izin baca. Di bawah tenda itu ia melakukan ini dengan membuat deskriptor file duplikat untuk digunakan penerjemah.
eradman
@eradman Saya telah memasukkan itu (bersama dengan contoh, penjelasan, dan beberapa komentar saya) ke dalam jawaban .
Mosvy
3

Anda bisa, saya pikir, melakukan ini dengan setuid.

Kecuali Anda tidak bisa karena sebagian besar distro (tampaknya) telah setuiddinonaktifkan karena ini merupakan lubang keamanan besar. Ini dinonaktifkan pada saya, jadi saya tidak benar-benar tahu bahwa jawaban ini akan berhasil, saya tetap mempostingnya karena saya pikir itu harus .

Lagi pula, jika saya ingin melakukan apa yang ingin Anda lakukan - dan saya memiliki distro yang setuiddiaktifkan untuk skrip - saya akan melakukan sesuatu seperti:

$ 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!

Artinya saya akan menulis skrip lain yang tujuan utamanya adalah memanggil skrip root-read-only, mengubahnya menjadi dimiliki oleh root, dan memberikannya setuid izin. (Bersamaan dengan status petugas yang tidak dapat ditulis oleh orang lain.)

Karena fungsi myscript-nonroot dapat dibaca oleh semua orang, itu dapat dibaca dan dieksekusi, dan saat Anda mendapatkan dua baris di mana Anda benar-benar mengeksekusi skrip Anda ( bash myscript) itu dijalankan sebagai root (atau siapa pun yang Anda inginkan, pengguna yang tepat tidak masalah, selama file wrapper dimiliki oleh pengguna yang sama.)

quodlibetor
sumber
Apa arti 4755? Saya baru dalam hal ini, jadi saya ingin tahu apa artinya. Saya mengerti bagian 755. Terima kasih
Kevdog777
2
yang 4set yang setuid bit. Lihat bagian Mode di halaman manual chmod di manpagez .
quodlibetor
Ok, saya masih tidak begitu mengerti, tapi saya butuh beberapa saat untuk mengerti 755sedikit.
Kevdog777
ya, sebenarnya chmod 755sama dengan 0775 oktal. ada banyak kebingungan di sekitar itu .. Halaman ini ( manpagez.com/man/1/chmod ) memiliki gulir horizontal yang mengerikan dan tidak diawetkan yang tidak dapat saya mengerti ...
erm3nda
2

Pada situasi ini saya menggunakan sudo dengan opsi NOPASSWD sehingga pengguna dapat menjalankan skrip tanpa bisa membacanya.

pengguna33577
sumber
2

Ada setengah kebenaran dari pernyataan sebelumnya. Anda dapat mengatur skrip sehingga tidak dapat dibaca oleh pengguna, tetapi masih dapat dieksekusi. Prosesnya sedikit berlarut-larut, tetapi bisa dilakukan dengan membuat pengecualian di / etc / sudoer sehingga pengguna dapat menjalankan skrip sebagai diri Anda sementara waktu tanpa diminta kata sandi. Metode ini: - menyiasati patch setuid untuk distro lain. - memungkinkan Anda untuk memberikan izin tinggi untuk skrip tertentu tanpa memberikan hak sudo pengguna untuk semuanya.

Ikuti instruksi pada posting ini: Izin file hanya dijalankan

santana
sumber
0

Ini bekerja pada OpenBSD

Seperti yang telah disebutkan dalam komentar oleh @eradman, ini dimungkinkan pada OpenBSD.

Sebagai root:

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

Sebagai pengguna biasa:

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

Itu bekerja dengan mengirimkan /dev/fd/3(atau apa pun fd terbuka ke skrip) ke penerjemah. Trik itu tidak akan berfungsi di Linux, di mana /dev/fd/Nbukan perangkat karakter khusus yang mengembalikan a dup(2)fd ketika dibuka, tetapi "sulap" symlinks ke file asli / gigi, yang membuka file dari awal [1]. Ini dapat diimplementasikan dalam Free / NetBSD atau Solaris ...

Tapi itu bukan apa yang harus terjadi

Pada dasarnya memberikan xizin (mengeksekusi) berarti juga memberikan rizin (baca) pada file apa pun yang memiliki 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

ktracebukan satu-satunya cara; jika interpreter terkait secara dinamis dapat dieksekusi seperti perlatau python, LD_PRELOADhack ed yang menimpa read(2)fungsi dapat digunakan sebagai gantinya.

Dan tidak, menjadikannya setuid tidak akan mencegah pengguna biasa melihat kontennya; dia bisa menjalankannya di bawah ptrace(2), yang akan menyebabkan bit setuid diabaikan:

Sebagai root:

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

Sebagai pengguna biasa:

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
       "

(maaf jika ini bukan cara yang paling sulit untuk menunjukkannya)

[1] ini dapat ditiru di Linux dengan menggunakan binfmt_misc, tetapi penerjemah harus dimodifikasi, atau pembungkus harus digunakan; lihat bagian terakhir dari jawaban ini untuk contoh yang sengaja dibuat tidak aman.

[2] atau secara umum, file apa pun yang tidak akan menyebabkannya execve()kembali ENOEXEC.

mosvy
sumber
-2

Ya, jika Anda pengguna root, Anda dapat mengeksekusi file tanpa izin baca

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

Tetapi jika Anda masuk dengan pengguna lain, Anda tidak dapat menjalankan file ini

$ ./test
-bash: ./test: Permission denied
gaurav goyal
sumber
3
Ini tidak benar-benar menjawab pertanyaan, karena root masih dapat membaca file bahkan tanpa izin.
wjandrea
-5

Untuk membuat skrip Anda tidak dapat dibaca namun dapat dieksekusi, Anda memiliki 3 opsi utama:

Pilihan pertama

Gunakan perintah openssl untuk mengenkripsi secara manual. Dan di masa mendatang, ketika Anda ingin menjalankan skrip, Anda harus menjalankan openssl secara manual lagi, dan memberikan kata sandi untuk didekripsi.

Enkripsi dengan openssl:

cat yourscript.sh | openssl aes-128-cbc -a -salt -k yourpassword> yourscript.enc

Dekripsi dengan openssl:

cat yourscript.enc | openssl aes-128-cbc -a -d -salt -k yourpassword> yourscript.dec

herscript.dec akan sama dengan script asli milikmu Script Anda

Opsi kedua

Gunakan situs seperti www.Enscryption.com untuk mengenkripsi skrip Anda secara otomatis dan membuat versi terenkripsi dari skrip tersebut dapat dieksekusi. Situs ini menggunakan kemampuan enkripsi openssl dan beberapa metode kebingungan lainnya untuk menyulitkan penyusup untuk membuka skrip Anda atau mengungkap rahasia yang ingin Anda sembunyikan. Dengan situs ini, Anda dapat mengenkripsi skrip shell dan perl baris perintah, skrip python, ruby. Saya pikir php juga.

Opsi ketiga

Gunakan alat seperti shc . Sepertinya belum diperbarui sejak 2012. tapi saya telah menggunakannya di masa lalu. Anda harus mengkompilasi skrip untuk setiap OS tempat Anda ingin menggunakannya, jika OS berbeda dari yang Anda gunakan untuk mengompilasinya.

Ringkasan:

Jika menyembunyikan kode Anda sangat penting bagi Anda, hanya mengandalkan izin dan kepemilikan akan membantu Anda, karena siapa pun dengan root dapat melakukannya. Itu hanya fakta. Apa yang dapat Anda lakukan, jika Anda benar-benar ingin mencegah melihat kode Anda oleh orang lain adalah menulis skrip di sekitar perintah openssl. Buat agar, sebelum skrip berjalan, itu akan meminta kata sandi DAN setelah kata sandi diberikan, itu akan menjalankan skrip tanpa menulisnya ke file temp. Jika ini kedengarannya terlalu banyak bekerja maka opsi 2 dan 3 harus cukup untuk tujuan Anda.

AncientMinds
sumber
Tautan "shc" juga menunjuk ke satu halaman dari sebelumnya. Apakah Anda kebetulan terafiliasi dengan halaman / layanan ini?
phk
3
Jika Anda menulis sandi, skrip itu tidak akan dapat berjalan tanpa kunci. Jika Anda mengirim kunci ke pengguna untuk menjalankannya, akan dapat melihat kontennya. Jawaban ini sangat bodoh ...
erm3nda