DVWA-1.9分10个功能模块:
Brute Force(暴力破解)
Command Injection(命令行注入)
CSRF(跨站请求伪造)
File Inclusion(文件包含)
File Upload(文件上传)
Insecure CAPTCHA(不安全的验证码)
SQL Injection(SQL注入)
SQL Injection(Blind)(SQL盲注)
XSS(Reflected)(反射型跨站脚本)
XSS(Stored)(存储型跨站脚本)
登录DVWA:
选择CSRF模块:
把安全级别设置为Low级别,分析源代码:
if( 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 = mysql_real_escape_string( $pass_new );
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysql_query( $insert ) or die( '
' . mysql_error() . '' );
// Feedback for the user
echo "
Password Changed.";
}
else {
// Issue with passwords matching
echo "
Passwords did not match.";
}
mysql_close();
}
?>
注:通过对源代码进行分析,可以看到源代码中只对两次输入的密码是否相同进行了判断,其他操作都没有进行防御,所以只需要用户在Cookie还有效的时间内在相同的浏览器访问攻击者伪造的URL,该操作是服务器对请求的发送者进行身份验证检查Cookie,中间就实现了CSRF攻击,修改其用户密码.
漏洞利用:
由于源代码中没有做过任何验证,诱导用户点击:http://192.168.197.136/dvwa/vulnerabilities/csrf/?password_new=111111&password_conf=111111&Change=Change,该URL即可实现密码修改,但是要注意需要服务器验证Cookie,所以必须让该URL和DVWA系统打开的浏览器一致,这样才可以验证成功。,由于链接过于明显,考虑通过变换URL的网址实现,例如百度的短网址,当然URL的IP地址是不能生成或更换的,需要服务器的域名.
构造攻击页面:
404
file not found.
注:当用户访问这个页面时,会以为访问的页面丢失了,但是当他打开这个页面时,用户的密码已经被修改了!
注:当用户访问这个页面时,会以为访问的页面丢失了,但是当他打开这个页面时,用户的密码已经被修改了!
把安全级别设置为Medium级别,分析源代码:
if( isset( $_GET[ 'Change' ] ) ) {
// Checks to see where the request came from
if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) {
// 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 = mysql_real_escape_string( $pass_new );
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysql_query( $insert ) or die( '
' . mysql_error() . '' );
// Feedback for the user
echo "
Password Changed.";
}
else {
// Issue with passwords matching
echo "
Passwords did not match.";
}
}
else {
// Didn't come from a trusted source
echo "
That request didn't look correct.";
}
mysql_close();
}
?>
注:通过对源代码进行分析,可以知道Medium端主要防御措施是通过if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) )ersgi这个函数来检查HTTP_REFERER(Http包头的Referer参数值来表示来源地址),SERVER_NAME((Http包头的Host参数表示及要访问的主机名192.168.197.136)以此来抵御CSRF攻击.
漏洞利用:
注:通过验证,就必须保证在Http请求中Referer字段中必须包含Host,所以攻击者只需要将文件名改成受害者的Host以及name就可以完美通过验证!
把安全级别设置为High级别,分析源代码:
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// 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 = mysql_real_escape_string( $pass_new );
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysql_query( $insert ) or die( '
' . mysql_error() . '' );
// Feedback for the user
echo "
Password Changed.";
}
else {
// Issue with passwords matching
echo "
Passwords did not match.";
}
mysql_close();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
注:通过源代码分析可以看到该模块中加入了Anti-CSRF token来防范CSRF攻击,同时每次随机生成了一个Token,当用户提交的时候,在服务器端比对一下Token值是否正确,不正确就丢弃掉,正确就验证通过.
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
注:这个High安全等级主要是利用了DVWA的XSS漏洞和CSRF漏洞共同完成的,找到DVWA的XSS模块,通过XSS漏洞获取浏览器Cookie:
注:返回DVWA的CSRF模块,向输入框中输入任意想要修改的密码,通过BrupSuite进行拦截,获取数据包:
将数据包发送到Repeater模块:
注:通过XSS漏洞获取Cookie直接粘贴到这个数据包中,通过BrupSuite对数据包进行篡改,发送,修改密码:
把安全级别设置为Impossible级别,分析源代码:
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_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 = mysql_real_escape_string( $pass_curr );
$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 = mysql_real_escape_string( $pass_new );
$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
echo "
Password Changed.";
}
else {
// Issue with passwords matching
echo "
Passwords did not match or current password incorrect.";
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
注:通过源代码分析可以看到Impossiable端代码添加了一个输入原来密码的操作,这样攻击者一开始不知道密码的情况下是不可能修改密码的,所以也就有效的防御了CSRF攻击!