您的位置:首页 > 其它

UNIX安全问题

2001-06-07 15:02 239 查看
UNIX安全问题
发布日期: 1999-9-27

概要: 

作为设计可靠软件的四月的安全专栏的继续,Peter将必须做的可靠编程技术的快速指南和一些方法上的建议放在一起. 他也包括了很多有价值的联机资源. (3,600词) 在四月份, 我写了一个关于可靠软件设计的专栏,在那里面我批评了SUN和其他的操作系统和软件供应商.事实是,大多数供应商没有一个为适当地创建和再检查代码服务的标准的安全系统. 他们不对那些将在安全上有影响的程序进行代码再检查. 他们也不强有力地坚持那些将避免我们今天看到的许多安全问题的准则. 结果是造成业界今天的现状——太多的安全漏洞, 忠告和补丁. 由于可靠程序设计的重要性,以及牵涉到读者的巨大利益,我们重新回到这个主题. 这个月,我们将在安全专家Spafford 和Matt Bishop提供的资料的基础上进一步扩展四月的专栏.这个专栏尝试搜集当前关于完整的UNIX程序设计FAQ的真知灼见.
我们希望你将发现它有用,它将使你写安全的代码的任务更加轻松. 所有的FAQs, 注解, 建议和校正都会受到欢迎.我们将应要求定期出版更新.
0. 概述
1. 这些方法应该何时使用?
2. 安全性设计原则
3. 可靠的程序设计方法
4. 不可靠的程序设计方法
5. 测试程序安全性

0. 概述 太多的程序有安全上的漏洞. 在目前的业界, 发布代码只经过很少的测试,很少或根本没有可靠编程技术.这个FAQ力图成为程序员的工具,使编写可靠程序的过程更轻松. 应用好程序设计技术是重要的, 即使你的代码只在有限的情形或有限的时间内使用. 许多程序的使用都超出了他们的原来的计划范围.
Ivan Krsul 在Purdue大学做他的博士论文时发现, 历史上的大部分的安全性缺陷都是程序运行于和他们的设计者所知道或所想象的不同环境的结果.例如,程序员可能认为某个系统调用永远不会失败,或程序永远不会调用非文本的参数.因此,一个程序员所能做的确保代码可靠的最好的事情之一就是质疑假设,仔细地想它们是否有效并且设想它们失效的条件。 这个FAQ试图编纂将被用在能影响系统安全性的任何程序中的思想, 技术,步骤, 和系统调用.
1. 这些方法应该何时使用? 如果这些可靠的程序设计方法在所有的程序上使用了,那将是最好不过的. 毕竟它们大多数是简单良好的程序设计技术,不管程序是否相应的安全. 然而, 在每个程序中实现所有这些技术将比不用他们付出更多的时间和努力. 因此,如果这些方法无法每一处都使用, 他们起码也应该用在"重要"的程序中. 这些方法特别应该用于以下情况:  
所有的setuid 和setgid 程序
所有的网络daemons(接受网络连接的程序)
所有的要求细小的安全性的程序(例如,检查一文件的访问许可并打开它)
接受外界输入或使用从外部环境中获得的信息的程序 (例如: 为用户服务的邮件代理程序, spawning子进程路径变量)
作为系统管理使用的程序
2. 安全设计原则
不管所使用的程序语言,程序的目的和写程序所用的技术,下面这些原则都有助于确保程序尽可能地不犯错误:

1.最少的特权. 程序使用最起码够用的特权去完成任务. 问"软件需要什么特权?" ,不问 "软件想要什么特权?"

