基础知识: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
简单实现代码:
[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返回如下结果:
请求本地的mysql端口:http://127.0.0.1:3306/test.txt
内网web应用指纹识别
识别内网应用使用的框架,平台,模块以及cms可以为后续的攻击提供很多帮助。大多数web应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型,甚至详细的版本。根据这些信息就可以针对性的搜集漏洞进行攻击。比如可以通过访问下列文件来判断phpMyAdmin是否安装:
http://127.0.0.1/phpMyAdmin/themes/original/img/b_tblimport.png
读取本地文件
file:///C:/Windows/PFRO.log
如何防御
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
下面这个图也许能激发大家对这个漏洞的兴趣
|