สคริปต์สามารถเรียกใช้งานได้ แต่ไม่สามารถอ่านได้หรือไม่?


65

เป็นไปได้ไหมที่จะเรียกใช้งานสคริปต์หากไม่มีสิทธิ์ในการอ่าน ในโหมดรูทฉันสร้างสคริปต์และฉันต้องการให้ผู้ใช้รายอื่นเรียกใช้งานสคริปต์นี้ แต่ไม่ได้อ่าน ฉันไม่chmodอนุญาตให้อ่านและเขียน แต่อนุญาตให้ใช้งานได้ แต่ในโหมดผู้ใช้ฉันเห็นข้อความที่แจ้งว่า: สิทธิ์ถูกปฏิเสธ


ที่เกี่ยวข้อง: รันสคริปต์โดยไม่ต้องถอดรหัสพวกเขา
สกอตต์

คำตอบ:


68

ปัญหาก็คือว่าสคริปต์ไม่ได้เป็นสิ่งที่จะทำงาน แต่ล่าม ( bash, perl, pythonฯลฯ ) และล่ามจำเป็นต้องอ่านสคริปต์ สิ่งนี้แตกต่างจากโปรแกรม "ปกติ" เช่นเดียวกับlsที่โปรแกรมโหลดเข้าสู่เคอร์เนลโดยตรงตามที่ล่ามต้องการ เนื่องจากเคอร์เนลเป็นไฟล์โปรแกรมอ่านจึงไม่จำเป็นต้องกังวลเกี่ยวกับการเข้าถึงการอ่าน ล่ามจำเป็นต้องอ่านไฟล์สคริปต์เนื่องจากจะต้องอ่านไฟล์ปกติ


2
ใช่ แต่ในกรณีของเขามีทางออกหรือไม่?
Olivier Pons

13
ความเป็นไปได้อย่างหนึ่งคือการมีโปรแกรม C อย่างง่ายที่ฝังสคริปต์และเรียกล่ามอย่างชัดเจน โปรแกรม AC ไม่จำเป็นต้องมีสิทธิ์อ่านเพื่อดำเนินการ
Arcege

1
เคอร์เนลไม่ได้แยกแยะอย่างชัดเจนในกรณีนี้และในความเป็นจริงแล้วมันจะรันเชลล์ (เช่นเดียวกับที่ไฟล์เรียกทำงานเป็นไบนารี) อย่างไรก็ตามเชลล์เองจะพังทันทีเนื่องจากไม่สามารถอ่านไฟล์อินพุต (เนื้อหาไฟล์สคริปต์)
Jozef

34

สิ่งนี้เป็นไปได้สำหรับไบนารีเท่านั้น

$ chown foo:foo bar
$ chmod 701 bar

ในฐานะผู้ใช้ที่ไม่มีสิทธิ์:

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

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

ตอนนี้ที่นี่เป็นนักเตะ แม้ว่าไฟล์จะไม่สามารถอ่านได้ด้วยวิธีการทั่วไปคุณไม่สามารถป้องกันการอ่านไฟล์ได้ นี่เป็นความท้าทายที่แท้จริงในhttp://smashthestack.org/ (ระดับ 13) มียูทิลิตี้ที่รู้จักกันดีเรียกว่าเป็นที่ช่วยให้คุณสามารถอ่านไฟล์โดยใช้hktraceptrace


น่าสนใจมาก (hktrace)
fthinker

1
เป็นไปได้ไหมที่จะแปลงเชลล์สคริปต์เป็นรูปแบบไบนารี
ashim

4
ที่จริงคุณสามารถป้องกันได้ฉันคิด เวอร์ชันเคอร์เนล linux ปัจจุบันตั้งค่ากระบวนการเป็นแบบไม่ดัมพ์หมายความว่าไม่มีผู้ใช้ปกติสามารถ ptrace อีกต่อไปหากผู้ใช้ไม่ได้รับอนุญาตให้อ่านไบนารี
thejh

