Linux 和 Unix 安全编程:环境变量

2016-02-19 12:32 7 1 收藏

图老师小编精心整理的Linux 和 Unix 安全编程:环境变量希望大家喜欢,觉得好的亲们记得收藏起来哦!您的支持就是小编更新的动力~

【 tulaoshi.com - 编程语言 】


  环境变量
   缺省情况下,环境变量从进程的父进程继续而来。但是,在程序执行另一个程序时,调用程序可以把环境变量设置为任意值。这对setuid/setgid程序而言很危险,因为其入侵者可以完全控制它们得到的环境变量。由于环境变量一般是继续来的,同样可以传递使用;安全程序可能调用某些其它程序,在没有非凡措施的情况下,这会把有潜在危险的环境变量值传递给调用的程序。
  
   有些环境变量是危险的
   有些环境变量是危险的,因为很多库和程序被环境变量以某些隐含、模糊或未公开的方式所控制。例如,sh和bash shell使用IFS变量来决定哪个字符被用来分隔命令行参数。由于shell是被若干底层调用(如C中的system(3)和popen(3),或Perl中的back-tick算符)执行的,把IFS设置为不平常的值就会搅乱那些看起来安全的调用。该行为在bash和sh里有说明,但不引人注目;许多长时间的用户知道IFS,只不过是因为了解IFS可用来破坏安全性,而不是因为有意经常使用的缘故。更糟的是,不是所有的环境变量都有文档说明,而且即使有,其它的程序也可以改变和增加危险的环境变量。所以唯一的真正解决方案(下文有描述)是只选择所需要的环境变量,不理会其余的环境变量。
  
  环境变量的存储格式是危险的
  一般来说,程序应该使用标准的访问例程来访问环境变量。例如,在C里应使用getenv(3)获取环境变量的值,使用POSIX标准例程putenv(3)或BSD扩展setenv(3)来设置环境变量的值,使用unsetenv(3)来清除环境变量。需要说明的是,Linux下也实现了setenv(3)。但黑客不会这么善良;黑客可以用execve(2)直接控制传递给程序的环境变量数据区。这就可能进行一些肮脏的攻击,只有那些了解环境变量工作实质的人才能理解这些攻击。在Linux下可以阅读environ(5)来了解环境变量工作实质的概要。简而言之,环境变量在内部作为一个指向字符的指针数组的指针来存储;该数组按顺序存储并以NULL指针结尾(这样就可以知道何时数组结束)。指向字符的指针每个都依次指向一个形式为“NAME=value”的以NIL结尾的字符串值。这包含若干意义,例如,环境变量名不能包含等号,而且name或value都不能含有NIL字符。但是,这种格式有一个很危险的含义,就是答应多个入口使用同一个变量名而值不同(如SHELL有多个值)。虽然典型的命令shell禁止这么做,本地操作的黑客可以使用execve(2)制造出这样的情况来。
  
  这种存储格式(以及设置方式)的问题在于程序可能会检查某个值(看看是否合法)而实际上使用的却是另一个不同的值。在Linux下,GNU的glibc库试图保护程序免受此影响:在实现glibc 2.1的getenv时,总是获取第一个匹配的入口,setenv和putenv总是设置第一个匹配的入口,而unsetenv实际上会清除所有匹配入口的设置(应该祝贺GNU的glibc实现者如此实现unsetenv!)。但是,有些程序直接访问环境变量,重复遍历所有环境变量;在这种情况下,它们可能会使用最后一个匹配的入口,而不是第一个。其结果就是假如检查的是第一个匹配的入口,但实际使用的是最后一个匹配的入口,黑客就可以以此来绕过保护例程。
  
  解决方案 -- 提取和清除
  对于安全的setuid/setgid程序,应该小心提取需要作为输入(假如需要的话)的简短的环境变量列表。然后应该清除整个环境,再重新设置一小组必需的环境变量作为安全的值。假如调用了下一级的程序,这实际上并不是什么更好的办法;因为没有可行的办法来列出“所有的危险值”。即使对直接或间接调用的每一个程序的源码都进行了仔细检阅,还是有人可以在你编写完代码后加入新的未公开的环境变量,其中就可能有一个可利用的环境变量。
  
  清除环境的简单方式是把全局变量environ设置为NULL。全局变量environ在中定义,C/C++用户需要#include该头文件。在产生线程前需要处理该值,但这几乎不成问题,因为在程序执行的开始阶段就需要进行这些处理。另一个清除环境的方式是使用未公开的函数clearenv()。clearenv()有个希奇的历史;有人建议在POSIX.1中定义它,但不知什么原因它没有进入标准。尽管如此,POSIX.9(绑定POSIX的Fortran 77)中定义了clearenv(),所以它具有了半官方的地位。clearenv()定义在,但在使用#include包含它之前,必须确定__USE_MISC已经#defined。
  
  一个几乎可以确定会不断添加的值是PATH,一个查找程序的目录列表;PATH应该不包括当前目录,一般应该像“/bin:/usr/bin”那样简单。一般还会设置IFS(其缺省值为“ ”)和TZ(时区)。假如不提供IFS或TZ,Linux也不会死机,但没有TZ值时有些基于System V的系统会出问题,而且据传言某些shell需要IFS值被设置。在Linux下,参见environ(5)以了解可能需要设置的通用环境变量列表。
  
  假如确实需要用户提供的值,首先要检查这些值(以保证这些值与合法值的模式相匹配,而且在某些合理的最大长度之内)。理想情况是在/etc下有些标准的可信赖文件,包含“标准的安全环境变量值”的信息,但是现在没有为此目的定义的标准文件。与此相似,可能需要在那些具有PAM模块的系统里检查PAM模块的pam_env。
  
  
  假如采用不答应直接重新设置环境的语言编写setuid/setgid程序,一个方法是建立一个“包裹”程序。包裹程序把环境程序设置为安全值,然后调用其它程序。注重:确定包裹程序会实际执行预期的程序;假如它是个解释程序,要确定不会出现可能的竞争状态,使得解释器能够载入另一个与授予了非凡的setuid/setgid权限的程序不同的程序。
  
  全文:www.linux.org.tw

