mysql -h 127.0.0.1 -P 4444 -uroot -e "select * from flag.flag;"
wireshark打开数据包 追踪TCP流 单独过滤出请求的包 以原始数据的形式展示 使用脚本编码
import sys
def results(s):
a=[s[i:i+2] for i in range(0,len(s),2)]
return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)
if __name__=="__main__":
s=sys.argv[1]
print(results(s))
background
之前通过国光师傅的靶场学习过ssrf的一些打法,在前几天暗月师傅的中秋打靶活动中用到了ssrf打me来getshell。我也是第一次接触到ssrf打me,于是就好好的记录一下ssrf的打法,发到我的blog上,以下大多数内容都是去年11月份完成的。
靶场地址:https://github.com/sqlsec/ssrf-vuls
原文链接:https://www.sqlsec.com/2021/05/ssrf.html
靶场拓扑图
这是靶场的拓扑图,就是用一个ssrf的点位来打内网的这些服务。

漏洞点
获取网段信息
探测存活
使用dict协议可判断端口是否开放

dict://182.168.1.1:80
172.172.0.25(文件上传)
别人新增的环境


文件上传
这里上传文件 是要用到post请求的 所以需要使用gopher协议来进行请求
构造请求包
判断POST数据的实际长度
使用脚本编码后一把梭
根据情况 可以删掉Accept-Encoding: gzip, deflate后手动url编码再请求

成功写入shell
访问马子并执行命令
172.72.23.22(GET命令执行)
网站存在但是没东西 我们先扫一下路径
白给的一道题了
url=http://172.72.23.22/shell.php?cmd=cat${IFS}/flag
其实这里就是简单的使用ssrf去转发get请求的流量
172.72.23.23(sql注入)
给了我们传参的方式和参数


fuzz一下发现过滤了空格 使用报错注入拿flag
这里注入用的是GET方式,实际中可能是POST,但方法跟上面一样
172.72.23.24(POST命令执行)
post请求ip参数

用脚本构造数据包 一定要删除Accept-Encoding: gzip, deflate
不然会乱码 因为会进行两次编码
Content-Length长度一定要正确
读取flag
172.72.23.25(XXE)
很明显的XXE

这里给出了请求方式 数据类型 请求结果
直接构造payload
post请求最基本的参数
地址
host
包的长度
编码方式
关于content-length的长度问题
直接在burp的repeater模块里构造好数据包 会自动填充的
可以在返回的页面里面直接填数据然后发包,我们拦包就会得到我们要的数据,但是这个请求地址是直接请求到当前页面的,所以没用,但我们可以方便的拿到数据包然后转gopher格式
读flag
172.72.23.26(Tomcat put传文件CVE-2017-12615)
直接rce用put文件上传
exp
一定要注意的是
172.72.23.27(未授权访问打redis)
这里没有web服务 无法写入shell
我们使用计划任务反弹shell
在burp下放包(防止浏览器编码的问题)
计划任务被成功写入,得shell
【这里就不放图了】
172.72.23.28(打有密码的redis)
直接lfi

我们尝试读取redis的密码 redis密码常见的路径
认证密码是否正确
dict不支持多行命令 所以只能使用gopher协议 抓取通信流量
处理后得到了数据
redis是使用的RESP协议 需要使用\r\n结束

无论是\r还是\r\n结尾 都会显示长度错误,我不用\r\n直接编码两次请求就能成功执行
我觉得$x代表了长度的话 那么\r\n算不算长度呢?如何区分\r\n是用户输入还是换行标识呢?

我试了空格\r\n也不行 但是文章里的师傅成功过 不清楚是什么原因
一键利用脚本(对他生成的payload解码后发现他也没有\r\n 还有我的请求一直无响应是应为在最后我没有quit)
通过计划任务反弹

172.72.23.29(打未授权mysql)
手搓篇

原理:无密码的mysql支持一步到位
也就是发一个包就能拿到返回结果
实验环境:
物理机windows设置无密码的mysql
虚拟机kali连接物理机的mysql
设置端口转发 将本机的4444端口转发到物理机的mysql3306端口上去
监听本地4444端口数据 并生成流量包
请求获取flag
wireshark打开数据包 追踪TCP流
单独过滤出请求的包
以原始数据的形式展示
使用脚本编码
直接python exp.py xxxxxxxx(这里接上原始数据就行)
到这一步我一直就打不通了 各种排错 我用gopherus生成payload去和我的payload对比


后来突然想起来 我本机是windows的 靶机是linux 能打通才怪了 我抓了windows的包 然后编码 请求 打不出flag 用同样的方法打Linux的就成功了
工具篇



无论windows还是Linux gopherus都能通杀 我惊呆了
Linux???
提权
然后使用udf进行提权 获取系统权限
这里使用gopherus没有成功 我试了很多遍都没有成功 看别人的博客 也有人说gopherus打不通
这里我觉得是16进制编码的问题 select直接写入的是16进制的东西 可能编码中出了点问题
使用tcpdump进行抓包(我直接windows连接远程然后wireshark抓包没打通)
按照上面的方法抓包,然后请求
UDF提权
其实也就是select去写入一个恶意文件,然后创建函数时加载这个恶意文件
查找mysql的插件目录
写入恶意so文件语句参考https://www.pwns.fun/web/tools/udf/index.html(国光原创的,我只是扒下来了)
同样的这里可以写入webshell,本质上都是写入文件。
创建函数
执行命令
gopherus
自动生成gopher格式的数据,但是把他放到http里面去打的话需要在URL编码一次
用法
可以打fast-cgi,redis,mysql等服务,gopherus只能在python2下面运行


打fast-cgi的演示
将生成结果再次url编码,注意url编码的字母要大写
DiscuzX3.2 ssrf打未授权访问Memcache
月师傅的靶场,是16,17年出来的洞了,我真的很佩服挖这些洞的大佬,我自己大概是永远也难挖出这种水平的洞了。这里只讲怎么样去打me,不看漏洞原理。其实都一样的,把序列化后的数据传进去直接生成就行了。

其他的打法
国光师傅还提到了可以打 FTP、Zabbix这些应用,但gopherus的作者写出了除了这些还能打smtp
ftp的打法我在网上没找到过多的资料,看到一些文章好像讲的都是CTf题,我就先暂时不看了,毕竟我现在的方向不是安研了
当zabbix的配置EnableRemoteCommands = 1时,即可执行系统命令,gopherus直接打
使用smtp发送邮件
