目录
CSRF
CSRF概念
CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Click Attack"或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
CSRF攻击是建立在会话上的。比如当你登陆了网上银行,正在进行网上转账的操作,此时你的某个好友(攻击者)给你发送了一条消息(URL),这个链接是攻击者精心构造的转账业务代码,并且与你登录的这家银行是一个,页面也相当真实,你便可能会认为这个网站是安全的,然而当你打开了这条URL后,你账户中的余额可能就会全部丢失。
主要是因为你的浏览器正处于与此网站的会话之中,那么任何的操作都是合法的,而攻击者构造的这段代码只不过是正常的转账操作代码而已。比如,你想给xxxser转账1000元,那么单击“提交”之后,可能会发送下面的请求:
http://www.secbug.org/pay.jsp?user=xxxser&money=1000
然而攻击者仅仅改变了一下url中的参数,便完成了一次“合法”的攻击:
http://www.secbug.org/pay.jsp?user=hacker&money=1000
所以总结一下:上述的过程描述了CSRF的两个攻击重点:
1. CSRF的攻击建立在浏览器和Web服务器的会话中。
2. 欺骗用户访问URL。
DVWA-CSRF
LOW
这里我们可以看到payload是
http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=123123&password_conf=123123&Change=Change
所在在攻击者得到发送的请求payload之后,便可以构造一个与目标网站极其类似的网站来诱使用户访问,这里我们仅仅构造一个简单的网页,达到用户的信息被莫名自动修改的效果。
<img src="http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=112233&password_conf=112233&Change=Change##" border="0" style="display:none;"/>
我们将这个网页命名为change.php,所以我们直接去访问change.php,然后我们去DVWA进行测试登录。
我们通过抓包来测试之前的密码123123是否正确:
这里已经发现了密码不正确。我们在测试被修改的密码是否正确:
正常登陆成功,所以这里就说明由于我们访问了攻击者构造的页面,使得我们的密码被修改了
Medium
和Low级别一样,没有加入Token,所以我们还是可以按照Low级别来修改密码。完成操作。
High
<?php
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 = ((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
echo "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
echo "<pre>Passwords did not match.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>
这次有了token值,我们需要在攻击者的服务器上去获得被攻击者的token值。因此我们的思路就是构造一个攻击页面,将其放在攻击者的服务器上,诱使被攻击者去访问,从而获得相应的token值,并且向服务器发送请求修改密码的操作,从而完成对应的攻击。
这里我们结合XSS漏洞来获取被攻击者的token值。
<iframe src="../csrf/"onload=alert(frames[0].document.getElementsByName('user_token')[0].value)></iframe>
此时当我们再去点击的时候就会出现客户的token。
此时我们在构造的页面中加上token的值,诱使用户进行访问。
http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change&user_token=7a243e4c2b0c86963ed92b28d9eb9461
测试之前的密码,已经不正确,我们来测试被修改的密码是否正确。
这里就已经发现只能使用攻击者想要修改的密码,才能进行登录。
预防跨站请求伪造
二次确认
在调用某些功能的时候进行二次认证,比如说在删除用户的时候,产生一个提示对话框,提示“确定删除用户吗?”。转账时,要求用户输入二次验证码等。
所以在这种情况下,当二次验证后,即使用户打开了CSRF POC页面,也不会直接执行,而是需要用户再次输入才可以完成攻击。
Token认证
Token即标志、记号的意思,也称之为令牌。
我们通过上面的一系列的测试得知,CSRF攻击的原理,有这两个要素:
1. 攻击者可以得知URL中的所有的参数项,并了解各部分的含义。
2. 必须诱导用户访问构造好的POC。
假设在攻击者已经获得了URL中的所有的参数项,并了解各部分的含义,并且也够早好了POC,我们还是可以通过Token验证来进行防护。Token类似于“验证码”,它是一种不需要输入的验证码。当用户登录Web应用程序后,首先,服务器端会随机产生一段字符串分配给此用户,并且存储在Session中,当用户进入某个页面时,直接传递在用户界面或者Cookie中。如果在HTML中,那么为了用户体验更好,会将其隐藏起来。当用户进行表单提交的时候,这段token代码也会被随之提交,当服务器收到数据的时候,会判断这些数据是否与Session中存储的数据一致,如果一致,则证明是合法的请求,但是如果不一致,则可能就是CSRF攻击。所以说Token就可以解决CSRF攻击。
这里需要提出的一点就是:在我们的DVWA实例中,High级别虽然使用了Token那么为什么还会有CSRF攻击。这里就是,当一个网站同时存在XSS、CSRF漏洞时,Token防御机制就会失效,因为攻击者可以通过Javascript获取到Token值。
所以在防范CSRF的时候,要判断该网站是否存在着XSS漏洞,如果存在,那么防范CSRF是没有任何的意义的。
SSRF
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
SSRF形成的原因:一般情况是由于服务器端提供了可以从其他的服务器获取数据的功能,但是没有对目标地址进行过滤。
比如,一个正常的web应用拥有着能够上传文件的功能,一般的文件上传是允许本地上传的,但是这种web应用可能允许网络上传,也就是说他本来是从指定的url中获取文本的内容或者加载指定地址的图片等,但是攻击者可以伪造服务器端从而发起请求,便可以突破客户端获取不到数据的限制。包括着内网资源等。
<?php
$url=$_GET['url'];
echo file_get_contents($url);
?>
上述的这段代码通过使用file_get_contents函数便可以从用户输入的指定url中获取数据并显示给用户。假如我们使用这样的payload,就可以获取某个内网ip的某个端口的开放情况。
?url=htpp:192.168.x.x:x
SSRF挖掘方法
可以分为两种:
从web功能上挖掘
图片的下载和加载:通过URL地址加载或者下载图片。
具有图片、文章的收藏功能的地方
分享:可以通过URL地址分享网页内容
转码服务:通过URL地址把源地址的网页内容调优使其适合手机屏幕浏览
在线翻译:通过URL地址翻译对应文本的内容。提供此功能的国内公司有百度、有道等。
未公开的API实现以及调用URL的功能
从URL关键字挖掘
share url link src source imageURL sourceURL display wap 等等
根据后台使用的函数不一样,对应的影响和利用方法又有不一样。
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
常见的SSRF攻击方式
针对服务器自身的攻击
关于在针对服务器自身的攻击过程中,攻击者通过环回地址来向承载应用的服务器来发送HTTP请求。所以我们可以在url中添加127.0.0.1来访问服务器本地的文件。
针对端口的攻击
http://xxx.com/ssrf.php?url=http://ip:3306
http://xxx.com/ssrf.php?url=http://ip:443
http://xxx.com/ssrf.php?url=http://ip:21
http://xxx.com/ssrf.php?url=http://ip:80
这里就可以判断出数据库的版本为5.7.26。我们可以通过响应时间、返回的错误信息、返回的服务Banner信息、响应时间等来对端口开放情况进行给判断。
针对其他后端系统的攻击
SSRF引起的另一种信任关系:服务器能够与用户无法直接访问的其他的后端系统进行交互,这些系统一般来说具有不可路由的专用ip地址。例如在后端还有其他的某个内网的地址192.168.x.x。我们可以直接让服务器去访问他,而不需要任何的身份验证。
文件读取和命令执行
文件读取
攻击者使用file伪协议,便可以实现对服务器上的文件读取的操作。
http://xxx.com/ssrf.php?url=file:///etc/passwd
命令执行
在PHP的环境下,可以使用expect来执行系统命令。
http://xxx.com/ssrf.php?url=except://id
SSRF防御
SSRF漏洞的防御主要是保证用户请求的合法性、服务器行为的合规性两个方面。
1. 限制请求端口只能为web端口,只允许访问HTTP和HTTPS的请求;
2. 过滤返回的信息;
3. 禁止不常使用的端口;
4. 限制不能访问内网的IP,防止对内网进行攻击;