1.1 Password Strength(密码强度)
密码是账户安全的保障,是我们进行身份认证的凭证, 一旦密码泄露,这就意味着可能会给我们带来很大损失(黑客可以通过我们的账号发布一些虚假信息进而欺骗他人,甚至可以获取我们银行卡密码,进而危及我们的财产安全,还涉及了我们的隐私问题), 然而由于我们的习惯问题,我们常常在不同的站点使用相同的密码,甚至我们喜欢使用一些简单的密码,例如123456,8888888等等,另外我们还经常使用姓名和生日等组合而成的有规律性的密码,这就为黑客破解我们的密码提供了方便。因此我们应该遵循密码的基本规则(最小长度,大小写字母、数字、特殊字符的组合使用、避免使用与姓名和生日相关的信息、在不同的站点使用不同的密码等),构建强壮的密码。
在这个实验中我们需要在http://www.cnlab.cn/codecheck网站测试几组密码(下面提供的密码),然后将每一个密码所对应的试探的时间写出来提交即可完成实验。从图 1 中五组数据我们可以看到所提供的密码长度均为 6 但是字母的组合却越来越复杂,这么一个递进关系,让我们切身的感受弱密码和强密码的不同。
图 1
1.2 Forgot Password(忘记密码)
随着互联网时代的到来,web 已经成为一个热点话题,为了账号的安全我们经常选择不对站点进行密码记住,忙碌之余我们难免会忘记某些账号的口令,当然站点的设计者在最初设计站点的时候就考虑到了这个问题,这就为用户的使用提供了很大的方便。但是许多 Web 应用程序的实施机制却并不安全,往往对于验证的信息要求过于简单。
这个练习中,我们的身份是:webgoat,我们密保问题的答案是:red;当我们提交身份认证和正确回答我们的密保问题的时候,web应用就会返回我们忘记的密码。然而我们希望查看账户:admin的密码,但是我们没有他的密保问题的答案,这就需要我们用猜测来完成这个实验。
首先,让我们输入admin点击提交,如图 2 所示,我们会看到如图 3 所示的页面。这时我们随意输入常用的颜色名称,如果错误会出现如图 4 所示的页面,这时我们只需要再次尝试就可以了(最后尝试的结果是 green ),直到出现如图 5 所示的页面,我们可以看到我们成功的获取了账户 admin 的口令。
图 2
图 3
图 4
图 5
1.3 Basic Authentication(基本身份认证)
基本身份认证通常用来保护服务器的资源, Web 服务器将发送 401 认证请求与所请求的资源响应,客户端浏览器将会提示用户在浏览器提供的对话框中输入用户名和密码,浏览器将用户名和密码使用 Base64 编码进行编码,并将这些凭据发送给 Web 服务端。Web 服务端会验证这些凭证,如果所提供的凭据正确,则返回所请求的资源。由于http 传输协议是无状态的协议,因此每一次的访问资源都会对这些凭据进行验证,以便不用每次请求都需要输入用户名和密码,浏览器会在每次请求时自动加载这些凭据信息。其实,我们可以在我们的浏览器中设置“不保存站点的cookie“,然后访问一个需要身份认证的站点,我们会发现即使我们认证成功,但是浏览器还会不停的让我们认证,这就是因为我们身份认证的凭证信息往往是以 cookie 的形式保存在客户端的,当我们设置”不保存站点cookie“时,那么其实我们的身份凭证信息没有被浏览器记录下来,在我们每一次向服务器发送请求的时候,服务器不能自动加载我们的身份凭证信息,那么 Web 服务器收不到这些信息,然后以为我们并未登陆,然后一直要求我们登陆。(感兴趣的可以试一下)
这个练习中我们需要了解 Basic Authentication 的基本过程,然后回答下面两个问题。第一个问题:基本身份认证的标签是什么?(就相当于key->value形式,问我们key是什么);第二个问题:用 base64 编码的身份信息是什么?(就相当于问我们 value 是什么)
那么,我们首先刷新页面,然后用 Webscarab 截获数据并进行分析,如图 6 所示,上面很多内容我们在之前的博客内都有谈过,在这里我们尤为关注的是 Basic 这个词和Authorization这个词,由 http 传输数据的格式,我们不难知道 Authorization 就是我们要找的 value ;而 Basic 为我们的标识符;Z3Vlc3Q6Z3Vlc3Q=是我们的身份信息。然后我们将我们的身份信息复制到 Webscarab -> tools -> transcode 中,采用 Base64 decode 进行解码所得结果如图 7 所示。即我们的身份认证信息是:“guest:guest”,则我们现在可以得到我们问题的答案分别为“Authorization”和“guest:guest”,输入结果并提交我们会发现如图 8 所示,即,我们通过了实验。
图 6
图 7
图 8
虽然我们通过了Basic Authentication 的第一关,但是我们可以看到它要求我们以 (basic,basic)登录,这就需要我们进行身份的再次认证,刚刚我们谈到了 cookie 和Authorization 那么让我们再唠叨几句吧!由于 http 是无状态的,但是我们需要看起来有状态的连接,这就需要我们采用某种特殊的认证方式,常用的是 cookie 和 session 机制,他们保存的都是用户身份的凭证,不同之处在于 cookie 存于客户端,而 session 保存于服务端,但是采用 session 时会产生一个 sessionID ,这个 sessionID是以cookie的形式存于客户端的,每次浏览器发送请求的时候会自动加载这个sessionID,然后服务端对其进行验证,以确信客户端的凭证是否有效。当然如果用户第一次登录的话这个凭证是无效的,服务端检测到这个消息会颁发凭证给客户端。这也意味着我们要实现再次认证的话,既将这个sessionID设置为无效(novalidsession)即可。(在这里特别强调一下,这个sessionID是一个非持久性的 cookie , 在第一次访问时设置,破坏先前的访问请求并不会改变存储在浏览器内存中的 cookie,这就是为什么每次请求都会发送先前的 cookie值)
接下来进入第二步,让你重新使用basic:basic进行认证。首先截取请求,尝试将basic:basic用base64编码一下,替换原来的字符串,系统提示如下:
You're almost there! You've modified the Authorization header but you are still logged in as guest. Look at the request after you typed in the 'basic' user credentials and submitted the request. Remember the order of events that occur during Basic Authentication.的确我改了验证头,但是服务器端依然认为我是以guest身份登陆的。为什么?当我第一次登陆的时候,服务器可能会把我的ip和登陆信息绑定,强制认为这个ip就是用这个登陆信息登陆的,也可能是把我的sessionid和登陆信息绑定,当然作为一个web应用程序,我更愿意做出后一种推断,所以我这次把验证头和session一起改(直接把cookie删掉,验证头改成basic,basic),尝试一下这种方法行不行。结果依然不行,系统提示:的确你让服务器改了session,但没有产生一次重新验证,你需要产生一次重新验证才可以。好既然你让我重新验证,那我直接把验证头和cookie都删掉!。删掉之后果然出现了熟悉的验证框,输入basic,basic后,截取向服务器端发送的请求,然后发现http请求包仍然被浏览器加上了sessionid,果断删掉(浏览器是根据站点cookie加上sessionid的,换言之这个cookie没有过期并且服务器没有通知浏览器sessionid失效,每一个http请求都会加上sessionid),然后发现是一个崭新的webgoat课程,之前的通关记录什么的全没了,点到这一关,果然提示congratulation! 通关!
1.4 Multi Level Login 1 (多级登录1 )
多级登录提供了一个健壮的验证。这是加入第二层的存档,在通过你的用户名和密码登录后,你可以请求一个交易码,这经常用于网上银行。你得到一个银行提供的由很多交易认证号生成的唯一列表,每个交易认证码只能用一次。另一种方法是短信提供一个交易认证号,这样做的好处是攻击者无法获得用户的交易认证号码。
首先,根据提示登录系统,用户名:jane,口令:tarzan,如图 11 所示;然后得到如图 12 中所示,我们需要将隐藏框中的 2 改为 1 ,然后提交,最后得到如图 13 所示的结果,即:实验通过,这种攻击也叫重放攻击。
图 11
图 12
图 13
1.5 Multi Level Login2(多级登录2)
在这个实验中,我们需要尝试破坏这种登录机制,通过其他账号进行登录。你需要做的是在只知道用户名的情况下,通过其他的账号进行登录系统。
首先,我们以 Joe 的账号进行登录,(Joe,banana),如图 14 所示,登录之后我们会发现如图 15 所示,在这里我们输入交易码,并且将隐藏框内的 Joe 改为 Jane,然后提交数据,这时我们用 Webscarab 截获数据会发现,我们提交的数据已经被修改成 Jane 了,如图 16 所示;然后会发现如图 17 所示,即,实验通过了。这个实验的主要问题在于,进行第二层认证的时候默认用户来自于第一层认证的用户,缺少了用户与交易码之间绑定关系的验证。同样我们可以通过绑定交易吗与用户之间的关系进行验证,而不是采用客户端提交的形式进行验证。例如我们可以通过当前提交数据的用户的标识对用户的身份进行确定,而不是采用账户名进行验证。
图 14
图 15
图 16
图 17