6

สิ่งนี้เป็นไปไม่ได้อย่างน้อยใน Linux (Unices อื่น ๆ อาจอนุญาต) ลองคิดดูเมื่อคุณเรียกใช้สคริปต์เชลล์จำเป็นต้องอ่านเพื่อที่จะได้รู้ว่าต้องทำอย่างไร


3
เป็นไปได้อย่างแน่นอน OpenBSD ช่วยให้สคริปต์ใด ๆ ที่จะดำเนินการโดยไม่ได้รับอนุญาตอ่าน ภายใต้ฝากระโปรงมันทำเช่นนี้โดยการสร้างไฟล์อธิบายซ้ำกันเพื่อให้ล่ามใช้
eradman

@eradman ฉันได้ใส่นั้น (พร้อมกับยกตัวอย่างเช่นคำอธิบายและคำพูดบางอย่างของฉัน) เป็นคำตอบ
mosvy

3

setuidคุณสามารถผมคิดว่าทำเช่นนี้กับ

ยกเว้นว่าคุณทำไม่ได้เพราะ distros ส่วนใหญ่ (เห็นได้ชัด) setuidปิดการใช้งานเพราะเป็นช่องโหว่ความปลอดภัยขนาดใหญ่ จะปิดใช้งานในเหมืองดังนั้นฉันไม่จริงรู้ว่าคำตอบนี้จะทำงานผมโพสต์มันอยู่แล้วเพราะผมคิดว่ามันควรจะเป็น

อย่างไรก็ตามถ้าฉันต้องการทำสิ่งที่คุณต้องการจะทำ - และฉันมี distro ที่setuidเปิดใช้งานสคริปต์ - ฉันจะทำสิ่งที่ชอบ:

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

ซึ่งจะบอกว่าฉันจะเขียนสคริปต์อื่นที่มีวัตถุประสงค์เพียงอย่างเดียวคือการเรียกสคริปต์แบบอ่านอย่างเดียวรูทเปลี่ยนเป็น root โดยเป็นเจ้าของและให้สิทธิ์ setuid (รวมถึงคนอื่น ๆ ที่ไม่สามารถเขียนสถานะได้)

เนื่องจากฟังก์ชั่น myscript-nonroot สามารถอ่านได้โดยทุกคนจึงสามารถอ่านและดำเนินการได้และเมื่อถึงเวลาที่คุณได้รับสองบรรทัดที่คุณใช้งานสคริปต์จริง ๆ ( bash myscript) ก็จะถูกเรียกใช้เป็นรูท (หรือใครก็ตามที่คุณต้องการ ไม่สำคัญตราบใดที่ไฟล์ wrapper เป็นของผู้ใช้คนเดียวกัน)


4755 หมายถึงอะไร ฉันยังใหม่กับสิ่งนี้ดังนั้นฉันต้องการทราบความหมายของมัน ฉันเข้าใจส่วนที่ 755 ขอบคุณ
Kevdog777

2
4ชุดsetuidบิต ดูส่วนโหมดในหน้าคน chmod ใน manpagez
quodlibetor

ตกลงฉันยังไม่ค่อยเข้าใจ แต่มันใช้เวลาสักพักกว่าจะเข้าใจ755สักหน่อย
Kevdog777

อ๋อจริง ๆ แล้วchmod 755เท่ากับ 0775 ฐานแปด มีความสับสนมากมายเกี่ยวกับเรื่องนั้น .. หน้านี้ ( manpagez.com/man/1/chmod ) มีสกรอลล์แนวนอนที่น่ากลัวและไม่มีใครจับที่ฉันไม่สามารถเข้าใจได้ ...
erm3nda

2

