今天学学 ssrf,有些服务器的某些资源可能会规定请求必须来自内网才能访问资源,如果不是内网用户则会被拒,而 ssrf 就能为我们提供一个内网访问的通道。

浅析ssrf

在计算机安全中,服务器端请求伪造(英语:Server-side Request Forgery,简称SSRF)是攻击者滥用服务器功能来访问或操作无法被直接访问的信息的方式之一

在之前做过的题目种,我们已经初步接触过本地网页限制访问资源的例子,但是我们都可以伪造,比如 referer 字段或者是 X-Forwarded-for 字段,因为包含在我们请求的 headers 中,因此我们可以直接伪造。但是 $_SERVER 就是我们所不能伪造的了,这个变量是什么呢?

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。这也就意味着大量的此类变量都会在» CGI 1.1 规范中说明,所以应该仔细研究一下。

所以我们对 SERVER 变量进行校验即可判断请求是否来自本地,如果不来自本地则直接拒绝掉。

1
2
3
4
5
6
<?php 
if($_SERVER['SERVER_ADDR']!=='127.0.0.1'){
die('非本地访问');
}
echo('flag{test_flag}');
?>

可以发现是无法访问的。

只有我们在本机使用环回地址才能访问成功。

那么我们最主要就是如何让服务器代我们发起请求,如果能代我们发起请求,那就会造成给 ssrf

web351

1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
?>

一步一步解读。

第一个从 url 参数中获取 url

  • curl_init:初始化一个 cURL 会话,参数可以为空,或者为一个 url
  • curl_setopt:设置 cURL 会话的一些属性。
  • curl_exec:根据参数选项执行 curl 命令,并把结果返回给浏览器。
  • curl_close:关闭会话

就是直接可以请求一个网页,然后可以发现底下有 flag.php,但是只有本地能访问,因此在这里我们让 curl 去请求 127.0.0.1/flag.php 即可。