dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>操作系统>unix>文章内容
UNIX系统编程常用库函数说明(下)
来源:黑客基地 作者:佚名
3. 写安全的C程序

  一般有两方面的安全问题,在写程序时必须考虑:

  (1)确保自己建立的任何临时文件不含有机密数据,如果有机密数据,设置临时文件仅对自己可读/写。确保建立临时文件的目录仅对自己可写。

  (2)确保自己要运行的任何命令(通过system(),popen(),execlp(),execvp()运行的命令)的确是自己要运行的命令,而不是其它什么命令,尤其是自己的程序为SUID或SGID许可时要小心。

  第一方面比较简单,在程序开始前调用umask(077)。若要使文件对其他人可读,可再调chmod(),也可用下述语名建立一个"不可见"的临时文件。

  Creat("/tmp/xxx",0);
  file=open("/tmp/xxx",O_RDWR);
  unlink("/tmp/xxx");

  文件/tmp/xxx建立后,打开,然后断开链,但是分配给该文件的存储器并未删除,直到最终指向该文件的文件通道被关闭时才被删除。打开该文件的进程和它的任何子进程都可存取这个临时文件,而其它进程不能存取该文件,因为它在/tmp中的目录项已被unlink()删除。

  第二方面比较复杂而微妙,由于system(),popen(),execlp(),execvp()执行时,若不给出执行命令的全路径,就能"骗"用户的程序去执行不同的命令。因为系统子程序是根据PATH变量确定哪种顺序搜索哪些目录,以寻找指定的命令,这称为SUID陷井。最安全的办法是在调用system()前将有效UID改变成实际UID,另一种比较好的方法是以全路径名命令作为参数。execl(),execv(),execle(),execve()都要求全路径名作为参数。有关SUID陷井的另一方式是在程序中设置PATH,由于system()和popen()都启动shell,故可使用shell句法。如:

  system("PATH=/bin:/usr/bin cd");
  这样允许用户运行系统命令而不必知道要执行的命令在哪个目录中,但这种方法不能用于execlp(),execvp()中,因为它们不能启动shell执行调用序列传递的命令字符串。

  关于shell解释传递给system()和popen()的命令行的方式,有两个其它的问题:

  *shell使用IFS shell变量中的字符,将命令行分解成单词(通常这个shell变量中是空格,tab,换行),如IFS中是/,字符串/bin/ed被解释成单词bin,接下来是单词ed,从而引起命令行的曲解。

  再强调一次:在通过自己的程序运行另一个程序前,应将有效UID改为实际的UID,等另一个程序退出后,再将有效UID改回原来的有效UID。

  SUID/SGID程序指导准则

  (1)不要写SUID/SGID程序,大多数时候无此必要。
  (2)设置SGID许可,不要设置SUID许可。应独自建立一个新的小组。
  (3)不要用exec()执行任何程序。记住exec()也被system()和popen()调用。

  。 若要调用exec()(或system(),popen()),应事先用setgid(getgid())将有效GID置加实际GID。
  。 若不能用setgid(),则调用system()或popen()时,应设置IFS:
  popen("IFS=\t\n;export IFS;/bin/ls","r");
  。 使用要执行的命令的全路径名。
  。 若不能使用全路径名,则应在命令前先设置PATH:

  popen("IFS=\t\n;export IFS;PATH=/bin:/usr/bin;/bin/ls","r");

  。 不要将用户规定的参数传给system()或popen();若无法避免则应检查变元字符串中是否有特殊的shell字符。
  。 若用户有个大程序,调用exec()执行许多其它程序,这种情况下不要将大程序设置为SGID许可。可以写一个(或多个)更小,更简单的SGID程序执行必须具有SGID许可的任务,然后由大程序执行这些小SGID程序。

  (4)若用户必须使用SUID而不是SGID,以相同的顺序记住(2),(3)项内容,并相应调整。不要设置root的SUID许可。选一个其它户头。

  (5)若用户想给予其他人执行自己的shell程序的许可,但又不想让他们能读该程序,可将程序设置为仅执行许可,并只能通过自己的shell程序来运行。

  编译,安装SUID/SGID程序时应按下面的方法

  (1)确保所有的SUID(SGID)程序是对于小组和其他用户都是不可写的,存取权限的限制低于4755(2755)将带来麻烦。只能更严格。4111(2111)将使其他人无法寻找程序中的安全漏洞。

  (2)警惕外来的编码和make/install方法

  。 某些make/install方法不加选择地建立SUID/SGID程序。
  。 检查违背上述指导原则的SUID/SGID许可的编码。
  。 检查makefile文件中可能建立SUID/SGID文件的命令。

共3页: 上一页 [1] 2 [3] 下一页
上一篇:UNIX系统编程常用库函数说明(上)   下一篇:Linux和Windows系统调用的比较
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·GDB教程
·Linux与Unix二大操作系统编程的
·UNIX的Shell命令使用详解
·Unix发展趋势分析:向开放架构迁
·UNIX系统编程常用库函数说明(上
·Cygwin使用指南
·UNIX的分支 服务器上的FreeBSD操
  相关文章
·UNIX系统编程常用库函数说明(上
·Unix发展趋势分析:向开放架构迁
·UNIX的Shell命令使用详解
·Linux与Unix二大操作系统编程的
·GDB教程
·Cygwin使用指南
·UNIX的分支 服务器上的FreeBSD操
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763