[【通过】] SSRF漏洞分析与本地测试

[复制链接]
havyeei 发表于 2016-12-29 10:01:10 | 显示全部楼层 |阅读模式

正式成员|主题 |帖子 |积分 37

基础知识:1. file_get_contents()-将整个文件读入
获得并输出网站首页源代码:
[PHP] 纯文本查看 复制代码
<?php
$homepage = file_get_contents('http://www.baidu.com/');
echo $homepage;
?>



查看相对路径里面的文件,5版本以后默认可以读取:
[PHP] 纯文本查看 复制代码
<?php
// <= PHP 5
//$file = file_get_contents('./people.txt',true);
// > PHP 5
$file = file_get_contents('./people.txt',FILEUSEINCLUDE_PATH); ?>



使用流内容:
[PHP] 纯文本查看 复制代码
<?php
//Create a stream
$opts = array(
  'http'=>array(
    'method'=>'GET',
    'header'=>'Accept-language: zh\r\n' .
        'Cookie: foo=bar\r\n'
  )
) ?>



这几种代码都是输出变量的内容,看看下面的图片:
http://localhost/test/file_get_contents.php

1.png
简单实现代码:

[PHP] 纯文本查看 复制代码
<?php
  $url = $_GET['url']; 
  $url = 'http://' .$url;
  $con = file_get_contents($url);
  echo $con; 
?>


常见的后端实现代码srf攻击可能存在任何语言编写的应用,我们通过一些php实现的代码来作为样例分析。
1. file_get_contents:
[PHP] 纯文本查看 复制代码
<?php
if (isset($POST['url']))
{	//将整个文件读入一个字符串
$content = file_get_contents($POST['url']);
$filename ='./images'.rand().'img1.jpg'; 
echo $filename . '<br />';
//将一个字符串写入文件
file_put_contents($filename,$content);
echo $_POST['url'] . '<br / >';
$img = "<img src=\"".$filename."\"/>";
echo 1 . '<br />';
}
echo $img;
?>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ssrf form</title>
</head>
<body>
<form name='ssrf' method='post' action='' >
url:<input type='text' name='url' >
提交:<input type='submit' name = 'submit' value='提交' >
</body>
</form>
</html>



2. fsockopen:

[PHP] 纯文本查看 复制代码
<?php 
function GetFile($host,$port,$link) 
{ 
//fsockopen()打开一个网络连接或者一个unix套接字连接
//intval()获取变量的整数值
$fp = fsockopen($host, intval($port), $errno, $errstr, 30); 
echo $fb;
if (!$fp) { 
echo "$errstr (error number $errno) \n"; 
} else { 
$out = "GET $link HTTP/1.1\r\n"; 
$out .= "Host: $host\r\n"; 
$out .= "Connection: Close\r\n\r\n"; 
$out .= "\r\n"; 
echo '<br />';
echo $out;
fwrite($fp, $out); 
$contents=''; 
while (!feof($fp)) { 
$contents.= fgets($fp, 1024); 
} 
fclose($fp); 
return $contents; 
} 
}
$a = GetFile($_POST['host'],$_POST['port'],$_POST['link']);
echo '<br />' . $a;
?>


3. curlexec:

[PHP] 纯文本查看 复制代码
<?php
if(isset($POST['url']))
{
$link = $POST['url'];
$filename = './curled' .rand() .'.txt';
//curlinit() 初始化一个新的会话,返回一个cURL句柄,供其他函数使用
$curlobj = curlinit($link);
$fp = fopen($filename,"w");
curlsetopt($curlobj, CURLOPTFILE, $fp);
curlsetopt($curlobj, CURLOPT_HEADER, 0);
curlexec($curlobj);
curlclose($curlobj);
fclose($fp);
$fp = fopen($filename,'r');
$result = fread($fp, filesize($filename));
fclose($fp);
echo $result . '
';
}
?>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8">
<title>ssrf form</title>
</head>
<body>
<form name='ssrf' method='post' action='' >
url:<input type='text' name='url' >
提交:<input type='submit' name = 'submit' value='提交' >
</body>
</form>
</html>



攻击场景

static/image/hrline/line3.png


大部分的web服务器架构中,web服务器自身都可以访问互联网以及服务器所在的内网。-也就是说可以实现内网探测。。。
正常情况下访问http://www.baidu.com/robots.txt返回如下结果:

4.png

请求本地的mysql端口:http://127.0.0.1:3306/test.txt

5.png
内网web应用指纹识别

识别内网应用使用的框架,平台,模块以及cms可以为后续的攻击提供很多帮助。大多数web应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型,甚至详细的版本。根据这些信息就可以针对性的搜集漏洞进行攻击。比如可以通过访问下列文件来判断phpMyAdmin是否安装:

http://127.0.0.1/phpMyAdmin/themes/original/img/b_tblimport.png

6.png

读取本地文件

file:///C:/Windows/PFRO.log


7.png


如何防御


  • 通常有以下5个思路:

1,过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2, 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
3,限制请求的端口为http常用的端口,比如,80,443,8080,8090。
4,黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
5,禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
用余弦的话总结ssrf攻击:
  • 利用这个漏洞,可以从漏洞服务器发出伪造的请求到目标服务上,目标服务可以是内网的各类服务,可以使用不一样的协议,并根据回显来判断攻击是否成功(如果是盲打的话,就不用回显了:))。
附赠:
SSRF漏洞的挖掘经验: https://sobug.com/article/detail/11
下面这个图也许能激发大家对这个漏洞的兴趣
8.png

评分

参与人数 1酒票 +5 收起 理由
管理05 + 5 欢迎加入90!

查看全部评分

Blck 发表于 2016-12-29 10:58:48 | 显示全部楼层

正式成员|主题 |帖子 |积分 180

科普文,实战介绍的太少。
快速回复 返回顶部 返回列表