什么是脆弱点?“可被人利用的漏洞”、“攻击”和“脆弱点”及其他术语通常用于描述合适的软件安全旨在纠正的对象:系统当中让黑客得以获取权限、从而访问信息或者破坏系统的缺陷。Mitre公司对脆弱点的定义是“系统或者网络中的一种状态,这种状态让黑客得以以另一个用户的身份执行命令、访问不该访问的数据、冒充别人,以及/或者发动拒绝服务攻击。”根据这个定义,脆弱性就意味着处于这种状态:攻击者(无论是人,还是像病毒或者间谍软件这些恶意程序)可以访问某个系统中超出其访问权限范围的部分。
导致出现脆弱点的途径很广,有的很明显,比如使用脆弱的密码或者存储未加保护的私人数据;有的则比较隐密,比如未加检查的输入。
·溢出攻击
这种攻击是最早实施的攻击之一,如今依然很普遍;它正是利用了这一点:开发人员想当然地以为最终用户输入的数据值得信任。大多数程序设计员没有料到用户名字段当中居然会有4万行的文本,或者把连键盘上都没有的模糊字符输入到密码字段当中,所以输入数据从来不会被验证正确无误。这种假设导致了溢出类攻击的出现。比方说,使用本文编辑器,加上对微软PowerPoint文件格式的一些了解,人们就可以手动编辑PowerPoint文件。对PowerPoint文件进行编辑,以便内部字段中拥有超出格式允许范围的更多数据,就会导致微软PowerPoint XP崩溃,然后执行攻击者想要执行的任何程序。在大家熟悉的有关这种脆弱点的一个例子中,内嵌的Windows计算器程序被执行;然而,被执行的程序同样很可能是比较恶意的程序。这只是表明无数这种漏洞的一个例子而已。
实质上,溢出类攻击中出现的是,放入了太多的数据,结果原始程序设计员以为绰绰有余的空间装不下这么多数据。多出来的数据就溢出到了预期存储区附近的内存中,并且覆盖了与该存储区的原始用途没有关系的数据。程序的其余部分执行时,它就使用刚被覆盖的数据。如果攻击者能够用伪数据(dummy data)填充足够大的空间(即空操作),然后添加一段恶意代码或者一个值,程序就会执行恶意代码或者使用这个新值。这可能会导致许多不同的后果。攻击者也许能够越过登录这一道机制,获得程序的管理员权限。如果受攻击的程序由系统管理员来启动,那么恶意代码随后将作为原始程序的一部分来运行,为攻击者提供了这个系统的管理员权限。溢出漏洞尽管并非总是很明显,但在一些情况下,很容易得到补救:只要在开发应用程序时,使用“安全”库、使用堆栈保护(即StackGuard),或者对输入数据进行检查,确保数据大小和类型正确。这个漏洞系列的工作方式都很相似,不过受影响内存的类型和预期效果会有所不同。
·缓冲区溢出攻击
在缓冲区溢出攻击的情况下,程序的内部值溢出,结果改变了程序的运行方式。在程序的正常运行过程中,函数被调用后,所调用函数的所有参数连同返回位置的指针都放到堆栈中。函数完成操作后,返回指针用来回到原始位置,程序继续运行。利用缓冲区溢出的攻击可以改变这个过程,让攻击者可以执行他们想要执行的任何函数。实现这种攻击的手段就是,只要输入足够多的数据,使用伪数据来覆盖函数参数,并且使用指向不同函数的新返回指针;现在执行的是新函数。
·SQL注入攻击
除了溢出漏洞外,SQL注入攻击是依赖开发人员忽视了对输入数据进行测试的另一种攻击。大多数人使用的密码采用字母数字;如果是关注安全的人,所用密码除了字母数字外,还会添加其他键盘符号。考虑到这一点,开发人员可能想允许任何字符都适合作为密码的一部分。这通常没什么问题,只要他们不忘清洁或者检查输入数据。遗憾的是,这种不该出现的情况却频频出现。使用SQL数据库的密码系统(这在许多网站上非常普遍)可能运行这样的查询:
SELECT * FROM users WHERE 'username' = '$USER' AND 'password'='$PASS';
$USER 和 $PASS将由用户提供的用户名和密码来代替。所以,如果用户输入了‘bob’和‘1234’,随之得到的查询会是这样子:
SELECT * FROM users WHERE 'username' = 'bob' AND 'password' = '1234';
而来自数据库的返回值将是任何一行行用户名为bob、密码为1234的数据。现在,如果攻击者输入admin和<<'hi' 或 1=1>>--,那么查询是这样子:
SELECT * FROM users WHERE 'username' = 'admin' and `password` = 'hi' OR 1=1--'
请注意:用户输入的引号与原始查询中的第三个引号的匹配情况。现在,数据库会返回用户名为admin的任何行,并且会取消对密码的检查,因为AND 'password' = 'hi' OR 1=1命令数据库寻找密码为hi或者1=1的行;而由于1总是1,所以每行都有可能是返回的对象。--这个SQL注释符取消了查询中原先的多余引号,还会取消任何额外检查;所以,就算有额外证书(即密钥卡或者captcha),它也会被忽略。现在,攻击者可以以管理员身份进入系统,甚至不必提供合法密码。只要使用越来越复杂的查询,攻击者就能变更、添加或者查询数据。这让攻击者对于数据库拥有与应用程序同样的权限。
事实证明,这种脆弱点是针对Web 应用程序最有效的攻击类型之一;随着人们日益依赖 Web 应用程序,这种漏洞的功效只会更加让人望而生畏。好消息是,与溢出类攻击一样,只要清洁输入数据,并且从不立即信任用户输入内容(至少对输入数据),就能在很大程度上预防这种脆弱点。