มีความจริงครึ่งหนึ่งของข้อความก่อนหน้านี้ คุณสามารถตั้งค่าสคริปต์เพื่อให้ผู้ใช้ไม่สามารถอ่านได้ แต่ยังสามารถใช้งานได้ กระบวนการนี้ถูกดึงออกมาเล็กน้อย แต่ทำได้โดยการยกเว้นใน / etc / sudoer เพื่อให้ผู้ใช้สามารถเรียกใช้สคริปต์ด้วยตัวคุณเองเป็นการชั่วคราวโดยไม่ต้องใส่รหัสผ่าน วิธีนี้: - รับรอบ patch setuid สำหรับ distros อื่น ๆ - อนุญาตให้คุณให้สิทธิ์ในระดับสูงสำหรับสคริปต์เฉพาะโดยไม่ต้องให้สิทธิ์ sudo แก่ผู้ใช้กับทุกสิ่ง

ทำตามคำแนะนำในโพสต์นี้: สิทธิ์ของไฟล์ดำเนินการเท่านั้น


1

ในสถานการณ์นี้ฉันใช้ sudo พร้อมตัวเลือก NOPASSWD เพื่อให้ผู้ใช้สามารถเรียกใช้สคริปต์โดยไม่สามารถอ่านได้


0

มันทำงานบน OpenBSD

ดังที่ได้กล่าวไปแล้วในความคิดเห็นโดย @eradman สิ่งนี้เป็นไปได้ใน OpenBSD

ในฐานะที่เป็นราก:

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

ในฐานะผู้ใช้ทั่วไป:

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

มันทำงานได้โดยการส่งต่อ/dev/fd/3(หรืออะไรก็ตามที่ fd เปิดให้สคริปต์) ไปยังล่าม เคล็ดลับนั้นจะไม่ทำงานบน Linux ซึ่ง/dev/fd/Nไม่ใช่อุปกรณ์ตัวอักษรพิเศษที่คืนdup(2)ค่า fd เมื่อเปิด แต่ symlink "magic" กลับไปยังไฟล์ต้นฉบับ / Dentry ซึ่งเปิดไฟล์จากศูนย์ [1] มันสามารถนำมาใช้ในฟรี / NetBSD หรือ Solaris ...

แต่มันไม่ใช่สิ่งที่แตกสลายไป

การให้xสิทธิ์โดยทั่วไป(ดำเนินการ) หมายถึงการอนุญาตr(อ่าน) ไฟล์ใด ๆ ที่มี 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

ktraceไม่ใช่วิธีเดียว; ถ้าล่ามที่มีการเชื่อมโยงแบบไดนามิกปฏิบัติการเหมือนperlหรือpythonการLD_PRELOADสับเอ็ดซึ่งแทนที่read(2)ฟังก์ชั่นสามารถนำมาใช้แทน

และไม่ทำให้ setuid ไม่ทำให้ผู้ใช้ทั่วไปเห็นเนื้อหา เธอสามารถเรียกใช้ภายใต้ptrace(2)ซึ่งจะทำให้บิต setuid ถูกละเว้น:

ในฐานะที่เป็นราก:

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

ในฐานะผู้ใช้ทั่วไป:

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
       "

(ขออภัยหากนี่ไม่ใช่วิธีที่ตรงไปตรงมาที่สุดในการแสดง)

[1] สามารถเลียนแบบได้บน Linux โดยใช้binfmt_miscแต่ล่ามจะต้องมีการแก้ไขหรือจะต้องใช้ wrapper ดูส่วนสุดท้ายของคำตอบนี้สำหรับตัวอย่างที่ทำโดยเจตนาไม่ปลอดภัยอย่างน่าขัน

[2] หรือโดยทั่วไปไฟล์ใด ๆ ซึ่งจะไม่ทำให้เกิดการที่จะกลับมาexecve()ENOEXEC


-2

ใช่ถ้าคุณเป็นผู้ใช้รูทคุณสามารถเรียกใช้ไฟล์โดยไม่ได้รับอนุญาตให้อ่าน

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

