感谢某电商平台安全工程师feiyu跟我一起讨论这个漏洞的修复。以往在安全测试的过程中后台经常存在验证码不失效果造成的撞库问题,甚至在一些银行或者电商的登录与查存页面同样存在这个问题,一旦造成撞库无论对用户账号的安全性还是网站的负载都是巨大的挑战。其实造成问题的原因并不复杂,主要是研发在开发过程中缺少对安全的认知,造成的疏忽。
今天心血来潮自己写了个验证码来模拟下出现的问题,首先我们从前端页面开始分析:
<!DOCTYPE html> <html> <head> <meta chartset="utf-8"> </head> <body> <form method="post" action="form.php"> <p>验证码图片:<img border="1" id="capthcha_img" onclick="this.src=‘captcha.php?r=‘+Math.random()" src="captcha.php?r="<?php echo rand();?> width="100" height="30" /> <a href="javascript:void(0)" onclick="document.getElementById(‘capthcha_img‘).src=‘captcha.php?r=‘+Math.random()">换一个</a></p> <p>输入内容:<input type="text" name="autocode" value="" /></p> <p><input type="submit" value="提交" style="padding:6px 20px;"/></p> </form> </body> </html>
可以看出验证码是通过captacha.php来生成。
我们节选captacha.php的关键部分来分析:
$_SESSION[‘authcode‘]=$captch_code;
我们把生成的captch_code以文字形式存在一个临时的session中。
并在前端表单提交后,在form.php中验证POST的验证码是否与Session中的值一致。
<?php if(isset($_REQUEST[‘autocode‘])){ session_start(); if(strtolower($_POST[‘autocode‘]) == $_SESSION[‘authcode‘]){ echo ‘right‘; }else{ echo‘wrong‘; } exit(); } ?>
万事俱备,似乎一切都很完美,一个验证码(机器自动化识别不在本次讨论范围内,TT)。
输入正确返回right:
输入错误范围wrong:
好了,漏洞来了。我们放到burpsuite中愉快的玩耍一下,在提交验证码的过程中抓包、截断、重放一下数据包:
无限重放验证码它就是不失效。
怎么修,这问题愁死我了,想了好久,终于有了点眉目。
其实很早以前我们写测试报告都说应该让存有验证码Session在合适的时间失效,问题是如何实现。考虑了一下,可以通过以下方法处理:
<?php if(isset($_REQUEST[‘autocode‘])){ session_start(); if($_SESSION[‘authcode‘] ==‘NULL‘){ \\通过验证码是否为空检测验证码是否被提交过 echo‘Invalid expired‘; }elseif(strtolower($_POST[‘autocode‘]) == $_SESSION[‘authcode‘]){ echo ‘right‘; }else{ echo‘wrong‘; } $_SESSION[‘authcode‘]=‘NULL‘; \\发起一次form提交后把session值置空 exit(); } ?>
效果如下:
如有不正确,欢迎大家指正。谢谢
时间: 2024-10-20 06:55:43