यह 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
दुभाषिया के लिए (या स्क्रिप्ट के लिए खुली एफडी जो भी हो) पास करके काम करता है । यह चाल लिनक्स पर काम नहीं करेगी , जहां /dev/fd/N
विशेष वर्ण उपकरण नहीं हैं जो dup(2)
खोले जाने पर fd की वापसी करते हैं, लेकिन मूल फ़ाइल / डेंट्री के लिए "जादू" को सहानुभूति होती है, जो फ़ाइल को खरोंच से खोलती है [1]। इसे Free / NetBSD या Solaris में लागू किया जा सकता है ...
लेकिन ऐसा नहीं है कि यह टूट गया है
मूल रूप से x
(निष्पादित) अनुमति देने का अर्थ है r
किसी भी फ़ाइल पर (पढ़ी गई) अनुमति देना, जिसमें एक शबंग है [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)
फ़ंक्शन को ओवरराइड करता है इसके बजाय इसका उपयोग किया जा सकता है।
और नहीं, इसे सेतु बनाने से एक नियमित उपयोगकर्ता को इसकी सामग्री को देखने से रोका नहीं जा सकेगा; वह बस इसे नीचे चला सकती है ptrace(2)
, जिससे सेतु के टुकड़ों को अनदेखा किया जाएगा:
जड़ के रूप में:
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
"
(क्षमा करें, अगर यह प्रदर्शित करने का सबसे कठिन तरीका नहीं है)
[१] इसे लिनक्स पर प्रयोग करके देखा जा सकता है binfmt_misc
, लेकिन दुभाषिया को संशोधित करना होगा, या एक आवरण का उपयोग करना होगा; एक उदाहरण के लिए इस उत्तर के अंतिम भाग को जानबूझकर असुरक्षित रूप से बनाया गया देखें।
[२] या सामान्य तौर पर, कोई भी फाइल जिसके कारण execve()
वापसी नहीं होगी ENOEXEC
।