📄 00000005.htm
字号:
subtotal += usec; <BR> /* if less then 1 msec request, do nothing but remember it */ <BR> if (subtotal < 1000) return(0); <BR> msec = subtotal/1000; <BR> subtotal = subtotal%1000; <BR> return poll(&foo,(unsigned long)0,msec); <BR> } <BR> <BR> 在 System V 或其他 非-BSD 的 Unix 中要使用这类的「小睡」程式,可以用 <BR> Jon Zeeff 的 s5nap,它曾被发表在 comp.sources.misc, volume 4 中。它 <BR> 需要安装一个驱动程式,但是装好後就可以跑得很好。(它的精确度会受到 <BR> kernel 中 HZ 这个变数的影响,因为它是用到了 kernel 中的 delay() 函 <BR> 式。) <BR> <BR> 现在很多较新版本的 Unix 都有提供这类的「小睡」功能了。 <BR> <BR>------------------------------ <BR> <BR>Subject: How can I get setuid shell scripts to work? <BR>Date: Thu Mar 18 17:16:55 EST 1993 <BR> <BR>4.7) 如何让 setuid 的 shell script 可以使用? <BR> <BR> [ 这个问题的回答很长,但是这是一个复杂又常问的问题。在此要谢谢 Maarten <BR> Litmaath 所提供的答案和以下所提到的 "indir" 程式。] <BR> <BR> 先假设你所用的 UNIX 是能认得「可执行的 shell script」的变异过的 UNIX <BR> (如 4.3BSD 或 SunOS)。这类 script 的第一行一定是如以下一般: <BR> <BR> #!/bin/sh <BR> <BR> 这样的 script 就是所谓可执行的 script,因为它和一般可执行的binary 档 <BR> 一样有 magic number 做开头。在我们所用的例子中,magic number 为 <BR> '#!',OS 会把这行接下来的部份当作这整个 script 的解译程式,其後可能还 <BR> 会有一些 option 如: <BR> <BR> #!/bin/sed -f <BR> <BR> 假设这个 script 的名字叫做 'foo',并且放在 /bin 下,那麽如果你用: <BR> <BR> foo arg1 arg2 arg3 <BR> <BR> 那麽 OS 实际在执行时会把它看成是: <BR> <BR> /bin/sed -f foo arg1 arg2 arg3 <BR> <BR> 有一点不同的是:如果 'foo' 被设定成 setuid,那麽 OS 会把它以第一种格 <BR> 式来解释;如果你硬是以第二种格式输入,那麽 OS 会以 /bin/sed 的 <BR> permission 为准,而它当然不会是 setuid。 <BR> <BR> ---------- <BR> <BR> 好吧,那如果我的 shell script 并不是以 '#!' 做开头,或是我的 OS 根本就 <BR> 不认得它呢? <BR> <BR> 嗯,如果这个 shell(或是其他的解译程式)试著要去执行它,那麽 OS 会传回 <BR> 一个错误讯息,表示这个档案不是以合法的 magic number 做开头。收到这个错 <BR> 误讯息後,shell 会把这个档案认定成是 shell script,并以另一种方式来执 <BR> 行: <BR> <BR> /bin/sh shell_script arguments <BR> <BR> 但是我们在前面已经看到了,在这样的情形下,被设成为 setuid 的 <BR> shell_script 并不会发生作用。 <BR> <BR> ---------- <BR> <BR> 那麽,设成 setuid 的 shell script 到底有什麽安全上的问题呢? <BR> <BR> 嗯,假设这个 script 叫做 '/etc/shell_script',它的开头是: <BR> <BR> #!/bin/sh <BR> <BR> 现在我们来看看以下的命令会发生什麽事: <BR> <BR> $ cd /tmp <BR> $ ln /etc/setuid_script -i <BR> $ PATH=. <BR> $ -i <BR> <BR> 我们可以看出来,以上的最後一个命令会被解释成: <BR> <BR> #!/bin/sh -i <BR> <BR> 而这样的命令会让我们得到一个可以输入命令的 shell,并且会被 setuid 成 <BR> 这个 script 的拥有者。 <BR> 幸好,这样的安全漏洞可以很轻易地防止,只需要把第一行改成: <BR> <BR> #!/bin/sh - <BR> <BR> '-' 这个符号代表著它是整个 option list 的结尾:所以如果再用前述的方法 <BR> 的话,'-i' 就会如本来所期望的被解释成 script 档案的名字。 <BR> <BR> ---------- <BR> <BR> 然而,还有更严重的问题: <BR> <BR> $ cd /tmp <BR> $ ln /etc/setuid_script temp <BR> $ nice -20 temp & <BR> $ mv my_script temp <BR> <BR> 第三个命令会被解释成: <BR> <BR> nice -20 /bin/sh - temp <BR> <BR> 而因为这个命令的优先权被设得很低,那麽第四个命令可能就有机会抢先在 <BR> shell 开启 'temp' 之前就用 'my_script' 把 'temp' 给盖掉!有四种方法 <BR> 可以修补这个安全上的漏洞: <BR> <BR> 1) 让 OS 用另一个比较安全的方式执行 setuid script。如 System V R4 和 <BR> 4.4BSD 利用 /dev/fd 来把该 script 的 file descriptor 传给解译程式。 <BR> <BR> 2) 透过一个前端程式来间接解译要执行的 script,以确定在真正的解译程式 <BR> 启动前一切正常。例如,你可以用 comp.sources.unix 中的 'indir' 程 <BR> 式,那麽你的 script 开头就会像这样: <BR> <BR> #!/bin/indir -u <BR> #?/bin/sh /etc/setuid_script <BR> <BR> 3) 造一个 'binary wrapper':一个真正的 setuid 可执行程式,这个程式的 <BR> 唯一功能就是用来执行 script 中所指定的解译程式,并以该 script 的档 <BR> 名为参数传给解译程式。 <BR> <BR> 4) 造一个 'setuid script server' ,并把一些要用到、检查过的 setuid <BR> script 存放在 database 中。当成功地被呼叫後,会去执行正确的解译程 <BR> 式及正确的 script。 <BR> <BR> --------- <BR> <BR> 现在我们已经能确定所解译到的 script 是正确的,那麽还有其他的危险吗? <BR> <BR> 很抱歉,当然还有!在使用 shell scipt 的时候,你一定不能忘记要把 PATH <BR> 这个变数很明确地设到正确的路径去。你能够指出这是为什麽吗?除此之外, <BR> 还有 IFS 这个变数如果没设好也可能会造成麻烦。其他的环境变数也可能会造 <BR> 成安全上的问题,如 SHELL... 更重要的,你必须要确定在 script 中没有命 <BR> 令会让它产生出可下命令的 shell(interactive shell escape)!还有就是, <BR> umask 可能被设成奇怪的值等等... <BR> <BR> 除此之外,你应该要知道 setuid script 会「继承」所有它所用到的命令的 <BR> bug 及安全问题。 <BR> <BR> 总而言之,你应该知道 setuid shell script 真的是件非常危险的事吧! <BR> 最好还是写 C 程式啦。 <BR> <BR>------------------------------ <BR> <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -