我是在dvwa(Damn Vulnerable Web App)上学到的这些东西,我把dvwa安装在了我的免费空间上,有兴趣的可以看看,
web常见攻击四 –不安全的验证码机制(Insecure CAPCTHE)
。DVWA想要用户名和密码的可以联系我:sq371426@163.com
dvwa 用的验证是google提供的,详情见google CAPCTHE
这里所谓的不安全的验证码机制是指对前台获得的验证码在后台验证不够全面引起的安全问题,呵呵,这里比较绕口是吧
下面我们来看一下不安全的代码吧
<table style="border-collapse: collapse; width: 798px; height: 16px; margin: 0px !important; padding: 0px !important; border: 0px !important;"><tbody><tr><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">PHP |</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;"></td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">copy code |</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">?</td><td width="99%" style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;"></td></tr></tbody></table></p><p> <table width="100%" style="border-collapse: collapse; width: 801px; height: 16px; margin: 0px !important; padding: 0px !important; border: 0px !important;"><tbody><tr><td width="1%" style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline;">01</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline;">0203if( isset( $_POST['Change'] ) && ( $_POST['step'] == '1' ) ) {0405$hide_form. = true;06$user = $_POST['username'];07$pass_new = $_POST['password_new'];08$pass_conf = $_POST['password_conf'];09$resp = recaptcha_check_answer ($_DVWA['recaptcha_private_key'],10$_SERVER["REMOTE_ADDR"],11$_POST["recaptcha_challenge_field"],12$_POST["recaptcha_response_field"]);1314if (!$resp->is_valid) {15// What happens when the CAPTCHA was entered incorrectly16echo "17";$hide_form. = false;18return;19} else {20if (($pass_new == $pass_conf)){21echo "22";echo "23<form. action=\"#\" method=\"POST\">24<input type=\"hidden\" name=\"step\" value=\"2\" />25<input type=\"hidden\" name=\"password_new\" value=\"" . $pass_new . "\" />26<input type=\"hidden\" name=\"password_conf\" value=\"" . $pass_conf . "\" />27<input type=\"submit\" name=\"Change\" value=\"Change\" />28</form>";29}3031else{32echo "33";$hide_form. = false;34}35}36}3738if( isset( $_POST['Change'] ) && ( $_POST['step'] == '2' ) )39{40$hide_form. = true;41if ($pass_new != $pass_conf)42{43echo "44";$hide_form. = false;45return;46}47$pass = md5($pass_new);48if (($pass_new == $pass_conf)){49$pass_new = mysql_real_escape_string($pass_new);50$pass_new = md5($pass_new);5152$insert="UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";53$result=mysql_query($insert) or die('5455' );echo "56";mysql_close();57}5859else{60echo "61";}62}6364?>
也许初学者都会这样的代码,但是自习看一看,这段代码存在一个致命的漏洞——虽然在第一步对验证码进行了验证,但是在第二部分却没有对验证码的有效性进行验证。
下面这段代码修复了这个漏洞
<table style="border-collapse: collapse; width: 798px; height: 16px; margin: 0px !important; padding: 0px !important; border: 0px !important;"><tbody><tr><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">PHP |</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;"></td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">copy code |</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;">?</td><td width="99%" style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline; border: 0px !important;"></td></tr></tbody></table></p><p> <table width="100%" style="border-collapse: collapse; width: 801px; height: 16px; margin: 0px !important; padding: 0px !important; border: 0px !important;"><tbody><tr><td width="1%" style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline;">01</td><td style="line-height: 1.5; font-family: 'sans serif', tahoma, verdana, helvetica; vertical-align: baseline;">02if( isset( $_POST['Change'] ) && ( $_POST['step'] == '1' ) ) {0304$hide_form. = true;05$user = $_POST['username'];06$pass_new = $_POST['password_new'];07$pass_conf = $_POST['password_conf'];08$resp = recaptcha_check_answer($_DVWA['recaptcha_private_key'],09$_SERVER["REMOTE_ADDR"],10$_POST["recaptcha_challenge_field"],11$_POST["recaptcha_response_field"]);1213if (!$resp->is_valid) {14// What happens when the CAPTCHA was entered incorrectly15echo "16";$hide_form. = false;17return;18} else {19if (($pass_new == $pass_conf)){20echo "21";echo "22<form. action=\"#\" method=\"POST\">23<input type=\"hidden\" name=\"step\" value=\"2\" />24<input type=\"hidden\" name=\"password_new\" value=\"" . $pass_new . "\" />25<input type=\"hidden\" name=\"password_conf\" value=\"" . $pass_conf . "\" />26<input type=\"hidden\" name=\"passed_captcha\" value=\"true\" />27<input type=\"submit\" name=\"Change\" value=\"Change\" />28</form>";29}3031else{32echo "33";$hide_form. = false;34}35}36}3738if( isset( $_POST['Change'] ) && ( $_POST['step'] == '2' ) )39{40$hide_form. = true;41if (!$_POST['passed_captcha'])42{43echo "44";$hide_form. = false;45return;46}47$pass = md5($pass_new);48if (($pass_new == $pass_conf)){49$pass_new = mysql_real_escape_string($pass_new);50$pass_new = md5($pass_new);5152$insert="UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";53$result=mysql_query($insert) or die('5455' );echo "56";mysql_close();57}5859else{60echo "61";}62}63?>
到这里这段代码算是比较安全的了,但是仔细想想还是觉得这段代码哪里不对劲,是否过于冗余了呢,
电脑资料
《web常见攻击四 –不安全的验证码机制(Insecure CAPCTHE)》(https://www.unjs.com)。下面我们来看精简安全的代码
PHP |copy code |?01
02<?php03if( isset( $_POST['Change'] ) && ( $_POST['step'] == '1' ) ) {0405$hide_form. = true;0607<!--DVFMTSC-->$pass_new = $_POST['password_new'];08$pass_new = stripslashes( $pass_new );09$pass_new = mysql_real_escape_string( $pass_new );10$pass_new = md5( $pass_new );1112<!--DVFMTSC-->$pass_conf = $_POST['password_conf'];13<!--DVFMTSC-->$pass_conf = stripslashes( $pass_conf );14$pass_conf = mysql_real_escape_string( $pass_conf );15$pass_conf = md5( $pass_conf );1617$resp = recaptcha_check_answer ($_DVWA['recaptcha_private_key'],18$_SERVER["REMOTE_ADDR"],19$_POST["recaptcha_challenge_field"],20$_POST["recaptcha_response_field"]);2122if (!$resp->is_valid) {23// What happens when the CAPTCHA was entered incorrectly24echo "25";$hide_form. = false;26return;27} else {28// Check that the current password is correct29$qry = "SELECT password FROM `users` WHERE user='admin' AND password='$pass_curr';";30$result = mysql_query($qry) or die('3132' );if (($pass_new == $pass_conf) && ( $result && mysql_num_rows( $result ) == 1 )){33$insert="UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";34$result=mysql_query($insert) or die('3536' );echo "37";mysql_close();38}3940else{41echo "42";}43}44}45?>