浙江省住房和城乡建设部网站,酒店网站建设策划方案,山西太原发现1例阳性,天津网站建设 企航互联CSRF(跨站请求伪造)简介概念 CSRF#xff08;Cross—site request forgery#xff09;#xff0c;跨站请求伪造#xff0c;是指利用受害者未失效的身份认证信息#xff08;cookie#xff0c;会话等#xff09;#xff0c;诱骗其点击恶意链接或者访问包含攻击代码的页面…CSRF(跨站请求伪造)简介概念 CSRFCross—site request forgery跨站请求伪造是指利用受害者未失效的身份认证信息cookie会话等诱骗其点击恶意链接或者访问包含攻击代码的页面在受害人不知情的情况下以受害者的身份向身份认证信息所对应的服务器发送请求从而完成非法操作如转账改密等。 CSRF与XSS的区别 CSRF属于业务逻辑漏洞在服务器看来所有的请求都是合法正常的 XSSSQL注入等等都是属于技术漏洞 XSS客户信任服务器 CSRF服务器信任客户经过身份认证的 CSRF攻击成功的前提 用户必须登录 黑客必须懂得一些发包的请求 服务器端不会有二次认证 被害者是不知情的 危害 修改用户信息如用户头像、发货地址等 个人隐私泄露机密资料泄露 执行恶意操作如修改密码购买商品转账等盗用受害者身份受害者能做什么攻击者就能以受害者身份 具体操作请看这篇文章pikachu靶场-csrf_pikachu csrf黑名单-CSDN博客
low等级
?phpif( isset( $_GET[ Change ] ) ) {// Get input$pass_new $_GET[ password_new ];$pass_conf $_GET[ password_conf ];// Do the passwords match?if( $pass_new $pass_conf ) {// They do!$pass_new ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $pass_new ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$pass_new md5( $pass_new );// Update the database$insert UPDATE users SET password $pass_new WHERE user . dvwaCurrentUser() . ;;$result mysqli_query($GLOBALS[___mysqli_ston], $insert ) or die( pre . ((is_object($GLOBALS[___mysqli_ston])) ? mysqli_error($GLOBALS[___mysqli_ston]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res : false)) . /pre );// Feedback for the user$html . prePassword Changed./pre;}else {// Issue with passwords matching$html . prePasswords did not match./pre;}((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res);
}?只是对输入的pass_new和pass_conf进行了比较没有进行其他的防御因此只要用户在cookie还有效的时间内在相同的浏览器访问我们给定的url该操作是服务器对请求的发送者进行了身份验证检查cookie就可以实现CSRF 攻击最终修改密码。
medium等级
?phpif( isset( $_GET[ Change ] ) ) {// Checks to see where the request came fromif( stripos( $_SERVER[ HTTP_REFERER ] ,$_SERVER[ SERVER_NAME ]) ! false ) {// Get input$pass_new $_GET[ password_new ];$pass_conf $_GET[ password_conf ];// Do the passwords match?if( $pass_new $pass_conf ) {// They do!$pass_new ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $pass_new ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$pass_new md5( $pass_new );// Update the database$insert UPDATE users SET password $pass_new WHERE user . dvwaCurrentUser() . ;;$result mysqli_query($GLOBALS[___mysqli_ston], $insert ) or die( pre . ((is_object($GLOBALS[___mysqli_ston])) ? mysqli_error($GLOBALS[___mysqli_ston]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res : false)) . /pre );// Feedback for the user$html . prePassword Changed./pre;}else {// Issue with passwords matching$html . prePasswords did not match./pre;}}else {// Didnt come from a trusted source$html . preThat request didnt look correct./pre;}((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res);
}?使用$_SERVER[HTTP_REFERER]获取请求的来源页面URL。使用$_SERVER[SERVER_NAME]获取当前服务器的域名。使用stripos()函数不区分大小写地查找字符串首次出现的位置来检查请求来源URL是否包含当前服务器的域名。 假如服务器地址为192.168.101.66即为SERVER_NAME我们只需要把我们构造的恶意页面文件名改为192.168.101.66.htmlHTTP_REFERER就会包含192.168.101.66.html,就可以绕过stripos了。 这个对于本地搭建的DVWA是无效的
high等级
?php$change false;
$request_type html;
$return_message Request Failed;if ($_SERVER[REQUEST_METHOD] POST array_key_exists (CONTENT_TYPE, $_SERVER) $_SERVER[CONTENT_TYPE] application/json) {$data json_decode(file_get_contents(php://input), true);$request_type json;if (array_key_exists(HTTP_USER_TOKEN, $_SERVER) array_key_exists(password_new, $data) array_key_exists(password_conf, $data) array_key_exists(Change, $data)) {$token $_SERVER[HTTP_USER_TOKEN];$pass_new $data[password_new];$pass_conf $data[password_conf];$change true;}
} else {if (array_key_exists(user_token, $_REQUEST) array_key_exists(password_new, $_REQUEST) array_key_exists(password_conf, $_REQUEST) array_key_exists(Change, $_REQUEST)) {$token $_REQUEST[user_token];$pass_new $_REQUEST[password_new];$pass_conf $_REQUEST[password_conf];$change true;}
}if ($change) {// Check Anti-CSRF tokencheckToken( $token, $_SESSION[ session_token ], index.php );// Do the passwords match?if( $pass_new $pass_conf ) {// They do!$pass_new mysqli_real_escape_string ($GLOBALS[___mysqli_ston], $pass_new);$pass_new md5( $pass_new );// Update the database$insert UPDATE users SET password . $pass_new . WHERE user . dvwaCurrentUser() . ;;$result mysqli_query($GLOBALS[___mysqli_ston], $insert );// Feedback for the user$return_message Password Changed.;}else {// Issue with passwords matching$return_message Passwords did not match.;}mysqli_close($GLOBALS[___mysqli_ston]);if ($request_type json) {generateSessionToken();header (Content-Type: application/json);print json_encode (array(Message $return_message));exit;} else {$html . pre . $return_message . /pre;}
}// Generate Anti-CSRF token
generateSessionToken();?设置了token限制它是在每次访问此页面时会随机生成一个token当发起服务器请求时服务器会检查它的值。
思路先获取token的值再构造链接并诱骗受害者访问。
利用以下payload在反射型xss中获取到token值不要点确认否则会重新生成新的token
iframe src../csrf/ onloadalert(frames[0].document.getElementsByName(user_token)
[0].value) 在 bp抓包中替换掉已经抓到的token即可实现修改密码
Impossible等级
?phpif( isset( $_GET[ Change ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php );// Get input$pass_curr $_GET[ password_current ];$pass_new $_GET[ password_new ];$pass_conf $_GET[ password_conf ];// Sanitise current password input$pass_curr stripslashes( $pass_curr );$pass_curr ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $pass_curr ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$pass_curr md5( $pass_curr );// Check that the current password is correct$data $db-prepare( SELECT password FROM users WHERE user (:user) AND password (:password) LIMIT 1; );$data-bindParam( :user, dvwaCurrentUser(), PDO::PARAM_STR );$data-bindParam( :password, $pass_curr, PDO::PARAM_STR );$data-execute();// Do both new passwords match and does the current password match the user?if( ( $pass_new $pass_conf ) ( $data-rowCount() 1 ) ) {// It does!$pass_new stripslashes( $pass_new );$pass_new ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $pass_new ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$pass_new md5( $pass_new );// Update database with new password$data $db-prepare( UPDATE users SET password (:password) WHERE user (:user); );$data-bindParam( :password, $pass_new, PDO::PARAM_STR );$data-bindParam( :user, dvwaCurrentUser(), PDO::PARAM_STR );$data-execute();// Feedback for the user$html . prePassword Changed./pre;}else {// Issue with passwords matching$html . prePasswords did not match or current password incorrect./pre;}
}// Generate Anti-CSRF token
generateSessionToken();?使用token机制使用PDOPHP 数据对象来执行数据库查询和准备语句以防止 SQL 注入攻击。在处理密码更改请求时首先验证当前用户输入的原始密码是否正确。