2024年1月2日发(作者:)
程序无法找到入口:找出并保护程序的入口
疯狂代码 / ĵ:Security/
本文论述了数据进入您各种途径重点是如何适当地对它们进行处理;您甚至可能还没有了解它们全部!本文首先论述了如何设计来限制数据可以进入您途径以及您设计会如何影响哪些可以成为输入然后论述了各种区别输入通道以及如何使用这些通道包括环境变量、文件、文件描述符、命令行、图形用户界面(GUI)、网络数据以及其他输入
早在 2001 年许多大公司安装了应用“SAP R/3 Web Application Server demo”却没有发现它有个致命漏洞这个应用中有个名为 saposcol 没有能保护自己免受恶意输入值攻击攻击者可以通过设置 PATH 环境变量来改变 saposcol 寻找其他位置然后为 saposcol 创建个恶意“扩展”来运行由于 saposcol 具有 uid root 权限这就意味着这个编程上失误本地用户可以 (作为 root)很快地获得整个计算机系统控制权(参阅 参考资料 中链接以深入了解这点及本文中提到其他相关内容)
本专栏前期文章 指出了些常见输入数据类型以及检查它们思路方法但是如果您不知道所有数据自何处而来那么只是知道如何检查数据类型是不够本文讨论了数据进入您各种区别途径 —— 有些并不是显而易见 —— 并着重讨论了如何适当地去处理它们
如果您不控制攻击者就会来控制
安全中第道防线是检查每个不可信输入但是这是什么意思呢?可以归结为以下 3点:
限制暴露部分如果您分为若干块 —— 这通常是个好主意 —— 那么尽量设计得让攻击者根本不能和大多数块通信这包括不能让他们利用各块的间通信路径如果攻击者不能查看、修改或者插入他们自己数据到那些通信路径中(包括作为块间中间人潜入)那是最好了如果那不可能 —— 比如当块的间使用网络通信时 —— 那么使用加密等机制来防范攻击者后续文章将更深入地讨论这问题
限制暴露部分所允许输入类型有时您可以修改设计以使只有少数输入可以接受 —— 如果可以那么就这样做吧
严格检查不可信输入真正“安全”应该没有任何输入但那种是没有用处因而您需要对来自于不可信源输入路径数据进行严格检查前期文章 论述了如何检查各种区别类型数据;本文将帮助您确定这些数据来源这并不是说您只 需检查进入您数据通常明智做法是检查多个位置数据但是您必须至少检查所有数据次并且明智做法是至少在数据第次进入时进行次检查
类型决定切
您必须检查所有不可信输入 —— 但是什么是不可信输入呢?其中些取决于您要做什么如果您是数据浏览器或者编辑器(比如文字处理器或者图像显示器)而这些数据有可能来自攻击者所以那是不可信输入如果您响应网络上请求那些请求可能正是来自攻击者 —— 所以网络连接是不可信输入
另个重要原因是您是如何设计如果您运行时身份是“root”或者其他些特权用户或者有对数据(比如数据库中数据)访问特权那么从中没有特权部分到那些有特权部分输入是不可信
尤其重要情形是所有“uid”或者“gid”只是运行个 uid/gid 就会获得特权这些特别难以保证安全为什么呢?uid/gid 有特别多输入 —— 它们中很多输入多得惊人 —— 可以被攻击者控制
常见输入源
下面章节将讨论些常见输入以及如何处理这些输入当您编写时候这些输入每个都应该考虑如果它们不可信定要谨慎对它们进行过滤
环境变量
环境变量可能令人难以置信地危险尤其是对那些 uid/gid 及它们危险原因在于以下 3个方面:
许多库和由环境变量以非常含糊方式控制着 —— 实际上很多都完全没有文档化命令 shell /bin/sh 使用 PATH和 IFS 等环境变量加载器 (/lib/.2) 使用 LD_LIBRARY_PATH 和 LD_PRELOAD 等环境变量很多使用 TERM、HOME 和 SHELL 环境变量 —— 所有 这些环境变量都可用于开发这样环境变量数不胜数;对调试来说它们很多都是晦涩变量并且将它们全部列出也是无济于事实际上您不可能了解全部环境变量有些并没有文档化
环境变量是继承而来如果 A B而 B CC D那么 D 将获得环境变量就是 A 所获得环境变量除非有些在这个过程中对其进行了改动这就意味着如果 A 是个安全而 D 开发者为了调试方便而增加了个没有文档化环境变量那么 D这个附加环境变量就会成为 A 个漏洞!这种继承不是偶然 —— 这是为了使环境变量有用 —— 但是这也使的成为个严重安全问题
环境变量可以被本地运行攻击者 完全 控制而且攻击者可以用区别寻常方式来利用这点如 environ(5) 手册页(参阅 参考资料)中所描述环境变量在内部作为指针来存储(以个 NULL 指针结束)每个指针指向个形式为NAME=value(这里 NAME 是环境变量名) 以零结尾(NIL-terminated)串这细节重要性何在?这是攻击者可能会做些不合常理事情例如为同个环境变量名创建多个值(比如两个区别 LD_LIBRARY_PATH 值)这可以很容易地导致库使用环境变量去做意想不到事情有可能被利用GNU glibc 库对此有防范例程但是使用环境变量其他库和任何例程可能很快陷入困境
有些情形下经过了修改以使得难以利用它们来使用环境变量历史上很多攻击利用是命令 shell 处理 IFS 环境变量思路方法但是当今大部分 shell(包括 GNU bash)已经经过了修改从而使 IFS 难以利用
什么是 IFS 问题?
尽管现在已经不是个严重问题但是 IFS 环境变量曾经在老 Unix shell 中导致了很多安全问题IFS 用来确定命令中什么样分隔词被发送到原始 Unix Bourne shell并和其他环境变量样被传递下去通常 IFS 变量应该有个空格、个制表符和个新行值 —— 这些都会被作为个空格来处理但是攻击者可以将 IFS 设置为不怀好意值例如他们可能向 IFS 添加个“/”这样当 shell 试图运行 /bin/ls 时老 shell 将把“/”解释为个空格 —— 也就是说 shell 将运行“bin”(不管在哪儿找到个)并使用“ls”选项!这样攻击者就可以提供个可以找到“bin”
值得欣慰是当今大部分 shell 都对此进行了防范当它们启动时至少会自动重新设置 IFS 变量 —— 包括 GNUbashGNU/Linux 常用 shellGNU bash 还限制了 IFS 使用使的只用于扩展结果这就意味着减少了 IFS 使用而且这样危险度也大大降低了 (早期 sh 使用 IFS 来分离所有词甚至命令)不幸是不是所有 shell 都可以保护自己(Practical Unix & Internet Security —— 参阅 参考资料 中链接 —— 中有测试这问题样例代码)尽管这特定问题已经(大部分)可以防范但它仍以例子证明了没有经过检查环境变量可以带来难以捉摸问题
不幸是尽管这加固措施是个好主意但它还是不够 —— 您还是需要谨慎地去处理环境变量在 Unix 类系统上所有如何运行这是个特别重要(虽然难以理解)例子Unix 类系统(包括 GNU/Linux)首先通过系统加载器来运行(在大部分 GNU/Linux 系统中这个加载器是 /lib/.2)它可以定位并加载所需要共享库这个加载器通常由环境变量来控制
在大部分 Unix 类系统中加载器通常在环境变量 LD_LIBRARY_PATH 中列出目录中开始搜索库我应该介绍说明下LD_LIBRARY_PATH 被很多 Unix 类系统使用但不是全部都用;HP-UX 用是环境变量 SHLIB_PATHAIX 用是LIBPATH而且在 GNU-based 系统(包括 GNU/Linux)中环境变量 LD_PRELOAD 所列出库首先加载并且优先于所有其他库
问题是如果攻击者可以控制用到底层库那么攻击者就可以控制整个例如假设攻击者可以运行/usr/bin/passwd(个可以改变您口令特权)但却用环境变量去改变这个用到库攻击者可以编写自己口令加密crypt(3) 然后当特权尝试这个库时攻击者可以让这个来做任何事情 —— 包括允许永久地、无限制地控制整个系统当前加载器通过检测是否设置了 uid/gid 来防范这问题如果设置了它们就会忽略 LD_PRELOAD 和LD_LIBRARY_PATH 环境变量
那么我们安全了吗?没有如果恶意 LD_PRELOAD 或者 LD_LIBRARY_PATH 值没有被 uid/gid 清除它将被传递到其他并导致出现加载器试图去防范问题因而虽然加载器让编写安全成为 可能但您还不得不去防范恶意环境变量而且这还不能处理那些没有文档化环境变量问题
对于安全 udi/gid 来说惟可靠办法是始终在开始时“提取并清除”环境变量:
提取出您确实需要环境变量(如果有)
清除所有环境变量在 C/C 中通过包含
只将您所需要环境变量设置为可靠值您几乎肯定要重新添加个环境值是 PATH它是搜索目录列表典型 PATH 应该只是设置为 /bin:/usr/bin或者些类似值不要向 PATH 中添加当前路径“.”或者甚至个空条目(这样在开始和结束冒号可被利用)典型您还需要设置 IFS(设置为它默认“ tn” —— 空格、制表符和新行)和 TZ(时区)其他您可能需要设置是 HOME 和 SHELL您应用可能还需要更多但是要限制它们 —— 除非是特别需要否则不要接受
潜在攻击者数据
文件
正如我在前期文章中提到不要信任可以被攻击者设置文件名Linux 和 Unix 允许用任意序列来作为文件名所以如果您正在使用个来自攻击者目录或者接受他个文件名定要有所准备攻击者可以创建以“-”开头文件名或者含有“&”等特殊文件名等等
不要信任可以被不可信用户控制文件内容这包括那些被浏览或编辑可能是由攻击者寄来文件例如著名文本编辑器 vim 版本 5.7当要编辑个文件时将查找个内置 statusline 命令来在它状态行上设置信息而那个命令又可以执行任意 shell 攻击者可以用电子邮件给受害者发送特别处理过文件如果受害者用 vim 来阅读或者编辑它受害者就可能会去运行攻击者想要运行任何!!!
避免从当前目录中获得配置信息用户可能会浏览个由攻击者控制目录攻击者在那里创建了个恶意配置文件(例如攻击者可能已经发送了个包括数据和恶意配置文件压缩目录)而应该从 /etc、用户主目录和/或桌面环境库中获得配置信息通常将配置信息以及其他信息存储在“~/.program-name”文件中是很方便;文件名最前句点是为了让它不影响正常显示如果您真正必须要从当前目录下得到配置信息那么要非常严格地检查其中所有数据
不要让攻击者控制任何临时文件我建议如果个用户是可信那么将临时目录放在那个用户主目录下如果这不可接受那么要用安全思路方法来创建和使用临时文件(我将在后期文章中讨论如何安全地创建临时文件)
文件描述符
不怀好意攻击者可能启动个而只是对它标准输入、标准输出或者标准做些奇怪事情例如攻击者可能会关闭它们中个或多个以使得您打开下个文件同时也是正常输出位置这对 uid/gid 来说尤其是个问题当前些 Unix 类系统已经可以防范这问题但不是所有系统都可以
uid/gid 防范这攻击种思路方法是使用 open 反复打开 /dev/null 直到文件描述符值大于 2(您必须在打开文件前做这件事情最好是在化时)然后如果对 open 第次返回是 2 或者更小那么不输出任何消息并退出通过先反复打开 /dev/null您自己保护了自己 —— 如果您偶尔试图去打开文件并输出消息时不会再发生坏事情在这种情况下不需要输出消息文件描述符 0 到 2 只是在攻击者试图去搅乱您时候才会被关闭
命令行
启动时可以接受来自命令行数据 —— 但是您可以相信这些数据吗?uid/gid 尤其不能如果您不能相信这些数据那就要自己做好切准备包括大参数、大量参数、不可知等等注意名字只是命令行值第 0 个参数 —— 不要 相信名攻击者会改变它
不但如此还要尽力去设计您命令行语法以使它更容易安全地使用例如支持用标准“--”(双破折号)选项来表示
“不再有选项”这样脚本就可以使用这个选项来防止攻击者通过创建以破折号开头文件名 (如“-fr”)来攻击否则攻击者可以创建“-fr”文件并让用户运行“yourcommand *”;这时您可能会将文件名(“-fr”)曲解为个选项
图形用户界面(GUI)
这里是应对灾难个方案:个进程拥有特别特权(例如如果它设置了 uid/gid)它使用操作系统图形用户界面(GUI)库而且 GUI 用户不是完全可信任问题是GUI 库(包括 Unix 、Linux 和 Windows )并不是设计这样使用这样做也不现实 —— GUI 库很大而且依赖于庞大基础结构所以很难为了安全性而去分析所有代码GTK+ GUI 库当发现它是在 uid 中运行时甚至会停止它没有假定会这样使用(感谢 GTK+ 开发者主动预防了这安全问题)
难道这意味着您只能使用命令行?不是将您分为小些部分用没有特权部分去实现 GUI用单独部分去实现需要特权操作下面是些常见做法:
通常简单思路方法是将有特权操作作为命令行来实现由 GUI —— 那样您可以“无偿地”获得 GUI 和命令行界面(CLI)从而简化了脚本编写和调试典型地CLI 特权是个 uid/gid 当然有特权必须保护自己不受攻击但是这个思路方法通常意味着这部分必须是安全这些应更小并且更容易保护
如果您需要高速通信将这个作为有特权启动把它分为可以安全通信独立进程然后将个进程永久释放特权并去运行 GUI
另种思路方法是实现有特权服务器来响应请求并创建 GUI 作为客户机
使用 Web 界面;创建个有特权服务器然后使用 Web 浏览器作为客户机这实际上是先前思路方法个特例但它很灵活因此通常值得考虑如任何其他为我们带来网络数据问题 Web 应用样您将需要使它安全
网络数据
如果数据来自于网络您应该认为它是高度不可信不要相信“源 IP”地址、HTTP“Referrer”头值或者类似数据所告诉您数据来自何方;那些来自发送者值可以被伪造当心来自域名系统(DNS)值;DNS 实现是个分布式数据库那些值中有些可能是攻击者提供
如果您有个客户机/服务器系统服务器应该永远不要相信客户机客户机数据在到达服务器前可以被操纵客户机可能已经被修改或者攻击者可能创建了他们自己客户机(很多这种情况!)如果您正在从 Web 浏览器获得数据不要忘记 Web cookie、HTML 表单数据、URL 等可以被用户设置为任意值这是网络购物车应用中常见问题;许多这样应用使用隐藏 HTML 表单域来存储产品信息(比如价格)和相关信息(比如运费)当用户发送这些值时就盲目地接收用户不仅能将产品价格设置为更低值或者零有时他们还可以设置负值价格以得到商品和附加现金反款记住必须检查 所有 数据;有些网络购物车检查了产品数据却忘记去检查运费
如果您正在编写个 Web 应用查询数据时要限制使用 GET 请求不要让 GET 请求实际上去改变数据(比如传输钱数)或者进行其他行为用户很容易被欺骗去点击他们 Web 浏览器中恶意超链接这样就会发送 GET 请求相反如果
您得到 GET 请求有查询以外行为那么返回个“you asked me to do X,is that okay? (Ok,Cancel)”格式确认消息注意限制 GET 查询不能帮您解决客户机数据问题(如先前段落所讨论) —— 服务器还是需要检查来自它们客户机数据!
其他来源
有很多其他输入比如当前目录、信号、内存映射、 V IPC、umask、文件系统状态有了在这里获得信息重要是不要忽略这些也可以作为输入即使它们有时看起来不像是输入
结束语
安全必须检查每个不可信输入通道这样做可以避免很多问题但是那也还不够有时即使只是读入数据也可以是安全漏洞 —— 甚至在数据被检查的前!处理数据可以导致以可怕方式失败我们将要讨论是当前第 1 号安全漏洞—— 缓冲区溢出我下期文章将论述这个漏洞是什么样如何进行防范以及为什么可以期望它未来将不再是问题
参考资料
阅读 David 安全编程 专栏中 各期文章“开发安全”文介绍了术语和其他基础“验证输入”文论述了对各种数据类型验证
David Secure Programming for Linux and Unix HOWTO(Wheeler2003 年 3 月)书给出了有关如何开发安全软件Software详细描述第 7 章详细论述了 uid 和限制特权
Jochen Hein “SAP R/3 Web Application Server Demo for Linux: root exploit”(Bugtraq2001 年 4 月)文讨论了 SAP 漏洞这个漏洞是 Bugtraq id 2662 和 CVE vulnerability CVE-2001-0366作为 workaround 运行 chmod u-s 来禁止它
“VIM statusline Text-Embedded Command Execution Vulnerability” (Bugtraq, 2001 年 3 月)Bugtraqid 2510讨论了 vim 漏洞这个漏洞是 CVE vulnerability CVE-2001-0408最初发现是 Red Hat RHSA-2001:008-04您可以关闭 .vimrc 中 statusline 或者 stl 选项来禁止它
“Multiple Vendor Web Shopping Cart Hidden Form Field Vulnerability”(Bugtraq2000 年 2 月)Bugtraq id 1237论述了为什么盲目接受来自用户产品价格值是不明智而大量 Web 应用中都存在这个
来自 Beyond-Security's “Well Known Flaw in Web Cart Software Res WideOpen”指出了不仅些购物车没有检查产品价格还有些检查了产品价格却没有检查运费(这样负数运费会带来不正确折扣)
David “Program Library HOWTO”(Wheeler, 2003 年 4 月)文论述了在 GNU/Linux 中如何处理库(包括共享库)
Owen Taylor “Why GTK_MODULES is not a security hole”(, 2000 年 1 月)解释了为什么“使用GTK+ 编写 stuid 和 gid 是不明智而且永远不会得到 GTK+ 团队(Team)支持”并指出当前版本 GTK+ 根本不会运行 uid
Adam Shostack 公布了 uid(7) 手册页 个拷贝
Princeton Computer Science 部门公布了 environ(5) 手册页 个拷贝
在 Simson GarfinkelGene Spafford 和 Alan Schwartz 经典的作 Practical Unix & Internet Security, 3rdEdition(O'Reilly & Associates, 2003 年)书中有些非常好论述第 11 章 论述了 IFS 环境变量
Cameron Laird 在 developerWorks “服务器诊所:实用 Linux 安全性”文中论述了服务器安全
在 developerWorks “软件Software安全性原则”系列文章中Gary McGraw 和 John Viega 给出了在构建安全系统时需要紧记 10 个要点在“构建安全软件Software:选择技术”文章中Gary 和 John 探究了设计者和员面临常见选择
在 IBM developerWorks Linux 专区 阅读更多 Linux 文章
IBM Research Security group 有许多安全相关项目包括 Internet 安全、Java 安全、密码学以及数据隐藏
IBM 白皮书“Secure Internet Applications _disibledevent=>网络安全个好出发点
上篇文章: 组SQLServer身份验证管理子
下篇文章: Imail ;iLDAP溢出分析


发布评论