แต่ถ้าคุณเข้าสู่ระบบด้วยผู้ใช้คนอื่นคุณจะไม่สามารถเรียกใช้ไฟล์นี้ได้

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

3
สิ่งนี้ไม่ตอบคำถามจริงๆทำให้รูทยังสามารถอ่านไฟล์ได้แม้จะไม่ได้รับอนุญาต
wjandrea

-5

ในการทำให้สคริปต์ของคุณอ่านไม่ได้ แต่ยังทำงานได้คุณมี 3 ตัวเลือกหลัก:

ตัวเลือกแรก

ใช้คำสั่ง openssl เพื่อเข้ารหัสด้วยตนเอง และในอนาคตเมื่อคุณต้องการเรียกใช้สคริปต์คุณจะต้องเปิด openssl ด้วยตนเองอีกครั้งและระบุรหัสผ่านเพื่อถอดรหัส

การเข้ารหัสด้วย openssl:

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

ถอดรหัสด้วย openssl:

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

yourscript.dec จะเหมือนกับสคริปต์ต้นฉบับของคุณ yourscript.sh

ตัวเลือกที่สอง

ใช้เว็บไซต์เช่นwww.Enscryption.comเพื่อเข้ารหัสสคริปต์ของคุณโดยอัตโนมัติและสร้างเวอร์ชันที่เข้ารหัสของสคริปต์ที่สามารถเรียกใช้งานได้ ไซต์นี้ใช้ทั้งความสามารถในการเข้ารหัสของ openssl และวิธีการทำให้งงอื่น ๆ เพื่อให้ผู้บุกรุกสามารถสอดแทรกสคริปต์ของคุณหรือเปิดเผยความลับที่คุณต้องการซ่อนอยู่ได้ยาก ด้วยไซต์นี้คุณสามารถเข้ารหัสเชลล์สคริปต์และบรรทัดคำสั่ง perl, python, ruby ​​script ฉันคิดว่า php เช่นกัน

ตัวเลือกที่สาม

ใช้เครื่องมือเช่นSHC ดูเหมือนว่าจะไม่ได้รับการอัพเดตตั้งแต่ปี 2012 แต่ฉันเคยใช้มาแล้วในอดีต คุณต้องรวบรวมสคริปต์สำหรับแต่ละระบบปฏิบัติการที่คุณต้องการใช้งานหากระบบปฏิบัติการแตกต่างจากระบบที่คุณใช้ในการรวบรวม

สรุป:

หากการซ่อนรหัสของคุณมีความสำคัญอย่างยิ่งต่อคุณการใช้สิทธิ์และการเป็นเจ้าของจะช่วยคุณได้เพราะทุกคนที่รูทสามารถเข้าใช้งานได้ นั่นเป็นเพียงความจริง คุณสามารถทำอะไรได้ถ้าคุณต้องการป้องกันการดูรหัสโดยไม่ได้รับอนุญาตจากใครก็ตามคือการเขียนสคริปต์รอบคำสั่ง openssl ทำก่อนที่สคริปต์จะรันสคริปต์จะถามรหัสผ่านและหลังจากได้รับรหัสผ่านแล้วสคริปต์จะทำงานโดยไม่ต้องเขียนลงในไฟล์ชั่วคราว หากดูเหมือนว่างานมากเกินไปตัวเลือกที่ 2 และ 3 ควรเพียงพอสำหรับวัตถุประสงค์ของคุณ


ลิงก์ "shc" ยังชี้ไปยังหน้าหนึ่งจากก่อนหน้า คุณมีส่วนเกี่ยวข้องกับหน้า / บริการนี้หรือไม่?
phk

3
หากคุณเข้ารหัสตัวเลขสคริปต์ของคุณจะไม่สามารถทำงานได้หากไม่มีรหัส หากคุณส่งรหัสไปยังผู้ใช้เพื่อเรียกใช้จะสามารถดูเนื้อหาได้ คำตอบนี้โง่มาก ...
erm3nda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.