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

APN设定

APN设定

2016-02-19 12:32

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

  环境变量
   缺省情况下,环境变量从进程的父进程继续而来。但是,在程序执行另一个程序时,调用程序可以把环境变量设置为任意值。这对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
展开更多 50%)
分享

猜你喜欢

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

编程语言 网络编程
Linux 和 Unix 安全编程:环境变量

Linux设置环境变量时如何修改文件

电脑入门
Linux设置环境变量时如何修改文件

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Linux C 函数参考(环境变量 终端控制)

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
Linux C 函数参考(环境变量 终端控制)

Linux系统中清理文件和清理环境变量的方法

服务器
Linux系统中清理文件和清理环境变量的方法

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

创建和访问环境变量

C语言教程 C语言函数
创建和访问环境变量

MySQL 相关的环境变量

编程语言 网络编程
MySQL 相关的环境变量

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

如何知道游戏是否兼容Windows 8系统

如何知道游戏是否兼容Windows 8系统

Java Socket编程(三)服务器Sockets

Java Socket编程(三)服务器Sockets
下拉加载更多内容 ↓