⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000011.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
.&nbsp;建立/etc/ptmp和/etc/passwd的链.&nbsp;<BR>.&nbsp;断开/etc/passnnn与/etc/ptmp的链.&nbsp;<BR>注意:临时文件应建立在/etc目录,才能保证文件处于同一文件系统中,建&nbsp;<BR>链才能成功,且临时文件不会不安全.此外,若新文件已存在,即便建&nbsp;<BR>链的是root用户,也将失败,从而保证了一旦临时文件成功地建链后&nbsp;<BR>没有人能再插进来干扰.当然,使用临时文件的程序应确保清除所有&nbsp;<BR>临时文件,正确地捕捉信号.&nbsp;<BR>(3)/etc/group的处理&nbsp;<BR>有一组类似于前面的子程序处理/etc/group的信息,使用时必须用include&nbsp;<BR>语句将/usr/include/grp.h文件加入到自己的程序中.该文件定义了group&nbsp;<BR>结构,将由getgrnam(),getgrgid(),getgrent()返回group结构指针.&nbsp;<BR>*getgrnam():在/etc/group文件中搜索指定的小组名,然后返回指向小组入&nbsp;<BR>口项的指针.&nbsp;<BR>*getgrgid():类似于前一子程序,不同的是搜索指定的GID.&nbsp;<BR>*getgrent():返回group文件中的下一个入口项.&nbsp;<BR>*setgrent():将group文件的文件指针恢复到文件的起点.&nbsp;<BR>*endgrent():用于完成工作后,关闭group文件.&nbsp;<BR>*getuid():返回调用进程的实际UID.&nbsp;<BR>*getpruid():以getuid()返回的实际UID为参数,确定与实际UID相应的登录&nbsp;<BR>名,或指定一UID为参数.&nbsp;<BR>*getlogin():返回在终端上登录的用户的指针.&nbsp;<BR>系统依次检查STDIN,STDOUT,STDERR是否与终端相联,与终端相联的标准输&nbsp;<BR>入用于确定终端名,终端名用于查找列于/etc/utmp文件中的用户,该文件&nbsp;<BR>由login维护,由who程序用来确认用户.&nbsp;<BR>*cuserid():首先调用getlogin(),若getlogin()返回NULL指针,再调用&nbsp;<BR>getpwuid(getuid()).&nbsp;<BR>*以下为命令:&nbsp;<BR>*logname:列出登录进终端的用户名.&nbsp;<BR>*who&nbsp;am&nbsp;i:显示出运行这条命令的用户的登录名.&nbsp;<BR>*id:显示实际的UID和GID(若有效的UID和GID和实际的不同时也显示有效的&nbsp;<BR>UID和GID)和相应的登录名.&nbsp;<BR>(4)加密子程序&nbsp;<BR>1977年1月,NBS宣布一个用于美国联邦政府ADP系统的网络的标准加密法:数&nbsp;<BR>据加密标准即DES用于非机密应用方面.DES一次处理64BITS的块,56位的加&nbsp;<BR>密键.&nbsp;<BR>*setkey(),encrypt():提供用户对DES的存取.&nbsp;<BR>此两子程序都取64BITS长的字符数组,数组中的每个元素代表一个位,为0&nbsp;<BR>或1.setkey()设置将按DES处理的加密键,忽略每第8位构成一个56位的加&nbsp;<BR>密键.encrypt()然后加密或解密给定的64BITS长的一块,加密或解密取决&nbsp;<BR>于该子程序的第二个变元,0:加密&nbsp;1:解密.&nbsp;<BR>*crypt():是UNIX系统中的口令加密程序,也被/usr/lib/makekey命令调用.&nbsp;<BR>crypt()子程序与crypt命令无关,它与/usr/lib/makekey一样取8个字符长&nbsp;<BR>的关键词,2个salt字符.关键词送给setkey(),salt字符用于混合encrypt()&nbsp;<BR>中的DES算法,最终调用encrypt()重复25次加密一个相同的字符串.&nbsp;<BR>返回加密后的字符串指针.&nbsp;<BR>(5)运行shell&nbsp;<BR>*system():运行/bin/sh执行其参数指定的命令,当指定命令完成时返回.&nbsp;<BR>*popen():类似于system(),不同的是命令运行时,其标准输入或输出联到由&nbsp;<BR>popen()返回的文件指针.&nbsp;<BR>二者都调用fork(),exec(),popen()还调用pipe(),完成各自的工作,因而&nbsp;<BR>fork()和exec()的安全方面的考虑开始起作用.&nbsp;<BR>3.写安全的C程序&nbsp;<BR>一般有两方面的安全问题,在写程序时必须考虑:&nbsp;<BR>(1)确保自己建立的任何临时文件不含有机密数据,如果有机密数据,设置&nbsp;<BR>临时文件仅对自己可读/写.确保建立临时文件的目录仅对自己可写.&nbsp;<BR>(2)确保自己要运行的任何命令(通过system(),popen(),execlp(),&nbsp;<BR>execvp()运行的命令)的确是自己要运行的命令,而不是其它什么命&nbsp;<BR>令,尤其是自己的程序为SUID或SGID许可时要小心.&nbsp;<BR>第一方面比较简单,在程序开始前调用umask(077).若要使文件对其他人可&nbsp;<BR>读,可再调chmod(),也可用下述语名建立一个&quot;不可见&quot;的临时文件.&nbsp;<BR>creat(&quot;/tmp/xxx&quot;,0);&nbsp;<BR>file=open(&quot;/tmp/xxx&quot;,O_RDWR);&nbsp;<BR>unlink(&quot;/tmp/xxx&quot;);&nbsp;<BR>文件/tmp/xxx建立后,打开,然后断开链,但是分配给该文件的存储器并未删&nbsp;<BR>除,直到最终指向该文件的文件通道被关闭时才被删除.打开该文件的进程&nbsp;<BR>和它的任何子进程都可存取这个临时文件,而其它进程不能存取该文件,因&nbsp;<BR>为它在/tmp中的目录项已被unlink()删除.&nbsp;<BR>第二方面比较复杂而微妙,由于system(),popen(),execlp(),execvp()执行&nbsp;<BR>时,若不给出执行命令的全路径,就能&quot;骗&quot;用户的程序去执行不同的命令.因&nbsp;<BR>为系统子程序是根据PATH变量确定哪种顺序搜索哪些目录,以寻找指定的命&nbsp;<BR>令,这称为SUID陷井.最安全的办法是在调用system()前将有效UID改变成实&nbsp;<BR>际UID,另一种比较好的方法是以全路径名命令作为参数.execl(),execv(),&nbsp;<BR>execle(),execve()都要求全路径名作为参数.有关SUID陷井的另一方式是&nbsp;<BR>在程序中设置PATH,由于system()和popen()都启动shell,故可使用shell句&nbsp;<BR>法.如:&nbsp;<BR>system(&quot;PATH=/bin:/usr/bin&nbsp;cd&quot;);&nbsp;<BR>这样允许用户运行系统命令而不必知道要执行的命令在哪个目录中,但这种&nbsp;<BR>方法不能用于execlp(),execvp()中,因为它们不能启动shell执行调用序列&nbsp;<BR>传递的命令字符串.&nbsp;<BR>关于shell解释传递给system()和popen()的命令行的方式,有两个其它的问&nbsp;<BR>题:&nbsp;<BR>*shell使用IFS&nbsp;shell变量中的字符,将命令行分解成单词(通常这个&nbsp;<BR>shell变量中是空格,tab,换行),如IFS中是/,字符串/bin/ed被解释成单词&nbsp;<BR>bin,接下来是单词ed,从而引起命令行的曲解.&nbsp;<BR>再强调一次:在通过自己的程序运行另一个程序前,应将有效UID改为实际的&nbsp;<BR>UID,等另一个程序退出后,再将有效UID改回原来的有效UID.&nbsp;<BR>SUID/SGID程序指导准则&nbsp;<BR>(1)不要写SUID/SGID程序,大多数时候无此必要.&nbsp;<BR>(2)设置SGID许可,不要设置SUID许可.应独自建立一个新的小组.&nbsp;<BR>(3)不要用exec()执行任何程序.记住exec()也被system()和popen()调用.&nbsp;<BR>.&nbsp;若要调用exec()(或system(),popen()),应事先用setgid(getgid())&nbsp;<BR>将有效GID置加实际GID.&nbsp;<BR>.&nbsp;若不能用setgid(),则调用system()或popen()时,应设置IFS:&nbsp;<BR>popen(&quot;IFS=\t\n;export&nbsp;IFS;/bin/ls&quot;,&quot;r&quot;);&nbsp;<BR>.&nbsp;使用要执行的命令的全路径名.&nbsp;<BR>.&nbsp;若不能使用全路径名,则应在命令前先设置PATH:&nbsp;<BR>popen(&quot;IFS=\t\n;export&nbsp;IFS;PATH=/bin:/usr/bin;/bin/ls&quot;,&quot;r&quot;);&nbsp;<BR>.&nbsp;不要将用户规定的参数传给system()或popen();若无法避免则应检查&nbsp;<BR>变元字符串中是否有特殊的shell字符.&nbsp;<BR>.&nbsp;若用户有个大程序,调用exec()执行许多其它程序,这种情况下不要将&nbsp;<BR>大程序设置为SGID许可.可以写一个(或多个)更小,更简单的SGID程序&nbsp;<BR>执行必须具有SGID许可的任务,然后由大程序执行这些小SGID程序.&nbsp;<BR>(4)若用户必须使用SUID而不是SGID,以相同的顺序记住(2),(3)项内容,并&nbsp;<BR>相应调整.不要设置root的SUID许可.选一个其它户头.&nbsp;<BR>(5)若用户想给予其他人执行自己的shell程序的许可,但又不想让他们能&nbsp;<BR>读该程序,可将程序设置为仅执行许可,并只能通过自己的shell程序来&nbsp;<BR>运行.&nbsp;<BR>编译,安装SUID/SGID程序时应按下面的方法&nbsp;<BR>(1)确保所有的SUID(SGID)程序是对于小组和其他用户都是不可写的,存取&nbsp;<BR>权限的限制低于4755(2755)将带来麻烦.只能更严格.4111(2111)将使&nbsp;<BR>其他人无法寻找程序中的安全漏洞.&nbsp;<BR>(2)警惕外来的编码和make/install方法&nbsp;<BR>.&nbsp;某些make/install方法不加选择地建立SUID/SGID程序.&nbsp;<BR>.&nbsp;检查违背上述指导原则的SUID/SGID许可的编码.&nbsp;<BR>.&nbsp;检查makefile文件中可能建立SUID/SGID文件的命令.&nbsp;<BR>4.root程序的设计&nbsp;<BR>有若干个子程序可以从有效UID为0的进程中调用.许多前面提到的子程序,&nbsp;<BR>当从root进程中调用时,将完成和原来不同的处理.主要是忽略了许可权限的检&nbsp;<BR>查.&nbsp;<BR>由root用户运行的程序当然是root进程(SUID除外),因有效UID用于确定文&nbsp;<BR>件的存取权限,所以从具有root的程序中,调用fork()产生的进程,也是root进程.&nbsp;<BR>(1)setuid():从root进程调用setuid()时,其处理有所不同,setuid()将把有&nbsp;<BR>效的和实际的UID都置为指定的值.这个值可以是任何整型数.而对非root&nbsp;<BR>进程则仅能以实际UID或本进程原来有效的UID为变量值调用setuid().&nbsp;<BR>(2)setgid():在系统进程中调用setgid()时,与setuid()类似,将实际和有效&nbsp;<BR>的GID都改变成其参数指定的值.&nbsp;<BR>*&nbsp;调用以上两个子程序时,应当注意下面几点:&nbsp;<BR>.&nbsp;调用一次setuid()(setgid())将同时设置有效和实际UID(GID),独立分&nbsp;<BR>别设置有效或实际UID(GID)固然很好,但无法做到这点.&nbsp;<BR>.&nbsp;setuid()(setgid())可将有效和实际UID(GID)设置成任何整型数,其数&nbsp;<BR>值不必一定与/etc/passwd(/etc/group)中用户(小组)相关联.&nbsp;<BR>.&nbsp;一旦程序以一个用户的UID了setuid(),该程序就不再做为root运行,也&nbsp;<BR>不可能再获root特权.&nbsp;<BR>(3)chown():当root进程运行chown()时,chown()将不删除文件的SUID和/或&nbsp;<BR>SGID许可,但当非root进程运行chown()时,chown()将取消文件的SUID和/&nbsp;<BR>或SGID许可.&nbsp;<BR>(4)chroot():改变进程对根目录的概念,调用chroot()后,进程就不能把当前&nbsp;<BR>工作目录改变到新的根目录以上的任一目录,所有以/开始的路径搜索,都&nbsp;<BR>从新的根目录开始.&nbsp;<BR>(5)mknod():用于建立一个文件,类似于creat(),差别是mknod()不返回所打开&nbsp;<BR>文件的文件描述符,并且能建立任何类型的文件(普通文件,特殊文件,目录&nbsp;<BR>文件).若从非root进程调用mknod()将执行失败,只有建立FIFO特别文件&nbsp;<BR>(有名管道文件)时例外,其它任何情况下,必须从root进程调用mknod().由&nbsp;<BR>于creat()仅能建立普通文件,mknod()是建立目录文件的唯一途径,因而仅&nbsp;<BR>有root能建立目录,这就是为什么mkdir命令具有SUID许可并属root所有.&nbsp;<BR>一般不从程序中调用mknod().通常用/etc/mknod命令建立特别设备文件而&nbsp;<BR>这些文件一般不能在使用着时建立和删除,mkdir命令用于建立目录.当用&nbsp;<BR>mknod()建立特别文件时,应当注意确从所建的特别文件不允许存取内存,&nbsp;<BR>磁盘,终端和其它设备.&nbsp;<BR>(6)unlink():用于删除文件.参数是要删除文件的路径名指针.当指定了目录&nbsp;<BR>时,必须从root进程调用unlink(),这是必须从root进程调用unlink()的唯&nbsp;<BR>一情况,这就是为什么rmdir命令具有root的SGID许可的原因.&nbsp;<BR>(7)mount(),umount():由root进程调用,分别用于安装和拆卸文件系统.这两&nbsp;<BR>个子程序也被mount和umount命令调用,其参数基本和命令的参数相同.调&nbsp;<BR>用mount(),需要给出一个特别文件和一个目录的指针,特别文件上的文件&nbsp;<BR>系统就将安装在该目录下,调用时还要给出一个标识选项,指定被安装的文&nbsp;<BR>件系统要被读/写(0)还是仅读(1).umount()的参数是要一个要拆卸的特别&nbsp;<BR>文件的指针.&nbsp;<BR>本文由isbase成员编译或原创,如要转载请保持文章的完整性&nbsp;<BR>欢迎访问我们的站点<A HREF="http://www.isbase.com">http://www.isbase.com</A>&nbsp;<BR> &nbsp;<BR>&nbsp;<BR>--&nbsp;<BR>※&nbsp;来源:·BBS&nbsp;水木清华站&nbsp;bbs.net.tsinghua.edu.cn·[FROM:&nbsp;162.105.17.237]&nbsp;<BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -