CSRF和SSRF带来的WEB漏洞

前言:

  前几天做了一波xss的总结,之后找到了进入第十五关的地址,不过在学习过程中,又看到了两个更加好玩漏洞利用,于是乎,打完xss练习平台后就迫不及待地学起来这个,也正好完成一波学长给布置的任务。就我个人的理解,CSRF就像是一块拥有诱惑力的蛋糕,吸引着一些没有足够网络安全意识的用户走入陷阱,而SSRF就像一个有着好几个不同的门的房间,连接着服务器上不同的权限。

参考文献:半夏小哥哥的教学视频倾旋小哥哥的教学视频

正文:

  CSRF的全称是跨站请求伪造(Cross-site request forgery),是基于客户端操作的请求伪造,简单说,会话对象只有两个,攻击者利用正常的登录状态对网站内部对某些请求操作进行截取,并将其伪造成网页中具有某些诱惑效果的html代码链接,比如图片点击事件,这样其他用户在无意中点击该图片的时候就会触发该操作,当然这个是有前提的,用户必须要信任该网站,也就是利用用户保存在浏览器上的隐式验证,比如说cookie。

CSRF实例:

  对于一些交互网站,一般都会有用户的登录界面和密码修改界面,如果说恶意用户制造了一个修改密码的URL(其实就是抓取修改密码时的请求),并以其他的形式留在该网站上,比如说以<img src='shellcode'>标签形式留在留言板上,这就会造成其他用户在无意中点击该标签的时候修改了自己的密码。这里有一张来自网上的图:

p1

大致来说的CSRF攻击步骤就如上图所示,这里在做一个简单的攻击实例:p2

  在这个找回密码的界面中,我们需要提交三个参数才能完成密码的更新:passwordcheckpasswordsubmit,后台的过滤语句并没有对这三个参数进行严格的控制,造成这里的URL可直接访问,也就是CSRF触发的前提条件之一成立,所以就会有恶意用户在这里构造恶意语句:<img src='http://127.0.0.1:8080/CSRF&SSRF/manage.php?password=admin&checkpassword=admin&submit=submit'>,这条语句可以出现一些论坛之类等该用户经常访问的网站上,如果受害用户在登录该网站的时候同时点击了论坛上的该图片标签,他的网站密码就会被改成admin。当然这只是一个举例,CSRF还有更加危险的操作,例如对账户进行转账等危险操作,不过一般大型公司的网站是不允许有该漏洞存在的。

  因为这里的代码是个人坐实验用的,所以仅供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
界面部分
<form action="GetNewPassword.php" method="GET">
<h3>找回密码</h3>
NewPassword:<input type="password" name="password" value=""><br />
ReNPassword:<input type="password" name="checkpassword" value=""><br />
<input type="submit" name="submit" value="submit" class="submit">
</form>


后台处理
<?php
error_reporting(0);
if(isset($_GET['submit'])&&$_GET['submit']==='submit'){
session_start();
$_SESSION['islogin']=1;
if(isset($_GET['password'])&&isset($_GET["checkpassword"])&&!empty($_GET['password'])&&!empty($_GET['checkpassword'])&&$_GET['password']===$_GET['checkpassword']){
//数据库连接操作
include_once 'mysqli.php';
$link=mysqlconnect();
$sql="select * from users";
$sql=escape($link,$sql);//转义字符串
$result=execute($link,$sql);
while($column=@mysqli_fetch_array($result)){
if($_SESSION['user']===$column['username']){
$sql2="update users set password='{$_GET['password']}' where username='{$_SESSION['user']}'";
$result=execute($link,$sql2);
if($result){
echo "<span style='margin-left:36%;' content=‘3;URL=login.html’>密码修改成功!三秒后返回登录界面。</sapn> | ";
echo "<a style='color:red;' href='login.html'>直接前往!</a>";
}else{
header('location:manage.php');
}
}
}
}
else{
header('location:manage.php');
}
}else{
header('location:manage.php');
}
?>

  因为这里设计的用户名部分是通过$_SESSION超级变量来获取的,所以漏洞触发地点也必须是在网站内部。这个是比较简单,只要利用一个标签就可以诱惑用户,危害明显比较大。再看看另一种提交方式:p3

  这个是post类型传参方式,相对于get型传参,它的CSRF攻击方式会更加麻烦一点,因为post类型不会形成一个URL,所以,要形成一个post类型的CSRF攻击,一般都会选择做一个钓鱼网站,界面的东西看起来是和正常无害界面一样,但后面的代码确实对传入的数据进行另类处理。不过,现在的互联网用户越来越多,大家对钓鱼网站也有了自己的认识,轻易不会上当。所以,在我看来,这个WEB漏洞存在的意义不大。

防御方式:
  1. 设置和判断cookie时采用hash值认证,一般攻击者再看到hash值时扭头就走,原因自然是不言而喻。
  2. 尽量采用post类型传参,这就减少了请求被直接伪造的可能。
  3. 采用验证码判断,这也是一道艰难的工程,想识别验证码的步骤就有点繁杂了。

  SSRF的全称是服务端请求伪造(Server-Side Request Forgery),由于某些应用需要调用其他服务器上的资源,需要传入一个目标地址提供给服务器请求,这就会造成攻击者利用该地址促使服务器访问内网的其他服务,简单说,SSRF就是通过获取资源的请求发送给服务器,利用一个服务器做跳板来访问其他服务器上的资源,适用于主机信息收集、WEB应用指纹识别、根据应用识别payload进行攻击和拒绝服务攻击。

SSRF实例:

  有csrf的基础,ssrf看起来就比较简单,可以利用权限较高的服务器的身份来访问其他服务器上的资源。这里举一个远程文件读取函数使用不当造成的ssrf漏洞:p4

再看一下ssrf.php文件源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
header('Content-Type:image/png');
if($_REQUEST['p']==1){
$file=empty($_REQUEST['img'])?FALSE:$_REQUEST['img'];
if($file){
$fp=fopen($file, 'r');
$result=fread($fp,filesize($file));
echo $result;
fclose($file);
}else{
echo '1<hr />';
}
}
if($_REQUEST['p']==2){
$file=empty($_REQUEST['img'])?FALSE:$_REQUEST['img'];
if($file){
$result=file_get_contents($file);
echo $result;
}else{
echo '2<hr />';
}
}
?>

第二个判断语句中,执行了一个远程文件读取的方法file_get_contents(),就相当与可以借助这台服务器来访问其他服务器上的内容,这就是一个前提条件。当然,如果存在第一个判断语句里面的内容,那还可以使用其他的伪协议 ,例如file协议,ftp协议等等。当然,一般程序员是不会直接输出文件内容的,不过这个可以用来判断服务器开了哪些主机存活,可以利用一些站点常见的文件来实现,比如favicon.ico文件,根据返回时间长短可以判断该主机是否存在,存在的主机返回的速度很快,一般多是1秒之内,不存在的主机返回速度很慢,大概会超过20秒。

SSRF漏洞出现位置:
  1. 通过URL地址分享网页内容;
  2. 转码服务;
  3. 在线翻译;
  4. 通过URL地址加载与下载图片;
  5. 图片、文章收藏功能;
  6. 未公开的API实现以及其他调用URL的功能;
  7. 从URL关键字中寻找share、wap、url、link、src、source、target、u、3g、display、sourceURL、imageURL、domain等等可控关键字。
SSRF远程文件访问:

  这里举例一个SSRF的远程文件访问操作,先看一触发的代码:

1
2
3
4
5
6
#ssrf_far.php
<?php
$str=$_POST['url'];
$str=file_get_contents($str);
$str($_POST['cmd']);
?>

这里就是一个程序员在做远程访问的时候常见的三行代码,有这三行代码存在,就会造成上述漏洞,再看一下执行效果:p5

这里ssrf_far.php中含有造成远程文件访问漏洞的代码,恶意攻击者就会利用该效果将URL地址定向到一个自己可以控制的服务器的站点文件内,就比如这里的assert.txt文件中写的内容就是shell_exec,这样就将ssrf_far.php文件的第三行代码变成了一个可以执行系统命令的php函数,造成一个危险操作。

防御方式:
  1. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
  2. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
  3. 限制请求的端口为http常用的端口,比如:80、443等。
  4. 黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
  5. 禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。

总结:

  因为我也是最近刚刚开始接触csrf和ssrf,所以对它们的理解不是很深刻,总感觉理解不到里面的奥义,希望有师傅能带带我,指点一下迷津。这是我的QQ

QQ