02BWAPP通关指北——失效的身份认证和会话管理篇

夺旗攻略 2018-10-21

这个是bwapp教程的第二篇(共十篇,对应owasp top 10 2013),其实十篇的教程早在几个月前都写完了,但是现在回头看看,理解和当时又不太一样,所以这些教程想慢慢发,加深一下自己对于web安全的认识。

作者:古月蓝旻

Broken Auth. - CAPTCHA Bypassing--low

验证码绕过,非常经典的一道题,还记得当年在宫司机的hackinglab里的验证码绕过的题目里也有一道与之非常相似的题目

所谓的验证码绕过主要是指本题的验证码失去了原本的作用,验证码本来主要用于防止暴力破解,在一次错误登录以后,验证码应该也要相应进行变化验证下一次登录,但是本题的验证码并未起到相应的效果,事实上它只要一次正确以后,后续的登录仍可使用该验证码,导致了验证码的失效,我们来看一下实际的操作

首先用户名密码处随便输入,在验证码处输入一次正确的验证码(注意大小写区分)

然后将密码字段添加爆破标记

在payload选项处填写一些随机密码,并将正确密码加入其中,开始爆破

根据返回包的长度差异可以看出其中bug对应的响应包长度有区别,此时查看可以发现显示为“Sucessful login!”,其它密码的的响应包显示为“Invalid credentials! Did you forgot your password?”

说明验证码根本就没有起到相应的效果

为啥会这样?

其实和hackinglab 脚本关的Q7原因是一样的

验证码发布的流程
1. 显示表单
2. 显示验证码(调用生成验证码的程序),将验证码加密后放进 session 或者 cookie
3. 用户提交表单
4. 核对验证码无误、数据合法后写入数据库完成
用户如果再发布一条,正常情况下,会再次访问表单页面,验证码图片被动更新, session 和 
cookie 也就跟着变了。
但是灌水机操作不一定非要使用表单页面,它可以直接模拟 post 向服务端程序发送数据,这样验证码
程序没有被调用,当然 session 和 cookie 存储的加密验证码就是上次的值,也就没有更新,
这样以后无限次的通过post直接发送的数据,而不考虑验证码,验证码形同虚设!
所以,在核对验证码后先将 session 和 cookie 的值清空,然后做数据合法性判断,然后入库!
这样,一个漏洞就被补上了!

之前写hackinglab教程的时候从别的dalao那里看到这句话还是懵懵懂懂,现在终于看懂了,我们结合一下题目源码看看问题所在

题目主干ba_captcha_bypass.php

在low级别下,首先验证会话变量captcha和POST表单提交的变量captcha_user是否相同,过了这一步才去验证帐号密码的正确性

继续往下,验证码的图片通过iframe标签引用自captcha_box.php

captcha_box.php

也就两行内容,分别是

引用验证码图片captcha.php
重新加载验证码图片的JS语句

验证码图片生成captcha.php

验证码内容调用random_string()函数生成,并将其赋值给会话变量captcha
验证码图片使用imagettftext()函数生成

一共分成3步,2、3步之所以分开的原因是方便重新生成验证码图片

有问题吗?

有的,模拟用户正常登录行为,用户提交错误的帐号、密码、验证码后,登录失败,浏览器由于响应包中包含

<iframe src="captcha_box.php" scrolling="no" frameborder="0" height="70"
width="350"></iframe>

会再去加载captcha_box.php,由于captcha_box.php需要captcha.php生成验证码图片,又会调用captcha.php

如上图所示,而在调用captcha.php的过程中,又会生成新的会话变量captcha,使得正常的登录行为验证码的生成不存在问题

但是使用burp等自动暴力破解工具仅对ba_captcha_bypass.php进行暴力破解,对响应包中要去调用captcha_box.php根本不予例会,更不用说进一步调用captcha.php,所以会话变量captcha一直没有更新,原先的POST字段captcha_user一直是可用的

再说一下medium和high等级下的防御思路

增加了一句

