分类:图片,手机或邮箱,语音,视频,操作等
原理:验证生成或验证过程中的逻辑问题
危害:账户权限泄漏,短信轰炸,遍历,任意用户操作等
漏洞:客户端回显(已讲),验证码复用,验证码爆破(已讲),绕过等
鼠标操作、图片里找东西难,因此很难设计出工具或插件,需要手工去测
插件:
captcha-killer
reCAPTCHA
captcha-killer使用
靶场:pikachu 验证码绕过(on server)
判断:
两次使用不同账号密码和相同的验证码情况下(验证码图不同),都报账号或密码错误的话,说明存在验证码复用漏洞。
安全策略:应该每一次验证码用完后销毁该验证码的seesion
靶场:pikachu
如何判断是前端验证还是后端验证
查看网页源代码,可以看出点击后会触发validate()函数
再往下翻发现这个函数的具体代码,我们可以看到验证码的验证机制是在客户端用js代码进行验证的。
我们在burp中进行验证,我们如果不输入验证码或者我们输入一个错误的验证码,我们查看一下返回信息,我们发现服务器返回的信息并没有关于验证码的信息,也就是说服务器没有对验证码进行处理,这就是基于客户端的验证码识别。
<script language="javascript" type="text/javascript">
var code; //在全局 定义验证码
function createCode() {
code = "";
var codeLength = 5;//验证码的长度
var checkCode = document.getElementById("checkCode");
var selectChar = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');//所有候选组成验证码的字符,当然也可以用中文的
for (var i = 0; i < codeLength; i++) {
var charIndex = Math.floor(Math.random() * 36);
code += selectChar[charIndex];
}
//alert(code);
if (checkCode) {
checkCode.className = "code";
checkCode.value = code;
}
}
function validate() {
var inputCode = document.querySelector('#bf_client .vcode').value;
if (inputCode.length <= 0) {
alert("请输入验证码!");
return false;
} else if (inputCode != code) {
alert("验证码输入错误!");
createCode();//刷新验证码
return false;
}
else {
return true;
}
}
createCode();
</script>
只需要一次验证码正确即可,在网页填写正确的验证码后进行抓包,在burpsuite上进行破解。
不安全的验证码-on server常见问题
验证码在后台不过期,导致可以长期被使用;
验证码校验不严格,逻辑出现问题;
验证码设计的太过简单和有规律,容易被猜解
如果验证码长时间未过期,我们可以利用上次的验证码继续暴力破解
如何判断验证码是否会过期?
方法一:
1.先获取提交表单的页面
2.刷新页面获取新的验证码,记下验证码,不提交。
3.放入重放提交表单里。若无提示验证码错误,则说明验证码长时间不会过期。
方法二:
随便填入账号密码,不填验证码,但记下验证码ngvufn,点击login,burpsuite开始抓包,不停forward,直到看到响应的cookie信息,把该包丢掉,这个请求包的cookie存的是本次验证码,如果这个包被允许发送,那么就会更新验证码的cookie。
无法正常返回验证码,说明刚刚被drop(丢弃)的请求包是获取验证码的,所以这时我们试试刚才那个验证码ngvufn
输出用户名或者密码错误,显然该验证码还可用。
如果我们不把那个包Drop掉,正常来说应该返回新的验证码的,但是这没有,因为那个包是去请求/inc/showvcode.php的,会更新cookie值,那么为什么会出现那个请求/inc/showvcode.php的数据包呢,因为在每次(login后)刷新页面会加载二维码图片,图片会去请求/inc/showvcode.php,随后刷新二维码图片。
showvcode.php的具体代码
<?php
session_start();
include_once 'function.php';
//$_SESSION['vcode']=vcode(100,40,30,4);
$_SESSION['vcode']=vcodex();
//验证码绕过 on server 这里其实还是有一个问题,就是服务端将验证码字符串以明文COOKIE的方式给了前端,那验证码还有什么鸟意义。。。
setcookie('bf[vcode]',$_SESSION['vcode']);
?>
因此我们可以先记住验证码,然后登录抓包进行爆破
关键就在于你获取了验证码后,不要刷新页面,直接在请求包中输入验证码然后爆破,如果刷新了验证码,存验证码的cookie就会更新
在这个靶场中能绕过的关键就是session中保存验证码没有更新,那么我们必须在每一次用户验证后重新更新session值。
修改代码:
token解释
靶场:
pikachu
1、在登录的数据包中会存在token值,每次的token值都是不一样的
2、这可以在一定程度上做到防止爆破?
每次发包时token都是不可预计的,所以难以利用常规的字典进行爆破,确实能在一定程度上防止爆破,但是在发送数据包后,response包中有新形成的token值,说明token是在客户端生成的,每刷新一次页面就更新一次token值,而且在回包中可以看中token是在form表单中,type是hidden,说明是隐藏表单,也是为了方便用post方式发送参数值。
3、可以利用burpsuit在每一次发送完数据包后利用回包中的token值。
第一步:
第二步:添加第1,2个的字典
第四步:添加第3个的字典,在options中的grep-Extract点add
第五步:选中红色的值,点击ok
第七步:添加第二个字典,选定recursive grep,burpsuite中强大的功能就体现在这了,可以利用返回包中的值作为字典,然后攻击开始
效果:
爆破成功,利用获得到的password去登录页面登录即可登陆成功
暴力破解是因为允许攻击者“不断试错”而存在的漏洞。
本次学习中提到的有三种类型的暴力破解。
无验证码:利用burpsuite的Proxy功能进行抓包,利用intruder进行字典破解。这里的intruder有四种爆破模式:分别是一套字典爆破一个变量;一个字典爆破两个变量;两个字典一对一爆破两个变量;两套字典相互组合爆破两个变量。
有验证码,但仅在前端利用js脚本验证:只需要输入一次正确的验证码,通过js脚本的验证,将此时抓取的数据包送到intruder即可爆破。因为只在前端验证,当前端验证通过时请求才会被发出,而此时正好可以被burpsuite抓取到,而抓取到的包是被服务器认为是通过验证的,之后也不会有任何验证,于是不需要在意验证码就可以去爆破了。
有验证码,但仅在后端验证且验证码不存在有效期,即服务端没有在验证过后删除session中的旧验证码。只需要刷新一个验证码,又不提交,然后利用之前抓取的包,在请求包里填写最新刷新出来的验证码,将账号密码设为变量即可进行爆破。防范措施:既要在验证之后立即将验证码从session中删除,又要保证不将验证码明文泄露在HTML代码或cookie中。
利用token防御:实则是无效的,因为token是以隐藏表单的形式存放在HTML代码中,也就是说,攻击者时可能获取到该token的。
暴力破解需要好的字典。比如常用密码top100等。
根据表单值长度的限制可以筛选一部分碰撞字段,提高效率。
抵御暴力破解的时候既要考虑易用性也要考虑安全性,不能因为安全而过分影响用户体验,当然一些涉及金钱等应用可以适当牺牲易用性。
接口也叫做API,APl,英文全称Application Programming Interface,翻译为“应用程序编程接口”。是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
简单接口实例介绍:
研发人员A开发了软件A,研发人员B正在研发软件B。
有一天,研发人员B想要调用软件A的部分功能来用,但是他又不想从头看一遍软件A的源码和功能实现过程,怎么办呢?
研发人员A想了一个好主意:我把软件A里你需要的功能打包好,写成一个函数;你按照我说的流程,把这个函数放在软件B里,就能直接用我的功能了!
其中,API就是研发人员A说的那个函数。
调用,遍历,未授权,篡改等
调用案例:短信轰炸
遍历案列:UID 等遍历
callback 回调 JSONP
参数篡改:墨者靶场