http.jpg

写在前面的话

HTTP认证实现的基础是Web服务器与浏览器之间能够安全地交换类似用户名和密码这样的用户凭证,我们也可以把HTTP认证当作是摘要验证(Digest Authentication),这种预定义方法/标准在HTTP协议中使用了编码技术和MD5加密哈希。在这篇文章中,我们将会跟大家详细讨论一下HTTP认证所采用的技术和标准。为了方便大家的理解,本文将使用我们自己编写的一个php脚本,它可以方便地帮助我们捕获用户名和密码。脚本下载

使用Base64编码的基本访问认证

在了解基本认证这一部分中,我们将使用base64编码来生成我们的加密字符串,这个字符串中将包含用户名和密码。需要注意的是,我们这里还可以选择使用其他的编码技术,例如URL编码或十六进制编码等等。

在下面给出的这个列子中,我们使用Burpsuite捕捉到了用户请求。我们可以看到,Web页面正在向客户端请求输入认证数据:

2.png

我们输入的用户名是“hackingarticles”,密码为“ignite”。

基本认证所采用的请求语句如下:


Value = username:password

Encoded Value =  base64(Value)

Authorization Value = Basic <Encoded Value> 

在基本认证过程中,用户名和密码会被组合成一个单独的字符串,并且使用冒号进行分割。

Value =  hackingarticles:ignite

接下来,浏览器会用base64来对这个字符串进行编码。

3.png

“hackingarticles:ignite”在经过base64编码之后的值即为“aGFja2luZ2FydGljbGVzOmlnbml0ZQ==”。

最终的认证值(Authorization Value)就是“字符串‘Basic’+空格+编码后的值”,Burpsuite捕获的请求如下图所示:

4.png

在这个例子中的认证值就是“Basica GFja2luZ2FydGljbGVzOmlnbml0ZQ==”,而这个值将会被发送至服务器端。最后,服务器会解密这个认证值,然后返回用户输入的凭证。

5.png

基本认证是非常不安全的,因为这里仅仅只使用了编码技术,而认证值是可以被解码的。为了增强认证的安全性,我们接下来会讨论其他一些安全系数更高的标准。

RFC 2069摘要访问认证

摘要访问认证使用了哈希算法来生成加密之后的结果。RFC2069现在已经过时了,目前广泛使用的是RFC 2617,它是RFC2069的增强版。为了让大家更好地理解RFC 2069所使用的请求语句,我们在下面给出了RFC2069的语句样例:


Hash1=MD5(username:realm:password)

Hash2=MD5(method:digestURI)

response=MD5(Hash1:nonce:Hash2)

Hash1(username:realm:password)中包含的是用户名和密码的MD5哈希值,其中的“rea1m”可以是服务器端提供的任意字符串,而用户名和密码则由客户端输入。

Hash2(method:digestURI)中包含的是请求方法和摘要地址的MD5哈希值,请求方法(method)可以是GET或POST,具体需要根据页面所使用的请求方法来确定,而摘要地址(digestURI)则是发送请求的页面地址。

response(hash1:nounce:hash2)中的值是最后需要发送给服务器端的字符串,其中包含的是刚才生成的hash1和hash2,以及一个任意字符串nonce,这个nonce字符串由服务器端发送给客户端,且只能使用一次(相当于一次性验证码)。

RFC 2617摘要访问认证

RFC 2617摘要认证同样使用了MD5哈希算法,但是最终哈希值的生成还需要涉及到一些额外的参数。RFC2617的请求语句如下所示:


Hash1=MD5(username:realm:password)

Hash2=MD5(method:digestURI)

response=MD5(Hash1:nonce:nonceCount:cnonce:qop:Hash2)

与之前一样,Hash1(username:realm:password)中包含的是用户名和密码的MD5哈希值,其中的“rea1m”可以是服务器端提供的任意字符串,而用户名和密码则由客户端输入。

Hash2(method:digestURI)中包含的是请求方法和摘要地址的MD5哈希值,请求方法(method)可以是GET或POST,具体需要根据页面所使用的请求方法来确定,而摘要地址(digestURI)则是发送请求的页面地址。

response((Hash1:nonce:nonceCount:cnonce:qop:Hash2)中的值是最后需要发送给服务器端的字符串,其中包含的是刚才生成的hash1和hash2以及一些额外参数。如果你想了解这些额外参数的话,可以参考微软发布的这篇技术文章【点我点我】。

接下来,我们会给大家介绍RFC 2617的工作机制。首先,Web页面会向客户端请求输入数据:

6.png

我们输入的用户名为“guest”,密码同样为“guest”。在Burpsuite的帮助下,我们捕获到了浏览器发送的请求以及所有的参数,现在我们就可以用其他哈希计算工具来生成输入数据的哈希值,然后再用我们自己生成的数据来与捕获到的哈希数据进行对比。

7.png

我们捕获到的哈希值以及相应参数如下所示:


realm=”Hacking Articles”,nonce=”58bac26865505″, uri=”/auth/02-2617.php”, opaque=”8d8909139750c6bd277cfe1388314f48″,qop=auth, nc=00000001, cnonce=”72ae56dde9406045″ , response=”ac8e3ecd76d33dd482783b8a8b67d8c1″,

Hash1 Syntax=MD5(username:realm:password)

hash1 =  md5(guest:Hacking Articles:guest)

我们自己用工具计算出的MD5哈希值如下所示:


guest:Hacking Articles:guest

Hash:2c6165332ebd26709360786bafd2cd49

8.png


GET:/auth/02-2617.php

Hash:b6a6df472ee01a9dbccba5f5e6271ca8

9.png


response =MD5(2c6165332ebd26709360786bafd2cd49:58bac26865505:00000001:72ae56dde9406045:auth:b6a6df472ee01a9dbccba5f5e6271ca8)

Hash:ac8e3ecd76d33dd482783b8a8b67d8c1

10.png

没错,我们通过Hash Calculator(哈希计算器)自行计算出的哈希值与我们通过Burpsuite捕获到的哈希值是完全一样的。

最后,服务器会解密response的值,输出结果如下图所示:

11.png

总结

我们在这篇文章中跟大家分析了当前HTTP认证的底层加密技术,希望这些内容可以帮助到各位白帽子,给大家在挖洞的过程中提供灵感。

* 参考来源:networkworld, FB小编Alpha_h4ck编译