2.经济的机制. 短小,简单的代码中的错误将比长的,复杂的代码中的要少. 决定执行作业所必要的最小值.
3.完全的中介. 检查对每一对象的每个访问, 每一调用的每个返回值, 和在每一判定点的每个变量值.
4.开放式设计. 不把要安全性寄托在晦涩上.
5.分离的特权. 在不同的时间、不同的例程或程序中保持必要的特权.
6.最起码的通用机制. 用户应该尽可能少地共享资源; 使共享资源减到最少.
7.心理的可接受程度. 安全性控制必须容易使用,否则他们将被用户忽略.
8.故障安全默认. 把拒绝作为缺省值,失败将被"关闭" (没有允许请求).
9.代码重用.当可能时重用以前测试过的代码.
10.怀疑未知. 任何由用户提供或从外部提供的东西都是值得怀疑的.
11.要有先见之明. 判断从你们的程序的功能中会产生什么安全问题并且在你开始编写程序以前就计划尽量这些问题.
3.安全的程序设计方法

依靠以下这些好的编程序实践和可靠的软件准则实现软件.关于编程技术,系统调用,库调用的适用的信息并不是举手可得的. Simson Garfinkle 和 Gene Spafford的《Practical Unix and Internet Security》的第23章有关于可靠编程和不可靠编程技术的大量有价值的资料.我在这里摘录了一些.

检查所有的命令行参数.

检查所有的系统调用参数和系统调用返回值.
检查在环境中传递的参数,不依赖Unix环境变量.
肯定所有的缓冲区是有边界的.
在内容被拷贝到本地的缓冲区以前,对每个变量做边界检查.
如果创建一个新文件,使用O_EXCL 和O_CREAT 标志确认文件尚未存在.
如果适当的话,使用lstat() 去保证一个文件不是一个链接.
使用下列库调用而不是用他们的替代者: fgets(), strncpy(), strncat(), snprintf(). 一般说来,使用检查长度的函数(终止符检查是不够的).
同样,小心地使用execve(), 如果你必须产生一个进程.
在程序开始处明确地更改目录(chdir()) 到一适当的目录.
设置限制值,使得程序失败时无法创建的一个核心文件:一个核心文件能持有内存中的口令或状态信息.
如果使用临时文件,考虑使用tmpfile() 或mktemp() 系统调用去创建它们(虽然大多数mktemp() 库调用存在有疑问的竞态条件).
有内部的一致性检查代码. 包括大量的记录,包括日期,时间,uid和有效uid, gid和有效 gid, 终端信息, pid,命令行参数, 错误以及起源主机..
程序的关键部分应尽可能的简短.
总是在任何文件参数中使用完整路径名.
检查用户输入以肯定它仅仅包含"善意"的字符.
使用好象lint这样的工具.
了解竞态条件, 包括死锁条件和排序条件.
当有来自网络的读请求时,设置超时限制和装载等级限制.
当有面向网络的写请求时,设置超时限制.
使用加密的通用任务程序以避免被劫持并且隐藏验证信息.
只要可能,使用chroot() 将程序上下文放到系统的一个子集中.
如果可能,静态地连接安全程序.
当你需要一个主机名时,在一连接上反转DNS 查找.
在网络守护程序中分散或限制过度的负担.
在网络读写时设置合理的超时限制.
如果适当,阻止多于一个拷贝的网络守护程序运行.
4. 不可靠的程序设计方法

当操作字符串,尤其是使用get(), strcpy(), strcat(),sprintf(), fscanf(), scanf(), vsprintf(), realpath(), getopt(), getpass(), streadd(), strecpy(), 和 strtrns()时,避免例程检查缓冲区边界失败. 类似的,防止execlp() 和execvp()失败. 从不使用system() 和popen() 系统调用.

不在world-writable目录创建文件.
通常,别创制setuid 或setgid 外壳脚本.
别作关于端口数的假设,要使用getservbyname().
别假定来自低数字端口的连接是合法的或可靠的.
别信任任何IP地址; 如果你想要确认真伪,使用密码学. (反转DNS 查找提供最小的级别的保证.)
别要求明文验证信息.
随机数生成器避免使用任何可猜测或可重演的种子.
别尝试从一严重的错误恢复; 输出详细数据并终止.
代码的括号部分要求有setuid()和 setgid()函数的更高权限.
考虑使用perl -T 或taintperl去编写setuid程序.
5. 测试程序安全性