if(isset($_SESSION["captcha"])

判断会话变量captcha是不是存在。。。这个讲道理是不能防止我们上面的攻击思路的,因为我们在第一次模拟正常登录行为的时候是获取了会话变量captcha的

同样我们验证一下

在medium和high level下果然还是可以爆破成功的

那么我们怎么防御这种攻击呢?根据上面的描述

在核对验证码后先将 session 和 cookie 的值清空,然后做数据合法性判断,然后入库

其实我觉得其实改一下high里面的验证代码即可

if(isset($_SESSION["captcha"]) && ($_POST["captcha_user"] == $_SESSION["captcha"]))
    {
        if($_POST["login"] == $login && $_POST["password"] == $password)
        {

            $message = "<font color=\"green\">Successful login!</font>";

        }

        else
        {

            $message = "<font color=\"red\">Invalid credentials! Did you forgot your password?</font>";

        }
    }

里面增加一句unset($_SESSION["captcha"]);

if(isset($_SESSION["captcha"]) && ($_POST["captcha_user"] == $_SESSION["captcha"]))
    {
        if($_POST["login"] == $login && $_POST["password"] == $password)
        {

            $message = "<font color=\"green\">Successful login!</font>";

        }

        else
        {

            $message = "<font color=\"red\">Invalid credentials! Did you forgot your password?</font>";

        }
    unset($_SESSION["captcha"]);
    }

实战检验一下,先改一下level为medium

应该是第一个请求出现密码错误,后面的请求出现验证码错误,果然不行了,哈哈哈

正确密码登录无影响,此处不单独截图了

那么问题又来了,为什么我们的思路直接就把medium和high级别的绕过了?

很简单,我们的思路本来就是针对medium和high级别的,low级别的验证码绕过根本不是这个思路

那么我们low级别下到底应该走什么思路呢?

其实源码里面也能推测出来思路,在low级别下并没有验证会话变量captcha是否存在,只是验证了($_POST["captcha_user"] == $_SESSION["captcha"])

那么如果$_SESSION["captcha"]一开始就没有生成,我们也没有提交$_POST["captcha_user"],那么这个逻辑也是成立的,因为双方都是NULL嘛

但是如果你用浏览器访问过一次ba_captcha_bypass.php,那么它会加载captcha_box.php和captcha.php,生成相应的$_SESSION["captcha"],就不为空了

为了做这题我们首先要注销登录一下,然后从头登录,选择本关卡,然后抓包,在响应包里去掉加载captcha_box.php和验证码的代码

这样就不会加载captcha_box.php也就不会生成$_SESSION["captcha"]

此时新的页面长这样

我们输入bee/111登录,抓包,然后爆破

和没有验证码的登录效果一毛一样,非常nice~

Broken Auth. - Forgotten Function--low

一开始挺莫名其妙的一道题,不管输入什么邮箱进去都显示Invalid user!

后来去源码里看了一眼...

原来是比较输入的邮箱是不是在users表里,是的话返回secret,不是返回Invalid user!

由于回显不同,所以这里是可以爆破有效邮箱的

这里简单作个弊,直接通过phpmyadmin去users表里看邮箱(用户root,密码bug)

试一下bwapp-bee@mailinator.com

成功,快撤~

Broken Auth. - Insecure Login Forms--low

非常简单的一题,首先正常登录自然是不行的

看一下响应包

白色字体在搞事情嘛

尝试登录一下,bingo

Broken Auth. - Logout Management--low

嗯,登出管理,一看这个应该和session销毁有关,近期两个APP渗透里都遇到这个问题

这里的here有超链接,点击进入ba_logout_1.php

看一下此时的cookie

放包

出现多个set-cookie并跳转到login.php

看起来需要重新登录一下,实际上目前cookie都是正常的,且没有变化

所以是一个假的注销咯?我们尝试访问一下登录后才能访问的

完全正常好伐?

看下ba_logout_1.php

low级别下do nothing,底下一堆set-cookie和header("Location: login.php");

果不其然,假的注销,只是个跳转,一切都是虚幻的

Broken Auth. - Password Attacks--low

这道题难倒是不难,啥验证码也没有,思路是直接使用burp爆破

但是看源码看得一脸懵逼

先看下ba_pwd_attacks_1.php

上面的代码图就不截取了,完全bwapp代码早期作品,代码不够简洁,一开始差点跑偏,想想也是,这道题确实是爆破第一课

而登录逻辑的核心即没数据库,也不走xpath什么的,直接就是一句

if($_POST["login"] == $login && $_POST["password"] == $password)

好了,找遍整个ba_pwd_attacks_1.php,都没有$login、$password,这里的人都叫它“没了值都”,我的login,在哪TM都在哪?

反正肯定不会找不到,去include里看看

居然真的在admin/settings.php里,而且还在最下面,真是醉了,真TM早期作品

ok,找到出处自然就知道问题所在

Broken Auth. - Weak Passwords--low

这两道题目质量确实比较低啊

弱口令的题目,其实就是拿字典去爆破,但是怎么爆破,用户名是什么呢?

看一下源码吧

所以test/test即可

Session Mgmt. - Administrative Portals--low

提示太明显,把

http://192.168.248.132/bWAPP/smgmt_admin_portal.php?admin=0

改成

http://192.168.248.132/bWAPP/smgmt_admin_portal.php?admin=1

medium和high级别下,把cookie和session中的admin=0改成admin=1即可

以下为4大划水教学题,主要看一下题目不同level下的表现,没什么需要做的

Session Mgmt. - Cookies (HTTPOnly)

cookie添加httponly属性可防止cookie被js操作

Session Mgmt. - Cookies (Secure)

cookie添加secure属性,该cookie仅能通过https进行传输

Session Mgmt. - Session ID in URL

sessionid在会话中可能引起固定会话攻击

Session Mgmt. - Strong Sessions

强session主要是指session生成由强加密/摘要/随机算法生成,并且有httponly,secure属性保护

至此失效的身份认证和会话管理篇结束,新增约7000字


本文由 古月蓝旻 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论