A1-注入 php
A2-跨站脚本(XSS) html
A3-错误的认证和会话管理 web
A4-不正确的直接对象引用 编程
A5-伪造跨站请求(CSRF) -- Cross-Site Request Forgery 浏览器
A7-限制远程访问失败 安全
A8-未验证的重定向和传递 服务器
A9-不安全的加密存储 网络
A10-不足的传输层保护 session
OWASP TOP10排名第3的威胁“遭破坏的认证和会话管理”,简而言之,就是攻击者窃听了咱们访问HTTP时的用户名和密码,或者是咱们的会话,从而获得sessionID,进而冒充用户进行Http访问的过程。 架构
因为HTTP自己是无状态的,也就是说HTTP的每次访问请求都是带有我的凭证的,而SessionID就是为了跟踪状态的,而sessionID自己是很容易在网络上被监听的到,因此攻击者每每经过监听sessionID来达到进一步攻击的目的。
这些漏洞每每会存在于Web页面的“更改个人密码”、“记住个人密码”、“忘记密码”、“安全提问”、“注销登陆”、“邮件地址”等环节上。
那么,通常来讲,如何来防范这种漏洞呢?
第一, 咱们要总体审视咱们的架构
l 认证机制自己必须是简单、集中和标准化的;
l 使用容器提供给咱们的标准session id;
l 确保在任什么时候候用SSL来保护咱们的密码和session id
第二, 验证认证的实现机制
l 检查SSL的实现方法
l 验证全部与认证相关的函数
l 确保“注销登陆”的动做可以关闭全部的会话
l 使用OWASP的WebScrab来测试你的应用
所谓认证,就是创建确信某物或某人是真实的这么一个过程,authentication来自于希腊语αυθεντικός,即真实的,可信的。认证自己依赖于多个认证因子,在计算机安全领域,认证意味着验证通信发起者的数字身份,常见的认证过程就是用户登陆认证,所谓认证测试就是理解系统中的认证机制并找到方法绕过该认证机制。
认证测试须要考虑的点有不少,下面咱们逐一来进行解释说明
l 在加密通道上传递密码
原则上,用户的认证必须经过加密信道进行传输,咱们在这里的目的不是要验证诸如HTTPS是否安全,咱们要验证的仅仅是用户的认证信息是否已经被加密了。
在用户登陆时,最多见的方式是用户输入用户名和密码后,经过POST方法传输,通常来讲,认证信息或者是经过不安全的HTTP传递,或者是经过加密的HTTPS传递。咱们注意到,甚至有些网站在登陆页面显示给咱们的是HTTPS,但事实上却仍然是用HTTP的,最简单的方法就是用网络监听工具,如SnifferPro或Ethereal来判断是不是真实加密了。
下面,咱们用OWASP的WebScrab截取一些信息来作个例子
假设,登陆页面要求用户输入用户名和密码,而后有一个“提交”按钮,那么在WebScrab中咱们获得以下的请求数据:
POST http://www.example.com/AuthenticationServlet HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.14) Gecko/20080404
Accept: text/xml,application/xml,application/xhtml+xml
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.example.com/index.jsp
Cookie: JSESSIONID=LVrRRQQXgwyWpW7QMnS49vtW1yBdqn98CGlkP4jTvVCGdyPkmn3S!
Content-Type: application/x-www-form-urlencoded
Content-length: 64
delegated_service=218&User=test&Pass=test&Submit=SUBMIT
在上面的数据中,咱们能够看到,POST方法经过HTTP协议把数据发送到http://www.example.com/AuthenticationServlet,那么显然在这时,传送的数据没有进行加密,恶意用户经过监听网络就很容易获得用户名和密码。
再看下一个例子,假设是用HTTPS协议,那么请求的头数据以下:
POST https://www.example.com:443/cgi-bin/login.cgi HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.14) Gecko/20080404
Accept: text/xml,application/xml,application/xhtml+xml,text/html
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: https://www.example.com/cgi-bin/login.cgi
Cookie: language=English;
Content-Type: application/x-www-form-urlencoded
Content-length: 50
Command=Login&User=test&Pass=test
可见,上述例子中的数据经加密后被传送到https://www.example.com:443/cgi-bin/login.cgi,这就确保了数据是加密的而不被其余人所窃取。
再看下面的一个例子,咱们在一个能够经过HTTP协议访问到的页面上经过HTTPS协议来发送数据
POST https://www.example.com:443/login.do HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.14) Gecko/20080404
Accept: text/xml,application/xml,application/xhtml+xml,text/html
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.example.com/homepage.do
Cookie: SERVTIMSESSIONID=s2JyLkvDJ9ZhX3yr5BJ3DFLkdphH0QNSJ3VQB6pLhjkW6F
Content-Type: application/x-www-form-urlencoded
Content-length: 45
User=test&Pass=test&portal=ExamplePortal
如上,咱们看到,咱们的请求经过HTTPS引向了https://www.example.com:443/login.do,但若是咱们再看Referer的值,就发现咱们是从HTTP页http://www.example.com/homepage.do过来的。在这种状况下,咱们的浏览器窗口中并不会告诉咱们如今使用的安全链接,而事实上咱们却正在使用安全链接。
在上面的例子中,若是咱们用Get方法,那么所输入的用户名和密码将会以明文的方式显示在URL中,这显然是不可取的。那么,若是咱们经由Get方法经过HTTPS来传递数据是否可行呢,看下面的数据
GET https://www.example.com/success.html?user=test&pass=test HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.14) Gecko/20080404
Accept: text/xml,application/xml,application/xhtml+xml,text/html
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: https://www.example.com/form.html
If-Modified-Since: Mon, 30 Jun 2008 07:55:11 GMT
If-None-Match: "43a01-5b-4868915f"
从上面的例子能够看到,用户名和密码都以明文的方式在URL里存在,而不像上面的几个例子中都在消息体中,但并非说攻击者就能够很容易看到这些信息,TLS/SSL毕竟是安全性很高的协议,整个HTTP数据包是加密的,但仍然要注意的是这些用户名和密码在传输过程当中会被存储在代理和服务器上,这也就有可能会泄露用户信息。
用户列举测试法
这种测试,简而言之是经过与应用的认证机制的交互,尝试可否得到一些正确的用户名,这对后面咱们会讲到的暴力破解颇有效,确认了正确的用户名就能用暴力破解去尝试密码了。
一般,WEB应用对于用户名正确的输入会有一些信息反馈,例如,若是咱们输错了密码,那么有时会反馈告知咱们系统存在该用户,或密码错误。因此,做为测试人员,就要尝试不一样的请求来判断系统是否会有不一样的返回。
对于HTTP的响应消息测试:
输入正确的用户名和密码
指望结果:使用WebScrab抓取服务器的返回信息(HTTP 200 Response,消息的长度)
输入正确的用户名/错误的密码
指望结果:从浏览器咱们每每会获得以下的返回
或者是以下返回
甚至是以下的返回
Login for User foo: invalid password
输入不存在的用户名
指望结果:返回可能以下
或者是以下的消息
Login failed for User foo: invalid Account
一般状况下,对于不一样的出错信息,服务器每每返回的消息是同样的,但若是不一样,测试人员就要去尝试在什么状况下不一样,以下:
客户请求:正确用户/错误密码——>服务器返回:密码错误
客户请求:错误用户/错误密码——>服务器返回:用户不存在。
那么显然第一条就告诉咱们咱们输入的是正确的用户名,经过这种方式咱们就能够得到一些正确的用户名信息。
还有其余一些尝试列举的方法:
有些应用程序会返回一些特定的出错信息;
分析URL以及重定向URL
以下面的URL:
http://www.foo.com/err.jsp?User=baduser&Error=0
http://www.foo.com/err.jsp?User=gooduser&Error=2
上面两个URL都告诉咱们到了错误页面,但上一条是Error值为0,下一条Error值为2,那么咱们能够猜想咱们得到了一个正确的用户名。
URI探测
有时候,Web服务器在接受一个对目录访问请求时,根据目录是否存在会有不一样的返回信息,例如在某些网站会给每一个用户设定一个目录,那么咱们若是尝试访问某个已存在的目录时,它可能的返回页面以下:
403 Forbidden error code
404 Not found error code
举例:
http://www.foo.com/account1-返回的出错信息: 403 Forbidden
http://www.foo.com/account2-返回的出错信息: 404 file Not Found
那么显然,account1是现实存在的。
l 探测性用户帐户测试法
众所周知,在系统中每每会有默认帐户或者很容易被猜到的经常使用帐户,并且每每不少用户会使用默认的密码,一样,有些应用系统的测试帐户研发人员有时也会忘记删除。这个问题事实上是一个漏洞,而这种漏洞每每是因为如下缘由形成的:
没有经验的IT工程师,他们每每不会更改安装的架构组件的缺省密码;
编程人员在应用中留有后门以便测试,但在发布时忘记删除;
系统的管理员和用户采用了很简单的密码;
系统有内嵌的,没法删除的内部用户名和密码
……
对于注入Cisco路由器或WebLogic等,他们都有一些默认的用户名和密码,咱们能够直接尝试,对于一些咱们根本不了解的应用,咱们能够作以下尝试:
尝试如下系统管理员的经常使用帐号——"admin", "administrator", "root", "system", "guest", "operator", "super","qa", "test", "test1", "testing",针对用户名和密码组合尝试,也能够尝试诸如"password", "pass123", "password123", "admin",或guest"这些密码。若是这些都没法成功,咱们能够写一些脚原本尝试相似的用户名和密码组合。
管理员的密码有时会与系统名字相关,如咱们测试的应用系统叫“Obscurity”,那么能够尝试用户名/密码组合Obscurity/obscurity。
利用注册页面咱们也能够猜想用户名和密码的格式和长度。
尝试上述提到的全部用户名和空密码。
查看页面的源文件,尝试找到全部引用到用户名和密码的信息,好比"If username='admin' then starturl=/admin.asp else /index.asp"
寻找那些源文件中注释中可能含有的用户名和密码信息;
…….
l 强力测试(暴力测试)
任何一种技术,在不一样的人手里运用所达到的效果是不一样的,正如暴力测试,也叫暴力破解,安全服务人员和测试人员利用这种技术来验证是否存在漏洞,而攻击者则利用其来寻找漏洞。
Web应用系统一般会有一些用户认证方式,这些方式包括证书、指纹、一次性令牌等等,但更多的,每每是用户名和密码的组合,这就使得暴力破解成为可能。
在对Web应用系统作暴力测试时,首先咱们须要了解的是系统的认证机制,一般Web系统会采用如下两种机制:
HTTP认证——包含基本存取认证和数字存取认证。
基于HTML表单的认证。
咱们下面对这些认证方式作一下简单介绍:
基本存取认证
基本存取认证假设假定用户会以用户名和密码的组合来代表本身的身份,当用户浏览器使用这种机制访问站点时,web服务器将会返回一个包含“WWW-Authenticate”头的401响应,且包含了一个“Basic”值,以及被保护的域名(例如,WWW-Authenticate: Basic realm=”wwwProtectedSite”)客户端会弹出一个须要用户输入该域用户名和密码的提示框。而后,客户端浏览器返回给服务器一个响应,响应包含“Authorization”头,还包含“Basic”值以及链接了用户名,冒号,密码的基于64位的编码(例如,Authorization: Basic b3dhc3A6cGFzc3dvcmQ=),但惋惜的是,这个回复只要被攻击者监听到就很容易被解码。
咱们来看一下这个过程:
1.客户端发送一个标准的HTTP请求
GET /members/docs/file.pdf HTTP/1.1
Host: target
2. web服务器定位到访问的这个资源是在一个受保护的目录;
3.服务器发送一个HTTP 401的认证请求;
HTTP/1.1 401 Authorization Required
Date: Sat, 04 Nov 2006 12:52:40 GMT
WWW-Authenticate: Basic realm="User Realm"
Content-Length: 401
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
4.浏览器弹出要求输入用户名和密码的数据窗口;
5.用户输入用户名和密码后,包含如下数据后再次提交;
GET /members/docs/file.pdf HTTP/1.1
Host: target
Authorization: Basic b3dhc3A6cGFzc3dvcmQ=
6.服务器把客户信息和存储的信息进行比较;
7.若是身份验证正确,服务器发回被请求的内容,若是失败,服务器将会返回HTTP