来源:http://www.tulaoshi.com/n/20160219/1601134.html

延伸阅读
win7系统怎么删除环境变量?   1、在桌面右击这台电脑,选择属性; 2、在打开的系统窗口左侧,点击高级系统设置; 3、在打开的系统属性窗口中,点击环境变量按钮; 4、将打开环境变量窗口。注意,用户环境变量位于窗口的上方,而系统环境变量位于窗口的下方; 5、如果要删除某个环境变量,则先选中该变量...
标签: 电脑入门
Windows系统环境变量大集合 详细信息 %ALLUSERSPROFILE% 所有用户 Profile 文件位置 %APPDATA% 应用程序数据的默认存放位置 %CD% 当前目录 %CLIENTNAME% 联接到终端服务会话时客户端的 NETBIOS 名 %CMDCMDLINE% 启动当前 cmd.exe 所使用的命令行 %CMDEXTVERSION% 当前命令处理程序扩展版本号 %CommonProgramFiles% 常用文件的文...
标签: windows 操作系统
近日,笔者一个朋友的计算机出现了一个奇怪现象:在Windows XP系统的命令行模式中运行所有命令都提示该命令不是内部或外部命令,也不能运行可执行文件和或批处理文件。 解决篇: 笔者认为是执行这些命令的可执行文件被误删造成的,进入系统安装目录的system32目录中发现ipconfig等可执行文件仍然存在,并没有被删除或改动的迹...
#!/usr/bin/perl #安装说明: #复制程序代码,并存成env.cgi #以ascii模式上传至主机cgi-bin目录后将属性改成755 $|=1; print "Content-type: text/html\n\n"; print " 环境变量清单 \n"; print " \n"; print " \n"; print "\n"; print "\n"; print "变量名称\n"; print "目...
所有使用mysqlclient客户库与服务器通信的MySQL客户使用下列环境变量: 使用MYSQL_PWD是不安全的。见6.3 与MySQL服务器连接。 “mysql”客户使用MYSQL_HISTFILE环境变量中命名的文件来保存命令行历史,历史文件的缺省值是“$HOME/.mysql_history”,这里$HOME是HOME环境变量的值。 所有MySQL程序取许多不同的选项,然...

经验教程

524

收藏

100
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部