使用和骇客(cracker)一样的方法来测试软件:

尝试在每个包中溢出缓冲区
尝试滥用命令行选项
尝试创造每一个想象得到的竞态条件
有设计者和实现者之外的人检查测试代码
阅读代码,象一个骇客(cracker)那样想问题, 寻找脆弱的地方 采取提高软件质量的步骤, 减少代码中的错误, 特别是安全漏洞. (请检验以下资源以获得更多的联机的信息.)
工具
可获得tripwire的一个新的商业版本. 详情请见visualcomputing 的主页.
信件
在上个月的专栏里, 我包括了一封请求帮助保护补网蜂窝环境下的Web文档新闻组的公开信, Gene Spafford的回信中提供了一种用来保护COAST archives的方法. 看来正是这一问题的解答.
Peter,  
我读到了你的信,你说有人问在补网蜂窝环境下的文档保护问题,你不知道解决的办法.
我有回送安装和NFS安装到chrooted服务器环境下的成功经验. 例如, 如果你执行一回送只读的安装到服务器的文件系统,它将帮助保护文件就象设置文件的可用出口一样. 同时, 你能经由一些另外的机制制作用对维护者可用的"真实"文件. 我们一直这样维护COAST archive将近四年了.
再见,
Gene Spafford
Gene 注意到回送安装的文件系统上的文件是不可改变的. Sun的有关文档说有这合适特权的进程能够改变回送安装的文件系统上的文件. 关于这个功能的证明还不清楚.因此,当它提供了对内容的另一层保护时,它并不向所希望的那样安全.
资源"设计可靠软件"
1998年四月安全专栏 http://www.sunworld.com/swol-04-1998/swol-04-security.html 1998年七月安全专栏 http://www.sunworld.com/swol-07-1998/swol-07-security.html  
Ivan Krsul的论文(krsul-phd-thesis.pdf or krsul-phd-thesis.ps.Z) ftp://coast.cs.purdue.edu/pub/COAST/papers/ivan-krsul/  
在 COAST能找到也许是最好的关于信息、程序、和指向其他安全站点的链接的单一来源 http://www.cs.purdue.edu/coast/  关于Unix的安全和可靠编程的详细信息请参阅 Simson Garfinkle 和Gene Spafford 的Practical Unix and Internet Securityhttp://www.amazon.com/exec/obidos/ISBN=1565921488/sunworldonlineA  
Matt Bishop的 关于安全编程的谈话, 指导,和文章可在以下 Web网址找到 http://seclab.cs.ucdavis.edu/~bishop/secprog.html  
SunWorld上的完整的安全专栏列表 http://www.sunworld.com/common/swol-backissues-columns.html#security  
SunWorld站点索引上的相关的网络安全描述
http://www.sunworld.com/common/swol-siteindex.html#netsec
Peter Galvin'的Solaris 安全 FAQ http://www.sunworld.com/common/security-faq.html  *<安全设计原则的头七条来自 Saltzer 和 Schroeder's 文章:The Protection of Information in Computer Systems, Proceedings of the IEEE, September 1975.
关于作者 
Peter Galvin 是 Corporate Technologies Inc.公司的首席技术专家,一个系统集成者和VAR. 他是Brown大学的计算机科学系附属系统的计划人员,他一直是过去四届SUG/SunWorld 会议的主席. 作为一个顾问和训练人员, 他在系统管理和安全性的问题上在世界范围内给予给谈话和指导.他为Byte 和Advanced Systems (SunWorld) 杂志, 以及Superuser时事通讯写文章. Peter 是最畅销的 Operating Systems Concepts 教科书的合著者. Peter的邮件地址是peter.galvin@sunworld.com.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: