安全测试(一):安全测试简介
最近接到关于安全测试的任务,先问了问同在测试行业的一个朋友,安全测试包括系统安全测试和代码安全测试。
先来简单了解下代码安全,通常可以从如下几个方面来审查代码的安全性:
代码以缺省值运行吗?
代码以高优先级运行吗?
代码是否侦听某个网络接口?
网络接口是不可靠的吗?
代码是用C/C++写的吗?
该代码以前是否有历史弱点?
该组件是否由安全研究员做过最终详细审查?
该代码处理敏感或隐私数据吗?
代码是可复用的吗(例如,某个 DLL、C++ 类头文件、库、或程序集)?
很显然,代码安全审查需要审查人员具有一定的编程功底,详细信息可以参阅http://www.51testing.com/html/21/1056.html。一般测试人员普遍关注的是系统安全测试。
系统安全问题中一般包含七个弱点,在这里只把它们一一列出,详细资料可以参阅http://www.djangobook.com/en/2.0/chapter20/(英文)。
● SQL Injection:(SQL注入)
SQL注入是最常见的攻击方式,它的主要原理是:攻击者通过改变WEB页的参数(如GET/POST数据或是URLS)直接将SQL片断提交到服务器,并在服务器端执行。
● Cross-Site Scripting (XSS):(跨站点脚本攻击)
XSS定义:由于WEB程序没有对用户提交的HTML内容进行适当的转译,这样攻击者就可能在你的WEB页中插入一些HTML语句,这些语句通常以<SCRITP>TAG的形式出现。攻击者通常使用XSS攻击来窃取COOKIES 和SESSION信息,或是欺骗用户将隐私信息暴露给错误对象(又称为钓鱼)。
● Cross-Site Request Forgery:(跨站点请求伪造)
CSRF:通过在WEB页或在给用户发邮件中插入恶意代码(通常是链接或是脚本),比如发送一个带有银行取款链接的图片或脚本(通常是HTML或 javascript),当用户访问这个图片时,此时页面加载图片过程会隐密地链接到一个远程页面,这个页面会自动向目标站点发起请求,如果这个目标站点仍保留这个用户的COOKIE信息,并且这个COOKIER未过期,那么攻击者就可以在用户不知情的情况以用户的身份登录银行或执行取款操作。CSRF的特性就是利用网站对用户标识的信任,欺骗用户的浏览器发送HTTP请求给目标站点。
● Session Forging/Hijacking:(Session 伪造/篡改)
Session 伪造/篡改能通过好几种方法对用户的session信息进行攻击,包括:
man-in-the-middle攻击:攻击者在各种有线(无线)网之间畅游的时候窥探用户的session资料。
session 伪造:攻击者用(可能是man-in-the-middle得来的)session资料来伪装成另一用户。
cookie 伪造:攻击者重写cookie中可能是只读的数据。
Session 篡改:攻击者诱导用户设置或者重置自己的session ID。
Session 毒害:攻击者在用户以web形式提交session信息的时候往用户的session资料中注入危险信息。
● Email Header Injection:(邮件标题注入)
邮件标题注入和SQL注入的原理类似,通过在EMAIL的SUBJECT中输入一些特殊语句如” ”,攻击者可以利用这个缺陷通过你的邮件服务器发送垃圾邮件。
● Directory Traversal:(目录遍历)
目录遍历是另一种注入类型的攻击,攻击者欺骗文件系统读写服务器不允许操作的文件。
● Exposed Error Messages:(曝露错误信息)
开发过程中,如果可以看到错误或历史记录对FIX问题是非常有用的。但是如果这些错误信息被攻击者所获取,那么攻击者就可以通过错误信息而了解到应用程序代码或是数据库或是配置等方面的内容,从而为其攻击提供有力的帮助。
安全测试(二):手动测试方法
这里先说一下手动测试的两个出发点,所谓知己知彼,百战不殆,安全测试也要从正反两个方面出发来考虑。一是从己方也就是系统安全本身出发,确保其安全机制正确执行了它们的功能;还有就是从敌方也就是攻击者的角度出发,专门针对模拟攻击者的测试用例。综合这两点,总结了一些方法,由于阅读的资料和相关经验有限,可能不够全面,希望能在将来慢慢补充。
首先是“输入校验”,输入是攻击者与系统最直接的接触方式,据统计,对于一个web应用,输入校验做的好能阻止90%~95%的攻击。那么应该怎样做好输入校验呢?可以参考以下几个步骤:
1、找到web应用所有能够接受用户输入的地方,也就是找到所有输入点;
2、逐个检查每个输入点,确认它们的相应的输入规则和边界。这里最好从合法输入入手,因为你不可能穷举出所有非法输入,但是可以列出所有合法输入;
3、重点关注隐藏域的输入点,比如cookie和URL参数;
4、验证来自数据库的信息,这点比较容易被忽视,因为一般都认为来自数据库的信息可信度是很高的,这也是为什么数据库容易成为攻击点;
5、不光要在客户端进行校验,还要在服务器端进行校验,因为客户端可能会被恶意更改导致危险数据进入系统内部;
6、注意隐藏异常信息,不要让这些信息成为攻击者的切入点。
做完输入校验之后,系统相对来说已经比较安全了,然后再对一些常见的安全点进行测试,从网上总结出了如下一些测试点,可以根据需要选择测试:
1、目录设置:每个目录下应该有index.html或main.html页面,这样就不会显示该目录下的所有内容。选中一幅图片,单击鼠标右键,看是否找到该图片所在的路径。若能找到,在浏览器地址栏中手工输入该路径,看是否发现该站点的信息。
2、SSL:站点使用SSL进行安全传送。进入一个SSL站点是因为浏览器出现了警告消息,而且在地址栏中的HTTP变成HTTPS。开发部门使用了 SSL,测试人员需要确定是否有相应的替代页面。当用户进入或离开安全站点的时候,请确认有相应的提示信息。是否有连接时间限制?超过限制时间后出现什么情况?
3、登录:验证系统阻止非法的用户名/口令登录,而能够通过有效登录。用户登录是否有次数限制?是否限制从某些IP地址登录?如果允许登录失败的次数为 3,你在第三次登录的时候输入正确的用户名和口令,能通过验证吗?口令选择有规则限制吗? 是否可以不登陆而直接浏览某个页面?是否有超时的限制,用户登陆后在一定时间内(例如15分钟)没有点击任何页面,是否需要重新登陆才能正常使用。
4、日志文件:在后台,要注意验证服务器日志工作正常。日志是否记所有的事务处理?是否有恶意操作失败记录?
5、非正常访问:主要用于需要验证用户身份以及权限的页面,复制该页面的url地址,关闭该页面以后,查看是否可以直接进入该复制好的地址。
6、输入框管理:对Grid、Label、Tree view类的输入框未作验证,输入的内容会按照html语法解析出来。
7、缓冲区溢出:没有加密关键数据,在页面输入密码,页面显示的是 *****, 右键,查看源文件就可以看见刚才输入的密码。
8、不安全的存储:包括两个方面。帐号列表:系统不应该允许用户浏览到网站所有的帐号,如果必须要一个用户列表,推荐使用某种形式的假名(屏幕名)来指向实际的帐号;浏览器缓存:认证和会话数据不应该作为GET的一部分来发送,应该使用POST。
9、拒绝服务:攻击者可以从一个主机产生足够多的流量来耗尽狠多应用程序,最终使程序陷入瘫痪。需要做负载均衡来对付。
最后是针对上篇文章中提到的七种常见攻击设计用例进行测试改良,具体方法可以参见以下资料,这里就不详细列出:
中文:http://www.51testing.com/?uid-49689-action-viewspace-itemid-74842
英文:http://www.djangobook.com/en/2.0/chapter20/
这里再提一下之前性能测试中发生的一些错误,现在看来是并发测试对系统安全的影响。最典型的情况是注册(现在改用邮箱验证之后应该不存在此类问题了)和购物,因为是并发,所以它们的提交和处理时间几乎是一样的,于是在判断是否数据库中已经存在该用户名或者是该用户是否有足够虚拟币的时候,因为是同时判断,所以数据库中的记录就不具有绝对的参考价值了,这也就是为什么在并发时会出现同一用户名多次注册以及购物能购到虚拟币为负。这只是一两个例子,仔细检查应该能发现更多的弱点。
总的来说,手动安全测试是很耗费时间和精力的,对测试人员的要求也很高,但也是必不可少的。下一篇文章将介绍如何用工具来进行安全测试,以弥补手动测试的不足。