SSRF

SSRF是什么

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

SSRF漏洞原理

可以理解为,服务器可以从其他的服务器获取信息。然而却没有对这个服务器的地址做限制

就比如说,我们可以指定一个有缺陷的url,或者自己的作为外部服务器。

SSRF漏洞挖掘

分享

通过URL分享网页的内容

转码

通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览:由于手机屏幕大小的关系,直接浏览网页内容的时候会造成许多不便,因此有些公司提供了转码功能,把网页内容通过相关手段转为适合手机屏幕浏览的样式。例如百度、腾讯、搜狗等公司都有提供在线转码服务

翻译

通过URL地址翻译对应文本的内容。提供此功能的国内公司有百度、有道

图片、文章收藏功能

图片、文章收藏中的文章收藏就类似于分享功能中获取URL地址中title以及文本的内容作为显示,目的还是为了更好的用户体验,而图片收藏就类似于功能四、图片加载。

http://title.xxx.com/title?title=http://title.xxx.com/as52ps63de

例如title参数是文章的标题地址,代表了一个文章的地址链接,请求后返回文章是否保存,收藏的返回信息。如果保存,收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF

未公开的api实现以及其他调用URL的功能

图片加载与下载

通过URL地址加载或下载图片,图片加载远程图片地址此功能用到的地方很多,但大多都是比较隐秘,比如在有些公司中的加载自家图片服务器上的图片用于展示

URL关键字中寻找

share
wap
url
link
src
source
target
u
display
sourceURl
imageURL
domain

产生SSRF的相关函数

PHP

  1. file_get_contents

    将整个文件读入到字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    if (isset($_POST['url']))
    {
    $content = file_get_contents($_POST['url']); //获取用户输入的url
    $filename ='./images/'.rand().';img1.jpg'; //蒋文件储存为为一个
    file_put_contents($filename, $content); //将获取的内容写入文件
    echo $_POST['url']; //输出用户输入的url
    $img = "<img src=\"".$filename."\"/>"; //输出图片
    }
    echo $img;
    ?>

  2. sockopen

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?php
    function GetFile($host, $port, $link)
    {
    $fp = fsockopen($host, intval($port), $errno, $errstr, 30); // 使用fsockopen函数建立与指定主机和端口的连接,设置超时时间为30秒
    if (!$fp) {
    echo "$errstr (错误号 $errno) \n"; // 如果连接失败,输出错误信息
    } else {
    $out = "GET $link HTTP/1.1\r\n"; // 构建HTTP GET请求头,使用HTTP/1.1协议,这对于保持连接很重要
    $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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?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;
    }
    ?>

  4. curl_exec

    关于curl

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php
    // 检查是否设置了POST请求中的'url'参数
    if (isset($_POST['url'])) {
    $link = $_POST['url']; // 获取POST请求中的'url'参数值

    $curlobj = curl_init(); // 初始化一个cURL会话
    curl_setopt($curlobj, CURLOPT_POST, 0); // 设置cURL请求为GET请求
    curl_setopt($curlobj, CURLOPT_URL, $link); // 设置要访问的URL
    curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置cURL执行后不直接输出结果,而是返回到变量中
    $result = curl_exec($curlobj); // 执行cURL请求并将结果保存到$result变量
    curl_close($curlobj); // 关闭cURL会话

    $filename = './curled/' . rand() . '.txt'; // 生成一个随机文件名
    file_put_contents($filename, $result); // 将cURL获取的结果保存到文件中
    echo $result; // 输出cURL获取的结果
    }

  5. fsockopen

java

仅支持 HTTP/HTTPS 协议的类:HttpClient 类、HttpURLConnection 类、 OkHttp 类、 Request

支持 sun.net.www.protocol 所有协议的类:URLConnection 类、URL 类、ImageIO 类

SSRF中URL的伪协议

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

SSRF漏洞利用(危害)

读取敏感文件

  1. 使用file协议读取文件内容

    file://

    本地文件传输协议,用于读取本地计算机里面的文件。

    就像是使用win里面的打开或者右键打开

    • 读取/etc/password

      在Linux 中 /etc/passwd文件中每个用户都有一个对应的记录行,它记录了这个用户的一些基本属性。

      系统管理员经常会接触到这个文件的修改以完成对用户的管理工作。

    • 读取/etc/host

      hosts文件主要作用是定义IP地址和主机名的映射关系,是一个映射IP地址和主机名的规定。可以用文

      本文件打开!当用户在浏览器中输入一个网址时,系统会首先自动从hosts文件中寻找对应的IP地址,

      一旦找到,浏览器会立即打开对应网页,如果没有找到,则浏览器会将网址提交DNS服务器进行IP地址解析。简单来说就是负责ip地址与域名快速解析的文件,读取文件可以得到内网所在网段。

      可以理解为这个是本地的DNS解析器

探测内网的服务

  1. 使用dict协议

    dict://

    dict 协议是一个在线网络字典协议,这个协议是用来架设一个字典服务的。不过用的比较

    少,所以网上基本没啥资料(包括谷歌上)。在SSRF漏洞利用中,常常用来探测内网的应用信息

攻击内网应用

  1. 通过dict://协议攻击redis

    可以导致任意用户利用ssrf漏洞攻击内网中的未授权Redis以及读取Redis的数据。

    攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,如果运行 redis 的用户是 root 用户,攻击者可以通过写定时任务的方式进行反弹shell。

    测试是否存在漏洞

    dcit://ip:port/info

    写定时任务

    写定时任务的目录

    centos,在/var/spool/cron/目录下

    ubuntu 的定时任务在 /var/spool/cron/crontabs/ 目录下

    可以根据服务器是否存在以下文件判断服务器的信息

    # Centos

    /etc/redhat-release

    # Ubuntu

    /etc/lsb-release

SSRF中url解码编码

HTTP

现在我们有一个url是:

http://ip:host/xxx

如果现在xxx里含有%xx格式,这个数据先是被接受之后才会被解码

gopher

还是这个url

http://ip:host/xxx

如果xxx里面含有%xx格式的数据,那么会在发送方就处理成接收方接受的数据

漏洞类型

  • 有回显:页面有返回具体内容。

  • 无回显:页面没有返回具体内容

SSRF利用

内网访问

ctfhub 技能树

伪协议读取文件

伪协议:

类型
file:///
dict://
sftp://
ldap://
tftp://
gopher://

这里使用ctfhub技能树的题做演示

file:///var/www/html/flag.php

注意这个是web目录

端口扫描

端口扫描使用的是dict://协议

但是请你注意,我们使用dict扫描出端口之后,需要使用url直接访问,而不是继续使用dict协议

下面是做题逻辑,他说了端口在8000~9000,直接使用bp扫

image-20231130140802475

访问:

image-20231130141033863

http://challenge-a30959492eed8566.sandbox.ctfhub.com:10800/?url=127.0.0.1:8017

POST请求

这次还是使用ctfhub 的技能树作为例子

题目是:

这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.加油吧骚年

要求我们发一个POST请求包,但是这个发包需要利用gopher协议

首先我们可以利用index.php的url访问flag.php和index.php

URL Bypass

ctfhub技能树里面的一道题

打开过后发现必须带有

http://notfound.ctfhub.com

这里我们需要知道一个东西

http://www.baidu.com@192.168.0.1/

请求的都是192.168.0.1里面的内容

是所以我们直接构造

challenge-a1e077f43b569033.sandbox.ctfhub.com:10800/?url=http://notfound.ctfhub.com@127.0.0.1/flag.php

IP Bypass

这道题我觉得比较鸡贼,因为他会有到你想ip,ban掉了127/172

但是我们有一个回环地址localhost

所以直接构造poc

?url=localhost/flag.php

302跳转

不知道这个怎么回事,我尝试在http添加Localtion字段发现没有什么用,直接访问这个就没有问题

?url=localhost/flag.php

redis

使用ctfhub 进行演示

image-20240509173630164

可以发现存在ssrf

然后尝试使用redis 对内网进行攻击

image-20240509191455708

制作出webshell

然后尝试使用访问,会发现不行,得再次url 加密一下

image-20240509191615554

然后访问

出现了504 但是不要紧

这个是时候shell.php 是已经写好的

image-20240509191715142


SSRF
https://tsy244.github.io/2023/11/28/web/SSRF/
Author
August Rosenberg
Posted on
November 28, 2023
Licensed under